2016-04-26 82 views
5

我有一个HTML的结构是这样的:设置插入符位置在“CONTENTEDITABLE”的div有孩子

<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> 

本质上,发生了什么,是setStart抛出一个IndexSizeError当我尝试SetCaretPosition比的子标签的起始较高的指数。 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);会前 '无聊' 的 'B' 的地方插入符号。

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

回答

7

因此,我遇到了同样的问题,并决定快速编写自己的例程,它递归地遍历所有子节点并设置位置。 注意这是如何发生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 
} 

我希望这会帮助你的!

+0

谢谢!我最终编写了一个我自己的函数,它保留了jQuery对象并递归地搜索DOM子代,但这也很有用! – John1984

0

它只适用于对象文本 childNodes(0)。所以你必须做它。这里不是非常标准的代码,但works.Goal是(我们)的(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> 
相关问题