javascript - 更改 contenteditable 后恢复光标位置

标签 javascript jquery html contenteditable

有这样的html:

<div contenteditable="true" class="value research-form thumbnail">
 Some text here
 </div>

div 的内容应该在用户键入时动态突出显示一些单词,例如:

 <div contenteditable="true" class="value research-form thumbnail">
 Some text here <span style="background-color: yellow">highlight</div> it
 </div>
 <script>
    $(document).ready(function () {
        var input = $('#textarea').on('input', function (event) {
            var newText = input.text().replace('highlight', '<span style="background-color: yellow">highlight</div>');
            input.html($.parseHTML(newText));
        });
    });
</script>

但是有一个问题:当我刷新 div 中的文本时,光标移动到输入文本的开头。

有什么方法可以在更改 contenteditable 值后恢复光标位置?还是有其他方法可以达到同样的效果?

最佳答案

我找到了解决方案。

完整代码如下:

<div class="container" style="margin-top: 10px">

    <div class="thumbnail value" contenteditable="true">

    </div>

</div>

<script>
    $(document).ready(function () {
        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 setCaretPosition(element, offset) {
            var range = document.createRange();
            var sel = window.getSelection();

            //select appropriate node
            var currentNode = null;
            var previousNode = null;

            for (var i = 0; i < element.childNodes.length; i++) {
                //save previous node
                previousNode = currentNode;

                //get current node
                currentNode = element.childNodes[i];
                //if we get span or something else then we should get child node
               while(currentNode.childNodes.length > 0){
                  currentNode = currentNode.childNodes[0];
               }

                //calc offset in current node
                if (previousNode != null) {
                    offset -= previousNode.length;
                }
                //check whether current node has enough length
                if (offset <= currentNode.length) {
                    break;
                }
            }
            //move caret to specified offset
            if (currentNode != null) {
                range.setStart(currentNode, offset);
                range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }

        function onInput(event) {
            var position = getCaretCharacterOffsetWithin(input.get(0));
            var text = input.text();
            text = text.replace(new RegExp('\\btest\\b', 'ig'), '<span style="background-color: yellow">test</span>');
            input.html($.parseHTML(text));
            setCaretPosition(input.get(0), position);
        }

        var input = $('.value').on('input',onInput);

        //content should be updated manually to prevent aditional spaces
        input.html('simple input test example');
        //trigger event
        onInput();
    });
</script>

关于javascript - 更改 contenteditable 后恢复光标位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26139475/

相关文章:

javascript - 使用 getElementById 一次指定 2 个操作

javascript - 通过在弹出窗口外单击来隐藏弹出窗口

javascript - 使用 Jquery 选择器验证是否已选择任何项目

javascript - ruby gem : Get files in asset pipeline

html - 如何显示两个列表,其中每个 li 元素垂直位于彼此下方?

html - Wordpress 正在向 html 添加隐藏的 <p>。我该如何删除它们?

javascript - TypeScript 中是否有可用于 HTML 元素的类?

javascript - $(iframe) 显示 null,检查 iframe 后显示对象,

javascript - 使用右侧选择器定位 div

HTML——在页面上给 fieldSets 一些结构