[英]Set Caret Position in 'contenteditable' div that has children
我有一个这样的 HTML 结构:
<div contenteditable="true">This is some plain, boring content.</div>
我也有这个 function 允许我将插入符号 position 设置到 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);
}
在我开始向 div 添加子标签(span, b, i, u, strike, sup, sub)
之前,这段代码完全可以正常工作,例如
<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
function 处理未知数量的这些子标签(以及可能未知数量的嵌套子标签),以便设置 position 的工作方式与没有标签时的工作方式相同。
所以对于这两个:
<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”之前。
我需要什么代码? 非常感谢!
所以,我遇到了同样的问题,并决定快速编写自己的例程,它递归遍历所有子节点并设置位置。 注意这是如何将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
}
我希望这对你有所帮助!
如果您要根据可编辑内容的字符索引将插入符号设为 position,最简单的方法是使用modify
方法:
const position = 6;
const el = document.querySelector('#editable');
const selection = document.getSelection();
if (!selection || !el) return;
// Set the caret to the beggining
selection.collapse(el, 0);
// Move the caret to the position
for (let index = 0; index < position; index++) {
selection.modify('move', 'forward', 'character');
}
不需要遍历子节点。
它只适用于对象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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.