我有一个具有contenteditable属性的div.用户需要能够键入并插入光标所在的几个选择菜单.我已设法获取光标位置并插入第一个选择菜单,但它只适用于第一个文本节点.
这就是我获取光标位置的方式:
function getCaretCharacterOffsetWithin(element) { var caretOffset = 0; var doc = element.ownerDocument || element.document; var win = doc.defaultView || doc.parentWindow; var sel; if (typeof win.getSelection != "undefined") { sel = win.getSelection(); if (sel.rangeCount > 0) { var range = win.getSelection().getRangeAt(0); var preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(element); preCaretRange.setEnd(range.endContainer, range.endOffset); caretOffset = preCaretRange.toString().length; } } else if ( (sel = doc.selection) && sel.type != "Control") { var textRange = sel.createRange(); var preCaretTextRange = doc.body.createTextRange(); preCaretTextRange.moveToElementText(element); preCaretTextRange.setEndPoint("EndToEnd", textRange); caretOffset = preCaretTextRange.text.length; } return caretOffset; }
然后我每次用户输入或点击时都会更新它.
function updatePos() { var el = document.getElementById("msg"); pos = getCaretCharacterOffsetWithin(el); } document.body.onkeyup = updatePos; document.body.onmouseup = updatePos;
然后,这是我如何处理添加选择的按钮.我不确定如何在文本节点之后插入元素,因此我插入一个br标记并在以后删除它.必须有一个更清洁的方式,对吧?
$('#btn').click(function(){ var selectList = document.createElement('select'); var msg = $('#msg'); $(msg).html(function(){ var first = $(msg).html().substring(0, pos); var last = $(msg).html().substring(pos); return first + '
' + last; }); $(msg).contents().filter('br').after(selectList); $(msg).contents().filter('br').remove(); $(msg).focus(); })
我想问题是我正在使用子字符串来分割文本并能够在那里插入选择,并且只要有另一个选择标记,子字符串就不能通过第一个文本节点.所以也许我应该用不同的方法重做整个事情,但我完全陷入困境.
这是jsfiddle:https://jsfiddle.net/8a63sosr/
谢谢!