web-dev-qa-db-fra.com

offsetTop contre jQuery.offset (). haut

J'ai lu que offsetLeft et offsetTop ne fonctionnent pas correctement dans tous les navigateurs. jQuery.offset() est supposé fournir une abstraction pour que cela donne la valeur correcte xbrowser.

Ce que j'essaie de faire est d'obtenir les coordonnées de l'endroit où un élément a été cliqué par rapport au coin supérieur gauche de l'élément.

Le problème est que jQuery.offset().top me donne en fait une valeur décimale dans FFX 3.6 (dans IE et Chrome, les deux valeurs correspondent).

Ce violon présente le problème. Si vous cliquez sur l'image du bas, jQuery.offset().top renvoie 327,5, mais offsetTop renvoie 328.

J'aimerais penser que offset() renvoie la valeur correcte et que je devrais l'utiliser car cela fonctionnera sur tous les navigateurs. Cependant, les personnes ne peuvent évidemment pas cliquer sur les décimales de pixels. Est-ce la bonne façon de déterminer le décalage réel par rapport à Math.round() le décalage renvoyé par jQuery? Devrais-je utiliser offsetTop à la place, ou une autre méthode entièrement?

73
Explosion Pills

Je pense que vous avez raison en disant que les gens ne peuvent pas cliquer sur la moitié des pixels, alors personnellement, j'utiliserais un décalage arrondi jQuery ...

13
ChristopheCVB

C’est ce que jQuery API Doc dit à propos de .offset():

Obtenez les coordonnées actuelles du premier élément ou définissez les coordonnées de chaque élément dans l'ensemble d'éléments correspondants, par rapport au document .

C'est ce que API Web MDN dit à propos de .offsetTop:

offsetTop renvoie la distance de l'élément actuel par rapport au sommet du noeud offsetParent

C'est ce que fait jQuery v.1.11 .offset() pour obtenir les coordonnées:

var box = { top: 0, left: 0 };

// BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== strundefined ) {
  box = elem.getBoundingClientRect();
}
win = getWindow( doc );
return {
  top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
  left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
};
  • pageYOffset dit intuitivement combien la page a défilé
  • docElem.scrollTop Est la solution de secours pour IE <9 (qui ne sont pas pris en charge par BTW dans jQuery 2)
  • docElem.clientTop Est la largeur de la bordure supérieure d'un élément (le document dans ce cas)
  • elem.getBoundingClientRect() obtient les coordonnées par rapport à la document  viewport (voir les commentaires). Il peut retourner des valeurs de fraction, c'est donc la source de votre bogue. C'est aussi peut causer un bogue dans IE <8 quand la page est zoomée. Pour éviter les valeurs de fraction, essayez de calculer la position itérativement

Conclusion

  • Si vous voulez des valeurs relatives au nœud parent , utilisez element.offsetTop. Ajoutez element.scrollTop Si vous souhaitez prendre en compte le défilement parent. (ou utilisez jQuery . position () si vous êtes fan de cette bibliothèque)
  • Si vous voulez des valeurs relatives à la vue , utilisez element.getBoundingClientRect().top. Ajoutez window.pageYOffset Si vous souhaitez prendre en compte le défilement du document. Vous n'avez pas besoin de soustraire le clientTop du document si le document n'a pas de bordure (ce n'est généralement pas le cas), vous avez donc une position relative par rapport au document
  • Soustrayez element.clientTop Si vous ne considérez pas la bordure d'élément comme une partie de l'élément
72
Jan Turoň

Essayez ceci: parseInt(jQuery.offset().top, 10)

4
Steve Chan

Il est possible que offset soit un non-entier, en utilisant em comme unité de mesure, relatif font-sizes dans %.

Je pense aussi que le offset pourrait ne pas être un nombre entier lorsque le zoom n'est pas 100% _ mais cela dépend de la façon dont le navigateur gère la mise à l'échelle.

2
Emyr