В IE> = 9 и браузерах, отличных от IE (Firefox 4+, браузеры WebKit, выпущенные с начала 2009 года, Opera 11, возможно, ранее), вы можете использовать _ 1_ метод Range
. В IE 4–10 вы можете использовать свойства boundingLeft
и boundingTop
TextRange
, которые можно извлечь из выделения. Вот функция, которая будет делать то, что вы хотите в последних версиях браузеров.
Обратите внимание, что есть некоторые ситуации, в которых вы можете ошибочно получить координаты 0, 0
, как упоминалось в комментариях @Louis. В этом случае вам придется вернуться к временному решению: временно вставить элемент и получить его позицию.
jsFiddle: http://jsfiddle.net/NFJ9r/132/
Код:
function getSelectionCoords(win) {
win = win || window;
var doc = win.document;
var sel = doc.selection, range, rects, rect;
var x = 0, y = 0;
if (sel) {
if (sel.type != "Control") {
range = sel.createRange();
range.collapse(true);
x = range.boundingLeft;
y = range.boundingTop;
}
} else if (win.getSelection) {
sel = win.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0).cloneRange();
if (range.getClientRects) {
range.collapse(true);
rects = range.getClientRects();
if (rects.length > 0) {
rect = rects[0];
}
x = rect.left;
y = rect.top;
}
// Fall back to inserting a temporary element
if (x == 0 && y == 0) {
var span = doc.createElement("span");
if (span.getClientRects) {
// Ensure span has dimensions and position by
// adding a zero-width space character
span.appendChild( doc.createTextNode("\u200b") );
range.insertNode(span);
rect = span.getClientRects()[0];
x = rect.left;
y = rect.top;
var spanParent = span.parentNode;
spanParent.removeChild(span);
// Glue any broken text nodes back together
spanParent.normalize();
}
}
}
}
return { x: x, y: y };
}
ОБНОВЛЕНИЕ
Я отправил ошибку WebKit в результате комментариев, и теперь она исправлена.
https://bugs.webkit.org/show_bug.cgi?id=65324
person
Tim Down
schedule
27.07.2011