Dans IE >= 9 et les navigateurs non-IE (Firefox 4+, navigateurs WebKit sortis depuis le début de 2009, Opera 11, peut-être plus tôt), vous pouvez utiliser la méthode getClientRects()
de Range
. Dans IE 4 à 10, vous pouvez utiliser les propriétés boundingLeft
et boundingTop
de TextRange
qui peuvent être extraites de la sélection. Voici une fonction qui fera ce que vous voulez dans les navigateurs récents.
Remarquez qu'il existe certaines situations où vous pouvez obtenir incorrectement les coordonnées 0, 0
, comme mentionné dans les commentaires par @Louis. Dans ce cas, vous devrez revenir à une solution de contournement en insérant temporairement un élément et en obtenant sa position.
jsFiddle: http://jsfiddle.net/NFJ9r/132/
Code:
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;
}
// Revenir à l'insertion d'un élément temporaire
if (x == 0 && y == 0) {
var span = doc.createElement("span");
if (span.getClientRects) {
// Assurez-vous que le span a des dimensions et une position en
// ajoutant un caractère d'espace de largeur zéro
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);
// Coller les nœuds textuels fragmentés ensemble
spanParent.normalize();
}
}
}
}
return { x: x, y: y };
}
MISE À JOUR
J'ai soumis un bogue WebKit suite aux commentaires, et il a maintenant été corrigé.
https://bugs.webkit.org/show_bug.cgi?id=65324