[英]How to get caret position within contenteditable div with html child elements?
I am working with a contenteditable div that will have the option to have inline html elements such as tags in the text flow.我正在使用一个 contenteditable div,它可以选择在文本流中包含内联 html 元素,例如标签。
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.在某些时候,我需要获取插入符 position,但发现如果插入符位于 html 子元素之后,则使用示例代码返回的 position 是不正确的。
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.我需要一个跨浏览器解决方案,它允许我存储插入符号的 position,以便即使在文本流中存在 html 元素的情况下也可以稍后恢复它。
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/原始 JSFiddle: http://jsfiddle.net/wPYMR/2/
I've answered a very similar question here: Editing Iframe Content in IE - problem in maintaining text selection 我在这里回答了一个非常相似的问题: 在IE中编辑iframe内容 - 维护文本选择的问题
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. 如果您没有更改contenteditable元素的内容,那么以下函数将执行。 Call saveSelection()
before doing whatever you need to do and restoreSelection()
afterwards. 在做任何你需要做的事之前调用saveSelection()
然后再调用restoreSelection()
。 If you are changing the content, I'd suggest using my Rangy library's save/restore selection module . 如果您要更改内容,我建议使用我的Rangy库的保存/恢复选择模块 。
var saveSelection, restoreSelection;
if (window.getSelection) {
// IE 9 and non-IE
saveSelection = function() {
var sel = window.getSelection(), ranges = [];
if (sel.rangeCount) {
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
ranges.push(sel.getRangeAt(i));
}
}
return ranges;
};
restoreSelection = function(savedSelection) {
var sel = window.getSelection();
sel.removeAllRanges();
for (var i = 0, len = savedSelection.length; i < len; ++i) {
sel.addRange(savedSelection[i]);
}
};
} else if (document.selection && document.selection.createRange) {
// IE <= 8
saveSelection = function() {
var sel = document.selection;
return (sel.type != "None") ? sel.createRange() : null;
};
restoreSelection = function(savedSelection) {
if (savedSelection) {
savedSelection.select();
}
};
}
Example use: 使用示例:
var sel = saveSelection();
// Do stuff here
restoreSelection(sel);
I posted a question about a cross-browser range/selection library and found some great stuff that I was able to solve all my needs with. 我发布了一个关于跨浏览器范围/选择库的问题,并发现了一些我能够解决所有需求的好东西。
Here is my post: Cross Browser Selection Range Library? 这是我的帖子: 跨浏览器选择范围库?
What helped me best was Tim Down's rangy . 最让我感到欣慰的是蒂姆·唐的笨拙 。
var display = $("#autocomplete");
var editArea = $('#editArea');
console.log(e.target.selectionStart);
var pos = $("#editArea").caret();
var offset = editArea.offset();
// now you can use left, top(they are relative position)
display.css({
left: offset.left + 10,
top: offset.top + 13,
color : "#449"
})
display.toggleClass("show");
return false;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.