2013-07-31 9 views
9

Mam następującą strukturę DOMRóżnica między offsetParent i parentElement lub parentNode

<body> 
    <div> 
     <table> 
      <outerElement> 
       <innerElement /> 
      </outerElement> 
     <table> 
    </div> 
</body> 

DIV jest jego przepełnienie ustawiony na auto, więc jeśli tabela rośnie większy - przewija w DIV.

W tym scenariuszu dlaczego table.offsetParent zwraca treść, podczas gdy zarówno table.parentNode, jak i zwraca Div?

muszę obliczyć aktualną pozycję innerElement w oknie, więc przechodzić z niego się thru wszystkich elementów nadrzędnych, zbierając ich wartości offsetTop i offsetLeft. Aż do DIV offsetParent działa dobrze, a następnie przeskakuje bezpośrednio do ciała. Problem polegający na przewijaniu w pewnym momencie, muszę również uwzględnić scrollTop i scrollLeft - podobnie jak w DIV w powyższym przykładzie. Problem polega na tym, że jeśli użyję offsetParent, nigdy nie napotkam DIV jako jednego z rodziców.

UPDATE

Jest to część kodu, która wykonuje ruchu postępowego:

while (oElem && getStyle(oElem, 'position') != 'absolute' && getStyle(oElem, 'position') != 'relative') { 
    curleft += oElem.offsetLeft; 
    curtop += oElem.offsetTop; 
    oElem = oElem.offsetParent; 
} 

gdzie getStyle jest funkcją zwyczaj, że w tym przypadku pobiera styl pozycji.

+0

Sprawdź, czy ciało ma pozycję: względna – Krishna

+0

@dumass nie, nie ma. A poza tym "offsetParent" działa na wielu elementach statycznych w dół hiearchii. Zaktualizuję kod, którego używam. –

Odpowiedz

0

Trzymaj się z dala od offsetParent, będziesz musiał dodać wiele hacków i czeków, aby upewnić się, że masz rację.

Spróbuj użyć zamiast tego getBoundingClientRect.

+7

Brak odpowiedzi na to pytanie ... –

+1

offsetParent może być bardzo użyteczny i właściwie używany, nie będziesz potrzebować "wielu hacków" – Mackelito

+0

@Mackelito Z tego, co pamiętam, ma problemy z zawijaniem marginesów, łatwiej jest z nim pracować. getBoundingClientRect'. – Ally

22

offsetParent to najbliższy rodzic, który ma position:relative lub position:absolute lub treść strony. parentNode jest bezpośrednim rodzicem, niezależnie od position.

+0

Niezupełnie zaktualizowałem pytanie, podając więcej szczegółów. Technicznie próbuję uzyskać pozycję "innerElement", aby być dokładnym, a wielu jej rodziców jest statycznych. –

3

Używanie getBoudingClientRect() jest naprawdę świetną pomocą (dzięki Ally za podpowiedź!).

Jeśli trzeba jeszcze Stanowisko względem lewego górnego rogu dokumentu, oto pomocny fragment:

if (node.getBoundingClientRect) { 
    var rect = node.getBoundingClientRect(); 
    var sx = -(window.scrollX ? window.scrollX : window.pageXOffset); 
    var sy = -(window.scrollY ? window.scrollY : window.pageYOffset); 

    return { 
     x: rect.left - sx, 
     y: rect.top - sy 
    } 
} 

Uwaga: document.body.getBoundingClientRect() może powrócić nieoczekiwaną wartość top w Firefoksie w pewnych okolicznościach. Dlatego położenie przewijania okna jest bardziej niezawodne.

Dla klienta, który jeszcze nie obsługuje getBoundingClientRect(), nadal musimy chodzić offetParents i dbać, aby każdy rodzic overflow: scroll (lub auto) miał position: relative.