This is slightly verbose because of long-winded boundary comparisons and because IE takes a different approach from other browsers, but does the job in all major browsers. It also handles multiple selections in Firefox.
jsFiddle: http://jsfiddle.net/Q982A/2/
Code:
function getSelectedTextWithin(el) {
var selectedText = "";
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection(), rangeCount;
if ( (rangeCount = sel.rangeCount) > 0 ) {
var range = document.createRange();
for (var i = 0, selRange; i < rangeCount; ++i) {
range.selectNodeContents(el);
selRange = sel.getRangeAt(i);
if (selRange.compareBoundaryPoints(range.START_TO_END, range) == 1 && selRange.compareBoundaryPoints(range.END_TO_START, range) == -1) {
if (selRange.compareBoundaryPoints(range.START_TO_START, range) == 1) {
range.setStart(selRange.startContainer, selRange.startOffset);
}
if (selRange.compareBoundaryPoints(range.END_TO_END, range) == -1) {
range.setEnd(selRange.endContainer, selRange.endOffset);
}
selectedText += range.toString();
}
}
}
} else if (typeof document.selection != "undefined" && document.selection.type == "Text") {
var selTextRange = document.selection.createRange();
var textRange = selTextRange.duplicate();
textRange.moveToElementText(el);
if (selTextRange.compareEndPoints("EndToStart", textRange) == 1 && selTextRange.compareEndPoints("StartToEnd", textRange) == -1) {
if (selTextRange.compareEndPoints("StartToStart", textRange) == 1) {
textRange.setEndPoint("StartToStart", selTextRange);
}
if (selTextRange.compareEndPoints("EndToEnd", textRange) == -1) {
textRange.setEndPoint("EndToEnd", selTextRange);
}
selectedText = textRange.text;
}
}
return selectedText;
}
Alternatively, you could use my Rangy library, and the code becomes:
function getSelectedTextWithin(el) {
var selectedText = "";
var sel = rangy.getSelection(), rangeCount = sel.rangeCount;
var range = rangy.createRange();
range.selectNodeContents(el);
for (var i = 0; i < rangeCount; ++i) {
selectedText += sel.getRangeAt(i).intersection(range);
}
return selectedText;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…