如何使用 html 子元素获取 contenteditable div 中的插入符位置?
我正在使用一个 contenteditable div,它可以选择在文本流中包含内联 html 元素,例如标签。
在某些时候,我需要获取插入符号位置,但发现在示例代码中,如果插入符号位于 html 子元素之后,则返回的位置不正确。
我需要一个跨浏览器解决方案,它允许我存储插入符号的位置,以便即使文本流中存在 html 元素,也可以在瞬间恢复它。
示例:
function getCaretPosition(editableDiv) {
var caretPos = 0, containerEl = null, sel, range;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
if (range.commonAncestorContainer.parentNode == editableDiv) {
caretPos = range.endOffset;
}
}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
if (range.parentElement() == editableDiv) {
var tempEl = document.createElement("span");
editableDiv.insertBefore(tempEl, editableDiv.firstChild);
var tempRange = range.duplicate();
tempRange.moveToElementText(tempEl);
tempRange.setEndPoint("EndToEnd", range);
caretPos = tempRange.text.length;
}
}
return caretPos;
}
$('div').keyup(function(){
alert(getCaretPosition(this));
});
div{width:300px; height:100px; border:solid 1px #DDD;}
div a{background:#333; color:#FFF;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div contenteditable=true>
some example text <a>anchor tag</a>
</div>
原始 JSFiddle: http://jsfiddle.net/wPYMR/2/
I am working with a contenteditable div that will have the option to have inline html elements such as tags in the text flow.
At certain points I need to grab the caret position but have found that with the example code the position returned is incorrect if the caret is after an html child element.
I need a cross browser solution that will allow me to store the position of the caret so that it can be restored a split second later even with the presence of html elements in the text flow.
Example:
function getCaretPosition(editableDiv) {
var caretPos = 0, containerEl = null, sel, range;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
if (range.commonAncestorContainer.parentNode == editableDiv) {
caretPos = range.endOffset;
}
}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
if (range.parentElement() == editableDiv) {
var tempEl = document.createElement("span");
editableDiv.insertBefore(tempEl, editableDiv.firstChild);
var tempRange = range.duplicate();
tempRange.moveToElementText(tempEl);
tempRange.setEndPoint("EndToEnd", range);
caretPos = tempRange.text.length;
}
}
return caretPos;
}
$('div').keyup(function(){
alert(getCaretPosition(this));
});
div{width:300px; height:100px; border:solid 1px #DDD;}
div a{background:#333; color:#FFF;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div contenteditable=true>
some example text <a>anchor tag</a>
</div>
Original JSFiddle: http://jsfiddle.net/wPYMR/2/
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在这里回答了一个非常类似的问题: 在 IE 中编辑 Iframe 内容 - 维护文本选择的问题
这是该答案的一个稍微简化的版本:
如果您不更改 contenteditable 元素的内容,则可以使用以下函数。在执行任何您需要执行的操作之前调用
saveSelection()
,然后调用restoreSelection()
。如果您要更改内容,我建议使用我的 Rangy 库的 保存/恢复选择模块。使用示例:
I've answered a very similar question here: Editing Iframe Content in IE - problem in maintaining text selection
Here's a slightly simplified version of that answer:
If you're not changing the contents of the contenteditable element then the following functions will do. Call
saveSelection()
before doing whatever you need to do andrestoreSelection()
afterwards. If you are changing the content, I'd suggest using my Rangy library's save/restore selection module.Example use: