2214 votes

Récupérer la position (X,Y) d'un élément HTML

Je veux savoir comment obtenir la position X et Y d'éléments HTML tels que img et div en JavaScript.

8 votes

J'ai utilisé ces 7 lignes de code qui fonctionnent dans tous les navigateurs avec des différences dans ie5, 6, 7 (je ne me souviens pas avoir eu de problème... c'est peut-être le type de document) ... quirksmode.org/js/findpos.html Je l'ai utilisé pendant de nombreuses années. Peut-être que quelqu'un pourra me signaler les défauts éventuels.

124 votes

@AnthonyWJones, je suppose que vous aviez besoin de ce plaisir pédant, mais il est évident, comme c'est toujours le cas lorsqu'il n'y a pas de spécification, que le PO fait référence au cas le plus général, ou fait référence aux coordonnées de la fenêtre du navigateur.

2 votes

La réponse de @AndyE est clairement gagnante - pouvez-vous s'il vous plaît marquer la réponse acceptée, afin que les autres n'aient pas à lire 10 autres réponses pour y arriver ?

2390voto

Andy E Points 132925

L'approche correcte consiste à utiliser element.getBoundingClientRect() :

var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);

Internet Explorer prend en charge cette fonction depuis aussi longtemps que vous pouvez vous en préoccuper, et elle a finalement été normalisée dans le cadre de l'initiative de la Commission européenne. Vues du CSSOM . Tous les autres navigateurs l'ont adopté il y a longtemps .

Certains navigateurs renvoient également les propriétés hauteur et largeur, bien que cela ne soit pas standard. Si vous êtes préoccupé par la compatibilité avec les anciens navigateurs, consultez les révisions de cette réponse pour une mise en œuvre optimisée de la dégradation.

Les valeurs renvoyées par element.getBoundingClientRect() sont relatifs à la fenêtre d'affichage. Si vous en avez besoin par rapport à un autre élément, il suffit de soustraire un rectangle de l'autre :

var bodyRect = document.body.getBoundingClientRect(),
    elemRect = element.getBoundingClientRect(),
    offset   = elemRect.top - bodyRect.top;

alert('Element is ' + offset + ' vertical pixels from <body>');

190 votes

A article très intéressant sur les coordonnées JS . Cet article n'est mentionné nulle part sur SO, il devrait

11 votes

BoundingClientRect change pendant le défilement

0 votes

Merci pour cette belle solution et merci aussi à @Déjàvu pour la belle source.

369voto

meouw Points 21368

Les bibliothèques se donnent du mal pour obtenir des décalages précis pour un élément.
Voici une fonction simple qui fait l'affaire dans toutes les circonstances que j'ai essayées.

EDIT : voir le commentaire d'Adams

function getOffset( el ) {
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
        _x += el.offsetLeft - el.scrollLeft;
        _y += el.offsetTop - el.scrollTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}
var x = getOffset( document.getElementById('yourElId') ).left;

16 votes

Changez : el = el.parentNode en : el = el.offsetParent ; et cela semble fonctionner pour les iframes imbriquées maintenant... Je pense que c'est ce que vous vouliez ?

0 votes

J'ai testé cela, ça marche super bien même avec un niveau de zoom présent !

63voto

AnthonyWJones Points 122520

Sur la plupart des navigateurs, les éléments HTML auront :-

offsetLeft
offsetTop

Ils spécifient la position de l'élément par rapport à son parent le plus proche qui a une mise en page. Ce parent est souvent accessible par la propriété offsetParent.

IE et FF3 ont

clientLeft
clientTop

Ces propriétés sont moins courantes, elles spécifient la position d'un élément par rapport à la zone client de ses parents (la zone rembourrée fait partie de la zone client, mais pas la bordure ni la marge).

38voto

Refik Ayata Points 159

Si la page comprend - au moins - un "DIV", la fonction donnée par meouw envoie la valeur "Y" au-delà des limites actuelles de la page. Afin de trouver la position exacte, vous devez gérer les deux "offsetParent "s et "parentNode "s.

Essayez le code donné ci-dessous (il est vérifié pour FF2) :

function findPos(obj) {
 var obj2 = obj;
 var curtop = 0;
 var curleft = 0;
 if (document.getElementById || document.all) {
  do  {
   curleft += obj.offsetLeft-obj.scrollLeft;
   curtop += obj.offsetTop-obj.scrollTop;
   obj = obj.offsetParent;
   obj2 = obj2.parentNode;
   while (obj2!=obj) {
    curleft -= obj2.scrollLeft;
    curtop -= obj2.scrollTop;
    obj2 = obj2.parentNode;
   }
  } while (obj.offsetParent)
 } else if (document.layers) {
  curtop += obj.y;
  curleft += obj.x;
 }
 return [curtop, curleft];
}   // end of findPos()

1 votes

Comme pour les autres solutions, même avec FF 24.4, le code ci-dessus ne fonctionne pas lorsque la largeur des bordures fait partie de la disposition de positionnement.

0 votes

Vous me sauvez la vie. Je travaille sur des bugs GWT assez profonds en ce moment et jeter ceci dans une méthode JSNI résout tous mes problèmes !

37voto

ThinkingStiff Points 19251

Vous pouvez ajouter deux propriétés à la Element.prototype pour obtenir le haut/gauche de n'importe quel élément.

window.Object.defineProperty( Element.prototype, 'documentOffsetTop', {
    get: function () { 
        return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
    }
} );

window.Object.defineProperty( Element.prototype, 'documentOffsetLeft', {
    get: function () { 
        return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
    }
} );

Voici une démonstration comparant les résultats à ceux de jQuery. offset().top et .left : http://jsfiddle.net/ThinkingStiff/3G7EZ/

17 votes

Modification de Element.prototype est généralement considéré comme une mauvaise idée . Cela conduit à un code vraiment difficile à maintenir. De plus, ce code ne tient pas compte du défilement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X