我有contentitable div <div contenteditable="true" id="editable-div"></div>
我想使用这个脚本向这个块添加hashtag功能:
const editableDiv = document.getElementById('editable-div');
editableDiv.addEventListener('input', function (event) {
let a = editableDiv.innerHTML;
if (a.indexOf('#') !== -1) {
event.preventDefault();
const editableDiv = document.getElementById('editable-div');
let a = editableDiv.innerHTML;
// Save the current cursor position
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const startContainer = range.startContainer;
const startOffset = range.startOffset;
// Change the contents of the block
a = a.replace(/#(\w+)/g, '<a href="#">#$1</a>');
editableDiv.innerHTML = a;
// Restore the cursor position
const newRange = document.createRange();
newRange.setStart(startContainer, startOffset);
selection.removeAllRanges();
selection.addRange(newRange);
}
});
#editable-div { height:100px; background-color:grey; }
<div contenteditable="true" id="editable-div"></div>
为什么在更改块的内容后光标总是转到开头?如何解决这个问题?return();不管用。并且恢复光标位置不起作用。
1条答案
按热度按时间oewdyzsn1#
在对
editableDiv.innerHTML
进行操作之后,<div>
内部的文档对象模型将被重新构建,而原来的range.startContainer
节点#text
将不再存在。它已被替换为新的#text
节点。如果您确定
<div>
中的start容器的 * 位置 *,并在重建后将range start设置为 * 相应的 * 容器,则可以正常工作。在下面的简单示例中,位置只是<div>
中的子元素的编号。但如果<div>
的内容包含嵌套的HTML标记,则会变得更加复杂。(而不是确定 * 位置 *,可以将所有文本放置在可以通过其
id
识别的元素(例如<span>
)中。但这并不包括用户可以创建新元素的情况,例如,将<li>
元素添加到列表中。