Je veux savoir comment obtenir la position X et Y d'éléments HTML tels que img
et div
en JavaScript.
A article très intéressant sur les coordonnées JS . Cet article n'est mentionné nulle part sur SO, il devrait
Je veux savoir comment obtenir la position X et Y d'éléments HTML tels que img
et div
en JavaScript.
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>');
A article très intéressant sur les coordonnées JS . Cet article n'est mentionné nulle part sur SO, il devrait
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;
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).
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()
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.
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/
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.
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 ?
0 votes
Bonjour M. Greg, pouvez-vous résoudre mon problème ? J'ai juste posté mon lien, cliquez dessus une fois. stackoverflow.com/questions/41743667/
18 votes
@Mote, Non, ce n'est pas si évident. Laissez l'inférence, la subjectivité et les faux axiomes de côté. Il peut être relatif au viewport ou au haut de la page (aka document.documentElement).
21 votes
Le choix par défaut du plus général n'est pas une inférence, c'est la progression logique, donc ce serait relatif à la fenêtre, ou "haut de page" pourrait être le terme comme vous le dites. En théorie des jeux, cela est codifié comme un concept appelé point de Schelling. Veillez à préciser quand vous ne voulez pas dire le cas le plus général.
9 votes
Le fait est que ce qui est évident pour certains ne l'est pas pour d'autres. Même si en théorie nous savons ce qu'il en est, en raison de la connaissance empirique, la clarté ne fait de mal à personne ici, en particulier à ceux qui viennent de commencer à programmer.