Ermitteln der Position des Elements relativ zum Dokument


113

Was ist der einfachste Weg, um eine Elementposition relativ zum Dokument- / Körper- / Browserfenster zu bestimmen?

Im Moment verwende ich .offsetLeft/offsetTop, aber diese Methode gibt Ihnen nur die Position relativ zum übergeordneten Element an. Sie müssen also bestimmen, wie viele Eltern zum body-Element gehören, um die Position zu kennen, die sich auf die Position body / browser window / document bezieht.

Diese Methode ist auch zu umständlich.

Antworten:


60

Sie können die offsetParentbis zur obersten Ebene des DOM durchlaufen .

function getOffsetLeft( elem )
{
    var offsetLeft = 0;
    do {
      if ( !isNaN( elem.offsetLeft ) )
      {
          offsetLeft += elem.offsetLeft;
      }
    } while( elem = elem.offsetParent );
    return offsetLeft;
}

28
Nein, nicht, wenn ein übergeordnetes Element (insbesondere ein HTML-Element !!!) Ränder, Auffüllungen oder Ränder aufweist.
Flash Thunder

In Bezug auf das Randmaterial ... könnte es hilfreich sein, die Boxgröße auf Border-Box zu setzen ... oder etwas in dieser Richtung ... nichts, was nicht behoben werden kann ...

Zunächst müssen Sie entscheiden, ob Rand und Rand entsprechend der Boxgröße berücksichtigt werden sollen. Zweitens sollte der kollabierte Rand berücksichtigt werden. Und schließlich wird es in Zukunft eine kompliziertere Situation geben, die diese Antwort verschlimmern würde.
Xianshenglu

5
Warum ist das die akzeptierte Antwort? Dies ist veraltet und funktioniert schlecht. Tun Sie sich selbst einen Gefallen und verwenden Sie getBoundingClientRect (), wie in den anderen Antworten vorgeschlagen.
Fabian von Ellerts

175

Sie können nach oben und links gelangen, ohne DOM wie folgt zu durchlaufen:

function getCoords(elem) { // crossbrowser version
    var box = elem.getBoundingClientRect();

    var body = document.body;
    var docEl = document.documentElement;

    var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
    var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;

    var clientTop = docEl.clientTop || body.clientTop || 0;
    var clientLeft = docEl.clientLeft || body.clientLeft || 0;

    var top  = box.top +  scrollTop - clientTop;
    var left = box.left + scrollLeft - clientLeft;

    return { top: Math.round(top), left: Math.round(left) };
}

6
Diese Antwort berücksichtigt nicht die Offsets der Eltern. Es ist nur relativ zum Ansichtsfenster
Nickey

3
@Nickey, das stimmt nicht - die Position des Ansichtsfensters sowie die Überprüfung des Bildlaufversatzes ergeben die Koordinaten relativ zum gesamten Dokument.
Natchiketa

1
Kann auf mobilen Geräten fehlerhaft sein stackoverflow.com/a/32623832/962634 Brauchen Sie Forschung
Basilikum

1
Warum subtrahieren Sie clientTop / clientLeft?
Teemoh

1
@Teemoh clientTop / clientLeft entspricht den Grenzwerten für das <html>Element.
Raphael Rafatpanah

98

Mit können Sie die element.getBoundingClientRect()Elementposition relativ zum Ansichtsfenster abrufen.

Verwenden Sie dann document.documentElement.scrollTop, um den Versatz des Ansichtsfensters zu berechnen.

Die Summe der beiden ergibt die Elementposition relativ zum Dokument:

element.getBoundingClientRect().top + document.documentElement.scrollTop

10
Relativ zum Ansichtsfenster ist nicht dasselbe wie relativ zum Dokument. Wenn die Seite etwas nach unten gescrollt wird, ist die Oberseite relativ zum Ansichtsfenster kleiner als die Oberseite relativ zum Dokument.
MrVimes

14
Er beginnt relativ zum Ansichtsfenster und fügt scrollY hinzu, um es relativ zum Dokument zu erhalten.
Joaquin Cuenca Abela

2
document.documentElement.scrollTopfunktioniert nicht in Safari, verwenden Sie window.scrollYstattdessen
Fabian von Ellerts

7

Ich schlage vor, zu verwenden

element.getBoundingClientRect()

wie hier vorgeschlagen anstelle der manuellen Offsetberechnung über offsetLeft , offsetTop und offsetParent . wie hier vorgeschlagen Unter bestimmten Umständen * führt die manuelle Durchquerung zu ungültigen Ergebnissen. Siehe diesen Plunker: http://plnkr.co/pC8Kgj

* Wenn sich das Element innerhalb eines scrollbaren übergeordneten Elements mit statischer (= Standard-) Positionierung befindet.


Sie können die Offset-Berechnung auch durchführen, indem Sie scrollLeft und scrollTop einbinden.
Ben J

Aber ich habe CSS3-Transformationen gefunden offsetLeftund offsetTopnicht berücksichtigt, was auch der getBoundingClientRect()Fall ist. In diesem Fall sind die Ergebnisse möglicherweise ungültig. Wenn Sie es brauchen, können Sie den Versatz eines Elements relativ zum übergeordneten Element (wie offsetLeft) mit abrufen (element.getBoundingClientRect().left - parent.getBoundingClientRect().left).
Ben J

sollte auf jeden Fall höher steigen; Diese Werte sind weitaus nützlicher und alles in einem Aufruf!
mix3d

7

document-offset( Skript von Drittanbietern ) ist interessant und scheint die Ansätze der anderen Antworten hier zu nutzen.

Beispiel:

var offset = require('document-offset')
var target = document.getElementById('target')
console.log(offset(target))
// => {top: 69, left: 108} 

5

Ich habe festgestellt, dass die folgende Methode am zuverlässigsten ist, wenn Kantenfälle behandelt werden, die offsetTop / offsetLeft auslösen.

function getPosition(element) {
    var clientRect = element.getBoundingClientRect();
    return {left: clientRect.left + document.body.scrollLeft,
            top: clientRect.top + document.body.scrollTop};
}

4

Für diejenigen, die die x- und y-Koordinaten verschiedener Positionen eines Elements relativ zum Dokument erhalten möchten.

const getCoords = (element, position) => {
  const { top, left, width, height } = element.getBoundingClientRect();
  let point;
  switch (position) {
    case "top left":
      point = {
        x: left + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "center left":
      point = {
        x: left + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "bottom left":
      point = {
        x: left + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
  }
  return point;
};

Verwendung

  • getCoords(document.querySelector('selector'), 'center')

  • getCoords(document.querySelector('selector'), 'bottom right')

  • getCoords(document.querySelector('selector'), 'top center')


2

Wenn es Ihnen nichts ausmacht, jQuery zu verwenden, können Sie die offset()Funktion verwenden. Weitere Informationen zu dieser Funktion finden Sie in der Dokumentation .


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.