2012-07-24 15 views

Odpowiedz

133

element.offsetLeft i element.offsetTop są czystymi właściwościami javascript dla znalezienia pozycji elementu w odniesieniu do jego offsetParent; jest najbliższy elementem dominującym z pozycji relative lub absolute

Alternatywnie, można zawsze użyć Zepto aby uzyskać pozycję elementu i jego rodzica, a po prostu odjąć dwa:

var childPos = obj.offset(); 
var parentPos = obj.parent().offset(); 
var childOffset = { 
    top: childPos.top - parentPos.top, 
    left: childPos.left - parentPos.left 
} 

ma to, że korzyści z przesunięcia dziecka względem jego rodzica, nawet jeśli rodzic nie jest ustawiony.

+4

elementem jest umieszczony 'static' nie są kompensowane rodziców. – Esailija

+0

prawo; mój błąd – jackwanders

+4

nie używaj średników wewnątrz nawiasów klamrowych, użyj przecinka –

34

w czystym js wystarczy użyć właściwości offsetLeft i offsetTop.
Przykład skrzypce: http://jsfiddle.net/WKZ8P/

var elm = document.querySelector('span'); 
 
console.log(elm.offsetLeft, elm.offsetTop);
p { position:relative; left:10px; top:85px; border:1px solid blue; } 
 
span{ position:relative; left:30px; top:35px; border:1px solid red; }
<p> 
 
    <span>paragraph</span> 
 
</p>

+0

Dziękuję. Czy istnieje również sposób na uzyskanie przesunięcia do elementu parent.parent? – matt

+2

'p.offsetTop + p.parentNode.offsetTop' Można go było owinąć w funkcję rekursywną, wiele lat temu [jak zaproponował PPK] (http://www.quirksmode.org/js/findpos.html) kilka lat temu. Możesz zmienić funkcję, aby przekazać liczbę poziomów do przejścia lub użyć selektora do naśladowania '$ (selector) .parents (parentSelector)'. Wolałbym to rozwiązanie, ponieważ implementacja zepto działa tylko w przeglądarkach obsługujących 'getBoundingClientsRect' - których niektóre telefony komórkowe nie obsługują. –

+0

Myślałem, że 'getBoundingClientsRect' jest szeroko wspierany ... jeśli ktoś wie, które telefony komórkowe go nie obsługują, byłbym zainteresowany (nie mogę znaleźć tabeli wsparcia dla telefonów komórkowych). – Nobita

3

zrobiłem to w ten sposób w programie Internet Explorer.

function getWindowRelativeOffset(parentWindow, elem) { 
    var offset = { 
     left : 0, 
     top : 0 
    }; 
    // relative to the target field's document 
    offset.left = elem.getBoundingClientRect().left; 
    offset.top = elem.getBoundingClientRect().top; 
    // now we will calculate according to the current document, this current 
    // document might be same as the document of target field or it may be 
    // parent of the document of the target field 
    var childWindow = elem.document.frames.window; 
    while (childWindow != parentWindow) { 
     offset.left = offset.left + childWindow.frameElement.getBoundingClientRect().left; 
     offset.top = offset.top + childWindow.frameElement.getBoundingClientRect().top; 
     childWindow = childWindow.parent; 
    } 

    return offset; 
}; 

=================== można nazwać jak ten

getWindowRelativeOffset(top, inputElement); 

skupię się tylko na IE jak na moje uwagi, ale podobne rzeczy można zrobić dla innych przeglądarek.

0

Dodaj przesunięcie zdarzenia do przesunięcia elementu macierzystego, aby uzyskać absolutną pozycję przesunięcia zdarzenia.

Przykład:

HTMLElement.addEventListener('mousedown',function(e){ 

    var offsetX = e.offsetX; 
    var offsetY = e.offsetY; 

    if(e.target != this){ // 'this' is our HTMLElement 

     offsetX = e.target.offsetLeft + e.offsetX; 
     offsetY = e.target.offsetTop + e.offsetY; 

    } 
} 

Kiedy cel zdarzenie nie jest elementem którym zdarzenie zostało zarejestrowane na, dodaje przesunięcie rodzica do bieżącego przypadku przesunięcia w celu obliczenia „absolutna” offset wartość.

Według Mozilla Web API: „The HTMLElement.offsetLeft tylko do odczytu Właściwość zwraca liczbę pikseli, że lewy górny róg bieżącym elementem jest przesunięcie w lewo w obrębie węzła HTMLElement.offsetParent”.

Dzieje się tak najczęściej, gdy zarejestrowałeś zdarzenie na rodzicu, który zawiera więcej dzieci, na przykład: przycisk z wewnętrzną ikoną lub rozpiętością tekstową, element li z wewnętrznymi przęsłami. itp...

0

Jasne jest łatwe z czystych JS, po prostu zrób to, praca na stałe i animowanego HTML 5 paneli też zrobiłem i spróbuj tego kodu i działa za każdym Brower (m.in. IE 8):

<script type="text/javascript"> 
    function fGetCSSProperty(s, e) { 
     try { return s.currentStyle ? s.currentStyle[e] : window.getComputedStyle(s)[e]; } 
     catch (x) { return null; } 
    } 
    function fGetOffSetParent(s) { 
     var a = s.offsetParent || document.body; 

     while (a && a.tagName && a != document.body && fGetCSSProperty(a, 'position') == 'static') 
      a = a.offsetParent; 
     return a; 
    } 
    function GetPosition(s) { 
     var b = fGetOffSetParent(s); 

     return { Left: (b.offsetLeft + s.offsetLeft), Top: (b.offsetTop + s.offsetTop) }; 
    }  
</script> 
1

Przykład

Gdybyśmy mieli element podrzędny o identyfikatorze "element potomny" i chcieliśmy uzyskać jego lewą/najwyższą pozycję względem elementu nadrzędnego, powiedzmy, że div ma klasę "item" -parent ", użyjemy tego kodu.

var position = $("#child-element").offsetRelative("div.item-parent"); 
alert('left: '+position.left+', top: '+position.top); 

Plugin Wreszcie, dla faktycznego wtyczki (z kilka uwag expalaining co się dzieje):

// offsetRelative (or, if you prefer, positionRelative) 
(function($){ 
    $.fn.offsetRelative = function(top){ 
     var $this = $(this); 
     var $parent = $this.offsetParent(); 
     var offset = $this.position(); 
     if(!top) return offset; // Didn't pass a 'top' element 
     else if($parent.get(0).tagName == "BODY") return offset; // Reached top of document 
     else if($(top,$parent).length) return offset; // Parent element contains the 'top' element we want the offset to be relative to 
     else if($parent[0] == $(top)[0]) return offset; // Reached the 'top' element we want the offset to be relative to 
     else { // Get parent's relative offset 
      var parent_offset = $parent.offsetRelative(top); 
      offset.top += parent_offset.top; 
      offset.left += parent_offset.left; 
      return offset; 
     } 
    }; 
    $.fn.positionRelative = function(top){ 
     return $(this).offsetRelative(top); 
    }; 
}(jQuery)); 

Uwaga: można użyć ten na kliknięcie myszką lub najechaniu myszą Wydarzenie

$(this).offsetRelative("div.item-parent"); 
0

Mam inne rozwiązanie. Odejmij rodzic wartość nieruchomości od wartości nieruchomości dziecko

$('child-div').offset().top - $('parent-div').offset().top; 
Powiązane problemy