Ermitteln Sie die Position eines div / span-Tags

103

Kann mir jemand zeigen, wie man die top& leftPosition eines divoder spanElements erhält, wenn eines nicht angegeben ist?

dh:

<span id='11a' style='top:55px;' onmouseover="GetPos(this);">stuff</span>
<span id='12a' onmouseover="GetPos(this);">stuff</span>

Wenn ich das tue:

document.getElementById('11a').style.top

Der Wert von 55pxwird zurückgegeben. Wenn ich das jedoch für span'12a' versuche , wird nichts zurückgegeben.

Ich habe eine Reihe von div/ spans auf einer Seite, für die ich die top/ left-Eigenschaften nicht angeben kann , aber ich muss eine divdirekt unter diesem Element anzeigen .

schmoopy
quelle

Antworten:

100

Diese Funktion zeigt Ihnen die x, y-Position des Elements relativ zur Seite an. Grundsätzlich müssen Sie alle Eltern des Elements durchlaufen und ihre Offsets addieren.

function getPos(el) {
    // yay readability
    for (var lx=0, ly=0;
         el != null;
         lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent);
    return {x: lx,y: ly};
}

Wenn Sie jedoch nur die x-, y-Position des Elements relativ zu seinem Container haben möchten, benötigen Sie lediglich:

var x = el.offsetLeft, y = el.offsetTop;

Um ein Element direkt unter diesem zu platzieren, müssen Sie auch seine Höhe kennen. Dies wird in der Eigenschaft offsetHeight / offsetWidth gespeichert.

var yPositionOfNewElement = el.offsetTop + el.offsetHeight + someMargin;
nickf
quelle
5
Leider schlägt diese Methode in Chrome fehl, wenn sich das Element in einer Tabelle mit Rahmen befindet. Es wird auch im IE6-Standardmodus aufgrund von BODY-Rändern fehlschlagen.
GetFree
1
Nur eine Warnung für Benutzer dieses Codes. Dies ist relativ zur Seite und nicht zum Fenster. Es gibt den gleichen Wert zurück, wenn der Benutzer mithilfe der Bildlaufleisten einen Bildlauf durchführt. Achtung.
Isaac Bolinger
danke @IsaacBolinger hat es gerade bemerkt. Kann mir jemand sagen, wie ich die Werte ändern kann, wenn die Fenstergröße geändert wird oder der Benutzer einen Bildlauf durchführt?
David Fariña
@ DavidFariña Dafür habe ich das Geometriemodul "Dom-Geometrie" von Dojo verwendet. Ich weiß nicht, wie ich es nativ machen soll.
Isaac Bolinger
Downvoted - Für erfahrene Benutzer mag dies offensichtlich sein, aber Sie haben nicht angegeben, was genau für el übergeben werden muss (dh geben Sie ein Beispiel für die Verwendung an).
Matt
183

Sie können die Methode getBoundingClientRect()für einen Verweis auf das Element aufrufen . Dann können Sie die untersuchen top, left, rightund / oder bottomEigenschaften ...

var offsets = document.getElementById('11a').getBoundingClientRect();
var top = offsets.top;
var left = offsets.left;

Wenn Sie jQuery verwenden, können Sie den prägnanteren Code verwenden ...

var offsets = $('#11a').offset();
var top = offsets.top;
var left = offsets.left;
Alex
quelle
11
+1 für diese Antwort getBoundingClientRect()sollte verwendet werden - und dies sollte die akzeptierte Antwort sein! Sie benötigen jedoch keinen "modernen Browser", damit dies funktioniert . Weitere Informationen finden Sie in der Kompatibilitätsliste, die ich hier gezeigt habe: stackoverflow.com/questions/1480133/… . Es funktioniert gut in IE 4.0+ (!), Chrome 1.0+, FF 3.0+, Safari 4.0+ und Opera.
Sk8erPeter
25
Beachten Sie, dass getBoundingClientRect()Werte relativ zum Ansichtsfenster und nicht zum Dokument zurückgegeben werden. Dafür möchten Sie so etwas wie top = el.getBoundingClientRect().top + window.pageYOffset - el.ownerDocument.documentElement.clientTop.
Zack Bloom
1
Beachten Sie auch , dass getBoundingClientRectnimmt transformberücksichtigt.
ExpExc
Dies ist nicht korrekt, wenn das erste nicht absolut positionierte Kind einen Rand oben oder einen Rand links hat. Derzeit gibt es auf dieser Seite keine genaue Lösung. Wenn jemand dies weiß, geben Sie bitte eine Antwort.
Curtis
16

Während @ nickfs Antwort funktioniert. Wenn Sie ältere Browser nicht mögen, können Sie diese reine Javascript-Version verwenden. Funktioniert in IE9 + und anderen

var rect = el.getBoundingClientRect();

var position = {
  top: rect.top + window.pageYOffset,
  left: rect.left + window.pageXOffset
};
Benjamin Intal
quelle
12

Wie Alex bemerkte, können Sie jQuery offset () verwenden, um die Position relativ zum Dokumentfluss zu ermitteln. Verwenden Sie position () für die x, y-Koordinaten relativ zum übergeordneten Element.

EDIT: Switched document.readyfür window.loadda loadwartet auf alle Elemente , so dass Sie ihre Größe , anstatt einfach die Vorbereitung der DOM erhalten. Nach meiner Erfahrung loadführt dies zu weniger falsch in Javascript positionierten Elementen.

$(window).load(function(){ 
  // Log the position with jQuery
  var position = $('#myDivInQuestion').position();
  console.log('X: ' + position.left + ", Y: " + position.top );
});
Dylan Valade
quelle
9

Für alle, die nur die obere oder linke Position benötigen, reichen geringfügige Änderungen am lesbaren Code von @ Nickf aus.

function getTopPos(el) {
    for (var topPos = 0;
        el != null;
        topPos += el.offsetTop, el = el.offsetParent);
    return topPos;
}

und

function getLeftPos(el) {
    for (var leftPos = 0;
        el != null;
        leftPos += el.offsetLeft, el = el.offsetParent);
    return leftPos;
}
Jens Frandsen
quelle
2

Mir ist klar, dass dies ein alter Thread ist, aber die Antwort von @alex muss als die richtige Antwort markiert werden

element.getBoundingClientRect() ist eine genaue Übereinstimmung mit jQuery's $(element).offset()

Und es ist kompatibel mit IE4 + ... https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect

lauwarm
quelle
Sie müssen den Seiten-Scroll-Offset einschließen
Benjamin Intal