2008-10-22 21 views
14

Zaimplementowałem zestaw elementów, które można przeciągnąć do niektórych kontenerów za pomocą jQuery. Potrzebuję animacji, która przenosi element do określonego kontenera bez interakcji użytkownika. Problem polega na tym, że elementy i pojemniki z kroplami są w całości różnych częściach DOM i są najczęściej pozycjonowane za pomocą pływaka.Uzyskaj względną pozycję między 2 elementami DOM za pomocą JavaScriptu

Potrzebuję tylko trochę kodu, aby uzyskać bezwzględną różnicę pozycji między dwoma pływającymi elementami DOM, najlepiej przy użyciu jQuery. Odkryłem tylko, że niektóre hacki parsują w górę DOM, ale zawsze są bardzo specyficzne dla przeglądarki (np. "To nie działa dobrze z Firefoksem lub IE lub czymkolwiek").

Najlepiej byłoby coś takiego:

var distance = getDistance(element1, element2); 

lub w notacji jQuery:

var distance = $(element1).distanceTo($(element2)); 

Odpowiedz

22

nigdy nie użyłem jQuery, tylko spojrzał API, więc można założyć, można wykonać następujące czynności:

 
var o1 = $(element1).offset(); 
var o2 = $(element2).offset(); 
var dx = o1.left - o2.left; 
var dy = o1.top - o2.top; 
var distance = Math.sqrt(dx * dx + dy * dy); 
+0

To nie zadziała, ponieważ .offset() zwraca tylko względną pozycję do elementu nadrzędnego. Ponieważ elementy macierzyste nie są takie same, wartości nie mogą być używane. Przekątna część odległości nie jest ważna btw, oczekiwałem lewej i najwyższych wartości ;-) – davil

+0

Cóż, nie zgadzam się z tobą. Zgodnie z odniesieniem do jQuery (http://docs.jquery.com/CSS) offset otrzymuje "bieżące przesunięcie pierwszego dopasowanego elementu względem rzutni". rzutnia jest słowem kluczowym, nie jest offsetParent –

+0

Przykład na stronie z przesunięciem jest dość mylący. Przykłady są ładowane w elementach iframe, co sprawia, że ​​wygląda tak, jakby pozycja była tylko względna względem elementu nadrzędnego, podczas gdy w rzeczywistości jest względna w stosunku do dokumentu (w tym przypadku elementu iframe). – nickf

1

Używanie czystego javascript.

var dx = obj1.offsetLeft - obj2.offsetLeft; 
var dy = obj1.offsetTop - obj2.offsetTop; 
var distance = Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2)); 
+0

Tak samo jak w przypadku odpowiedzi Sergeya ... offsetLeft i offsetTop działają tylko w tym samym elemencie nadrzędnym. – davil

1

Co z poniższymi?

var isIE = navigator.appName.indexOf("Microsoft") != -1; 

function getDistance(obj1, obj2){ 
    var obj1 = document.getElementById(obj1); 
    var obj2 = document.getElementById(obj2); 
    var pos1 = getRelativePos(obj1); 
    var pos2 = getRelativePos(obj2); 
    var dx = pos1.offsetLeft - pos2.offsetLeft; 
    var dy = pos1.offsetTop - pos2.offsetTop; 
    return {x:dx, y:dy}; 
} 
function getRelativePos(obj){ 
var pos = {offsetLeft:0,offsetTop:0}; 
while(obj!=null){ 
    pos.offsetLeft += obj.offsetLeft; 
    pos.offsetTop += obj.offsetTop; 
    obj = isIE ? obj.parentElement : obj.offsetParent; 
} 
return pos; 
} 
// 
var obj = getDistance("element1","element2") 
alert(obj.x+" | "+obj.y); 
+0

Ten test 'isIE' nie jest potrzebny. Dlaczego nie po prostu "obj = obj.offsetParent || obj.parentElement' (lub cokolwiek jest wymagane). – alex

Powiązane problemy