Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/90.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在contenteditable元素中保持插入符号的位置_Javascript_Html_Css_Ecmascript 6 - Fatal编程技术网

Javascript 如何在contenteditable元素中保持插入符号的位置

Javascript 如何在contenteditable元素中保持插入符号的位置,javascript,html,css,ecmascript-6,Javascript,Html,Css,Ecmascript 6,如何在contenteditable元素中保持插入符号的位置,当我尝试更新可编辑元素的innerHTML时,插入符号位置跳到行的第一个位置,我需要一个函数,该函数可以在可编辑元素innerHTML更新或更改时保持插入符号的位置 我的代码: // content editable element let editor = document.getElementById("editor"); editor.onkeypress = (e) => { if (e.keyCode ===

如何在contenteditable元素中保持插入符号的位置,当我尝试更新可编辑元素的
innerHTML
时,插入符号位置跳到行的第一个位置,我需要一个函数,该函数可以在可编辑元素
innerHTML
更新或更改时保持插入符号的位置

我的代码:

// content editable element
let editor = document.getElementById("editor");

editor.onkeypress = (e) => {
    if (e.keyCode === 32) {
        let lines = editor.children;
        for (let line of lines) {
            line.innerHTML += "Hello World !!!";
        }
    }
}
我的答覆是:

// content editable element
let editor = document.getElementById("editor");

// on keypress
editor.onkeypress = () => {
    // get the position of caret
    let pos = getCaretPos(editor.children[0]);

    // update the innerHTML
    editor.children[0].innerHTML += "Hello World !!!";

    // set the caret position
    setCaretPos(editor.children[0], pos);
}

function getCaretPos(element) {
    var ie = (typeof document.selection != "undefined" && document.selection.type != "Control") && true;
    var w3 = (typeof window.getSelection != "undefined") && true;
    var caretOffset = 0;
    if (w3) {
        var range = window.getSelection().getRangeAt(0);
        var preCaretRange = range.cloneRange();
        preCaretRange.selectNodeContents(element);
        preCaretRange.setEnd(range.endContainer, range.endOffset);
        caretOffset = preCaretRange.toString().length;
    } else if (ie) {
        var textRange = document.selection.createRange();
        var preCaretTextRange = document.body.createTextRange();
        preCaretTextRange.moveToElementText(element);
        preCaretTextRange.setEndPoint("EndToEnd", textRange);
        caretOffset = preCaretTextRange.text.length;
    }
    return caretOffset;
}

function setCaretPos(element, position) {
    var node = element;
    node.focus();
    var textNode = node.firstChild;
    var caret = position; // insert caret after the 10th character say
    var range = document.createRange();
    range.setStart(textNode, caret);
    range.setEnd(textNode, caret);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
}

最简单的答案是不要使用
innerHTML
。如果您使用的是contenteditable,那么关键是您要处理一个一致的活动DOM文档。如果插入字符串,浏览器将无法知道光标在后面的位置,因为您正在销毁它所拥有的所有信息。这很像你做的
line.innerHTML=“”;line.innerHTML=“你好,世界!!!”,因此光标会一直推到开始/结束处

考虑到这一点,你可以做到

if (e.keyCode === 32) {
    // 1. Get the children as a normal JS array, so that adding
    //    children in the next bit of code doesn't break for for-of.
    let lines = Array.from(editor.children);
    // Old Browsers:
    //   let lines = Array.prototype.slice.call(editor.children);

    for (let line of lines) {
        const newText = "Hello World !!!";

        // 2. Insert the text immediately after the 'line' DOM node.
        line.after(newText); 
        // Older Browsers:
        //   line.parentNode.insertBefore(
        //     document.createTextNode(newText), line.nextSibling);

    }
    // 3. Normalize the document, so that if the code above inserted multiple text nodes
    //    in a row (potentially meaning that `editor.children` is no longer just lines), 
    //    the nodes will be merged back together.
    editor.normalize();
}
如果不知道editor.children
具体包含什么,我无法100%肯定这会起作用,但类似的东西肯定会起作用