【问题标题】:Set Caret Position in 'contenteditable' div that has children在有孩子的'contenteditable'div中设置插入符号位置
【发布时间】:2016-04-26 15:34:08
【问题描述】:

我有一个这样的 HTML 结构:

<div contenteditable="true">This is some plain, boring content.</div>

我还有这个功能,可以让我将插入符号的位置设置到 div 中我想要的任何位置:

// Move caret to a specific point in a DOM element
function SetCaretPosition(object, pos)
{
    // Get key data
    var el = object.get(0); // Strip inner object from jQuery object
    var range = document.createRange();
    var sel = window.getSelection();

    // Set the range of the DOM element
    range.setStart(el.childNodes[0], pos);
    range.collapse(true);

    // Set the selection point
    sel.removeAllRanges();
    sel.addRange(range);
}

在我开始将子标签 (span, b, i, u, strike, sup, sub) 添加到 div 之前,此代码可以正常工作,例如

<div contenteditable="true">
    This is some <span class="fancy">plain</span>, boring content.
</div>

当这些子标签以自己的子标签结束时,事情会变得更加复杂,例如

<div contenteditable="true">
    This is some <span class="fancy"><i>plain</i></span>, boring content.
</div>

基本上,发生的情况是,当我尝试将SetCaretPosition 指向高于子标签开头的索引时,setStart 会抛出一个IndexSizeError。 setStart 仅在到达第一个子标签之前有效。

我需要的是 SetCaretPosition 函数处理未知数量的这些子标签(可能还有未知数量的嵌套子标签),以便设置位置的方式与没有标签。

所以对于这两个:

<div contenteditable="true">This is some plain, boring content.</div>

还有这个:

<div contenteditable="true">
    This is <u>some</u> <span class="fancy"><i>plain</i></span>, boring content.
</div>

SetCaretPosition(div, 20); 会将插入符号放在 'boring' 中的 'b' 之前。

我需要什么代码?非常感谢!

【问题讨论】:

    标签: javascript jquery html


    【解决方案1】:

    所以,我遇到了同样的问题并决定快速编写自己的例程,它递归遍历所有子节点并设置位置。 请注意这是如何将 DOM 节点作为参数,而不是像您的原始帖子那样使用 jquery 对象

    // Move caret to a specific point in a DOM element
    function SetCaretPosition(el, pos){
    
        // Loop through all child nodes
        for(var node of el.childNodes){
            if(node.nodeType == 3){ // we have a text node
                if(node.length >= pos){
                    // finally add our range
                    var range = document.createRange(),
                        sel = window.getSelection();
                    range.setStart(node,pos);
                    range.collapse(true);
                    sel.removeAllRanges();
                    sel.addRange(range);
                    return -1; // we are done
                }else{
                    pos -= node.length;
                }
            }else{
                pos = SetCaretPosition(node,pos);
                if(pos == -1){
                    return -1; // no need to finish the for loop
                }
            }
        }
        return pos; // needed because of recursion stuff
    }
    

    希望对你有帮助!

    【讨论】:

    • 谢谢!我最终编写了一个自己的函数来保留 jQuery 对象并递归搜索 DOM 子对象,但这也很有用!
    • 我整个星期都在网上搜索,但没有找到比这个更好的答案
    • > 希望对您有所帮助!它确实做到了!非常感谢@Sorunome。
    【解决方案2】:

    它只适用于object Text childNodes(0)。所以你必须做它。这里不是很标准的代码,但是有效。目标是(我们)的(p) id将输出对象文本。如果确实如此,那么它可能会起作用。

    <div id="editable" contenteditable="true">dddddddddddddddddddddddddddd<p>dd</p>psss<p>dd</p><p>dd</p>
    <p>text text text</p>
     </div>
    <p id='we'></p>
    <button onclick="set_mouse()">focus</button>
     <script>
    function set_mouse() {
        var as = document.getElementById("editable");
        el=as.childNodes[1].childNodes[0];//goal is to get ('we') id to write (object Text)
      var range = document.createRange();
         var sel = window.getSelection();
    range.setStart(el, 1);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    
    document.getElementById("we").innerHTML=el;// see out put of we id
    }
    </script>
    

    【讨论】:

      猜你喜欢
      • 2013-07-18
      • 2011-08-22
      • 2010-10-06
      • 2013-07-25
      • 2014-07-29
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      相关资源
      最近更新 更多