![](/img/trans.png)
[英]How to set the caret (cursor) position in a contenteditable element (div)?
[英]How to keep the position of the caret in contenteditable element
如何在 contenteditable 元素中保持插入符号的位置,当我尝试更新可编辑元素的innerHTML
,插入符号位置跳转到该行的第一行,我需要一个可以在可编辑元素innerHTML
时保持插入符号位置的函数更新或更改谢谢。
我的代码:
// content editable element
let editor = document.getElementById("editor");
editor.onkeypress = (e) => {
if (e.keyCode === 32) {
let lines = editor.children;
for (let line of lines) {
line.innerHTML += "Hello World !!!";
}
}
}
我的答案 :
// content editable element
let editor = document.getElementById("editor");
// on keypress
editor.onkeypress = () => {
// get the position of caret
let pos = getCaretPos(editor.children[0]);
// update the innerHTML
editor.children[0].innerHTML += "Hello World !!!";
// set the caret position
setCaretPos(editor.children[0], pos);
}
function getCaretPos(element) {
var ie = (typeof document.selection != "undefined" && document.selection.type != "Control") && true;
var w3 = (typeof window.getSelection != "undefined") && true;
var caretOffset = 0;
if (w3) {
var range = window.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
} else if (ie) {
var textRange = document.selection.createRange();
var preCaretTextRange = document.body.createTextRange();
preCaretTextRange.moveToElementText(element);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
return caretOffset;
}
function setCaretPos(element, position) {
var node = element;
node.focus();
var textNode = node.firstChild;
var caret = position; // insert caret after the 10th character say
var range = document.createRange();
range.setStart(textNode, caret);
range.setEnd(textNode, caret);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
最简单的答案是不使用innerHTML
。 如果您使用的是 contenteditable,那么它的全部意义在于您有一个一致的活动 DOM 文档可以处理。 如果您插入一个字符串,浏览器将无法知道光标之后应该在哪里,因为您正在破坏它所拥有的所有信息。 这很像你做的line.innerHTML = ""; line.innerHTML = "Hello World !!!";
line.innerHTML = ""; line.innerHTML = "Hello World !!!";
,所以光标一直被推到开头/结尾。
鉴于此,你可以做
if (e.keyCode === 32) {
// 1. Get the children as a normal JS array, so that adding
// children in the next bit of code doesn't break for for-of.
let lines = Array.from(editor.children);
// Old Browsers:
// let lines = Array.prototype.slice.call(editor.children);
for (let line of lines) {
const newText = "Hello World !!!";
// 2. Insert the text immediately after the 'line' DOM node.
line.after(newText);
// Older Browsers:
// line.parentNode.insertBefore(
// document.createTextNode(newText), line.nextSibling);
}
// 3. Normalize the document, so that if the code above inserted multiple text nodes
// in a row (potentially meaning that `editor.children` is no longer just lines),
// the nodes will be merged back together.
editor.normalize();
}
在不知道editor.children
实际上具体包含什么的情况下,我不能 100% 确定这会起作用,但肯定应该这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.