Get a range's start and end offset's relative to its parent container
Suppose I have this HTML element:
<div id="parent">
Hello everyone! <a>This is my home page</a>
<p>Bye!</p>
</div>
And the user selects "home" with his mouse.
I want to be able to determine how many characters into #parent
his selection starts (and how many characters from the end of #parent
his selection ends). This should work even if he selects an HTML tag. (And I need it to work in all browsers)
range.startOffset
looks promising, but it is an offset relative only to the range's immediate container, and is a character offset only if the container is a text node.
UPDATE
As pointed out in the comments, my original answer (below) only returns the end of the selection or the caret position. It's fairly easy to adapt the code to return a start and an end offset; here's an example that does so:
function getSelectionCharacterOffsetWithin(element) {
var start = 0;
var end = 0;
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.startContainer, range.startOffset);
start = preCaretRange.toString().length;
preCaretRange.setEnd(range.endContainer, range.endOffset);
end = preCaretRange.toString().length;
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(element);
preCaretTextRange.setEndPoint("EndToStart", textRange);
start = preCaretTextRange.text.length;
preCaretTextRange.setEndPoint("EndToEnd", textRange);
end = preCaretTextRange.text.length;
}
return { start: start, end: end };
}
function reportSelection() {
var selOffsets = getSelectionCharacterOffsetWithin( document.getElementById("editor") );
document.getElementById("selectionLog").innerHTML = "Selection offsets: " + selOffsets.start + ", " + selOffsets.end;
}
window.onload = function() {
document.addEventListener("selectionchange", reportSelection, false);
document.addEventListener("mouseup", reportSelection, false);
document.addEventListener("mousedown", reportSelection, false);
document.addEventListener("keyup", reportSelection, false);
};
#editor {
padding: 5px;
border: solid green 1px;
}
Select something in the content below:
<div id="editor" contenteditable="true">A <i>wombat</i> is a marsupial native to <b>Australia</b></div>
<div id="selectionLog"></div>
I know this is a year old, but this post is a top search result for a lot of questions on finding the Caret position and I found this useful.
I was trying to use Tim's excellent script above to find the new cursor position after having drag-dropped an element from one position to another in a content editable div. It worked perfectly in FF and IE, but in Chrome, the dragging action highlighted all content between the beginning and end of the drag, which resulted in the returned caretOffset
being too large or small (by the length of the selected area).
I added a few lines to the first if statement to check if text has been selected and adjust the result accordingly. The new statement is below. Forgive me if it's inappropriate to add this here, as it's not what the OP was trying to do, but as I said, several searches on info related to Caret position led me to this post, so it's (hopefully) likely to help someone else.
Tim's first if statement with added lines(*):
if (typeof window.getSelection != "undefined") {
var range = window.getSelection().getRangeAt(0);
var selected = range.toString().length; // *
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
if(selected){ // *
caretOffset = preCaretRange.toString().length - selected; // *
} else { // *
caretOffset = preCaretRange.toString().length;
} // *
}
链接地址: http://www.djcxy.com/p/65460.html
上一篇: 在包含HTML内容的contentEditable区域中获取插入(光标)位置
下一篇: 获取范围的开始和结束偏移量相对于其父容器