[英]How do I set the caret/cursor position on a specific contenteditable div?
[英]How do you get and set the caret position in a contenteditable?
基本上我想做以下事情:
许多现有的答案似乎因跨浏览器支持而变得复杂,但我只需要它在现代 chrome 上工作。 它还需要使用 html。 理想情况下,它看起来完全像这样:
var index = getCaretPosition(contentEditableDiv);
onEdit(contentEditableDiv); // <-- callback function that manipulates the text and sets contentEditableDiv.innerHTML = theManipulatedText
setCaretPosition(contentEditableDiv, index);
我试过查看文档,但这并不简单,我认为这个问题无论如何都应该得到更简洁的答案。
这似乎对我有用,但我只针对我的用例进行了测试。
得到
function getCaretIndex(win, contentEditable) {
var index = 0;
var selection = win.getSelection();
var textNodes = textNodesUnder(contentEditable);
for(var i = 0; i < textNodes.length; i++) {
var node = textNodes[i];
var isSelectedNode = node === selection.focusNode;
if(isSelectedNode) {
index += selection.focusOffset;
break;
}
else {
index += node.textContent.length;
}
}
return index;
}
放
function setCaretIndex(win, contentEditable, newCaretIndex) {
var cumulativeIndex = 0;
var relativeIndex = 0;
var targetNode = null;
var textNodes = textNodesUnder(contentEditable);
for(var i = 0; i < textNodes.length; i++) {
var node = textNodes[i];
if(newCaretIndex <= cumulativeIndex + node.textContent.length) {
targetNode = node;
relativeIndex = newCaretIndex - cumulativeIndex;
break;
}
cumulativeIndex += node.textContent.length;
}
var range = win.document.createRange();
range.setStart(targetNode, relativeIndex);
range.setEnd(targetNode, relativeIndex);
range.collapse();
var sel = win.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
需要的帮手
function textNodesUnder(node) { // https://stackoverflow.com/a/10730777/3245937
var all = [];
for (node=node.firstChild;node;node=node.nextSibling){
if (node.nodeType==3) {
all.push(node);
}
else {
all = all.concat(textNodesUnder(node));
}
}
return all;
}
TEST (只需调用此函数)
它遍历 contenteditable 中的文本,设置插入符号索引,然后读取它。 控制台输出是: (setIndex | getIndex)
function testContentEditable() {
document.body.innerHTML = "<div contenteditable></div>"
var ce = document.querySelector("[contenteditable]");
ce.focus();
ce.innerHTML = "HELLO <span data-foo='true' style='text-decoration: underline;'><span style='color:red;'>WORLD</span> MY</span> NAME IS BOB";
var i = 0;
var intv = setInterval(function() {
if(i == ce.innerText.length) {
clearInterval(intv);
}
setCaretIndex(window, ce, i);
var currentIndex = getCaretIndex(window, ce);
console.log(i + " | " + currentIndex);
i++;
}, 100);
}
小提琴
function getCaretIndex(win, contentEditable) { var index = 0; var selection = win.getSelection(); var textNodes = textNodesUnder(contentEditable); for(var i = 0; i < textNodes.length; i++) { var node = textNodes[i]; var isSelectedNode = node === selection.focusNode; if(isSelectedNode) { index += selection.focusOffset; break; } else { index += node.textContent.length; } } return index; } function setCaretIndex(win, contentEditable, newCaretIndex) { var cumulativeIndex = 0; var relativeIndex = 0; var targetNode = null; var textNodes = textNodesUnder(contentEditable); for(var i = 0; i < textNodes.length; i++) { var node = textNodes[i]; if(newCaretIndex <= cumulativeIndex + node.textContent.length) { targetNode = node; relativeIndex = newCaretIndex - cumulativeIndex; break; } cumulativeIndex += node.textContent.length; } var range = win.document.createRange(); range.setStart(targetNode, relativeIndex); range.setEnd(targetNode, relativeIndex); range.collapse(); var sel = win.getSelection(); sel.removeAllRanges(); sel.addRange(range); } function textNodesUnder(node) { // https://stackoverflow.com/a/10730777/3245937 var all = []; for (node=node.firstChild;node;node=node.nextSibling){ if (node.nodeType==3) { all.push(node); } else { all = all.concat(textNodesUnder(node)); } } return all; } function testContentEditable() { document.body.innerHTML = "<div contenteditable></div>" var ce = document.querySelector("[contenteditable]"); ce.focus(); ce.innerHTML = "HELLO <span data-foo='true' style='text-decoration: underline;'><span style='color:red;'>WORLD</span> MY</span> NAME IS BOB"; var i = 0; var intv = setInterval(function() { if(i == ce.innerText.length) { clearInterval(intv); } setCaretIndex(window, ce, i); var currentIndex = getCaretIndex(window, ce); console.log(i + " | " + currentIndex); i++; }, 100); } testContentEditable();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.