在有孩子的'contenteditable'div中设置Caret Position [英] Set Caret Position in 'contenteditable' div that has children
问题描述
我有这样的HTML结构:
< div contenteditable =true>这是一些简单的,无聊的内容。< / div>
我也有这个功能,允许我将插入位置设置为div中我想要的任何位置:
//将插入符号移动到DOM元素中的特定点
函数SetCaretPosition(object,pos)
{
//获取关键数据
var el = object.get(0); //从jQuery对象中剥离内部对象
var range = document.createRange();
var sel = window.getSelection();
//设置DOM元素的范围
range.setStart(el.childNodes [0],pos);
range.collapse(true);
//设置选择点
sel.removeAllRanges();
sel.addRange(range);
}
此代码完全正常,直到我开始添加子标记(span,b,i,u,strike,sup,sub)
到div例如
< div contenteditable =true>
这是一些< span class =fancy> plain< / span>,无聊的内容。
< / div>
当这些子标签最终带有自己的子标签时,事情会变得更复杂,例如
< div contenteditable =true>
这是一些< span class =fancy>< i> plain< / i>< / span> ;,无聊的内容。
< / div>
基本上,会发生什么,是 setStart
当我尝试 SetCaretPosition
到高于子标记开头的索引时,抛出 IndexSizeError
。 setStart
只有在到达第一个子标签时才会有效。
我需要的是 SetCaretPosition
函数用于处理未知数量的这些子标记(以及可能是未知数量的嵌套子标记),以便设置位置的工作方式与没有标记时相同。 / p>
所以对于这两个:
< div contenteditable =true >这是一些简单,无聊的内容。< / div>
这个:
< div contenteditable =true>
这是< u>一些< / u> < span class =fancy>< i> plain< / i>< / span> ;,无聊的内容。
< / div>
SetCaretPosition(div,20);
将将插入符号放在b之前的无聊中。
我需要的代码是什么?非常感谢!
所以,我遇到了同样的问题,并决定快速编写自己的例程,它遍历了所有的子节点递归并设置位置。
注意这是如何将DOM节点作为参数,而不是像原始帖子那样的jquery对象
//移动插入DOM元素中的特定点
函数SetCaretPosition(el,pos){
//遍历所有子节点
for(var节点el.childNodes){
if(node.nodeType == 3){//我们有一个文本节点
if(node.length> = pos){
//最后添加我们的范围
var range = document.createRange(),
sel = window.getSelection();
range.setStart(node,pos);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
返回-1; //我们完成了
} else {
pos - = node.length;
}
} else {
pos = SetCaretPosition(node,pos);
if(pos == -1){
return -1; //无需完成for循环
}
}
}
返回pos; //因为递归而需要
}
我希望这对你有所帮助! / p>
I have an HTML structure like this:
<div contenteditable="true">This is some plain, boring content.</div>
I also have this function that allows me to set the caret position to anywhere I want within the 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);
}
This code works completely fine until I start adding child tags (span, b, i, u, strike, sup, sub)
to the div e.g.
<div contenteditable="true">
This is some <span class="fancy">plain</span>, boring content.
</div>
Things get more complicated when these child tags end up with child tags of their own e.g.
<div contenteditable="true">
This is some <span class="fancy"><i>plain</i></span>, boring content.
</div>
Essentially, what happens, is that setStart
throws an IndexSizeError
when I try to SetCaretPosition
to an index higher than the start of a child tag. setStart
only works until it reaches the first child tag.
What I need, is for the SetCaretPosition
function to handle an unknown number of these child tags (and potentially an unknown number of nested child tags) so that setting the position works in the same way it would if there were no tags.
So for both this:
<div contenteditable="true">This is some plain, boring content.</div>
and this:
<div contenteditable="true">
This is <u>some</u> <span class="fancy"><i>plain</i></span>, boring content.
</div>
SetCaretPosition(div, 20);
would place the caret before the 'b' in 'boring'.
What is the code I need? Many thanks!
So, I was experiencing the same issue and decided to write my own routine quickly, it walks through all the child nodes recursively and set the position. Note how this takes a DOM node as argument, not a jquery object as your original post does
// 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
}
I hope this'll help you!
这篇关于在有孩子的'contenteditable'div中设置Caret Position的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!