2008-10-22 6 views
14

Ich habe eine Reihe von ziehbaren Elementen implementiert, die in einige Container mit jQuery abgelegt werden können. Was ich brauche, ist eine Animation, die ein Element ohne Benutzerinteraktion in einen bestimmten Container verschiebt. Das Problem ist, dass die Elemente und die Drop-Container vollständig in verschiedenen Teilen des DOM und meist mit Float positioniert sind.Erhalten relative Position zwischen 2 DOM-Elementen mit JavaScript

Alles, was ich brauche, ist ein Code, um den absoluten Positionsunterschied zwischen 2 Floating-DOM-Elementen zu erhalten, vorzugsweise mit jQuery. Das einzige, was ich fand, waren einige Hacks, die das DOM nach oben analysierten, aber immer sehr Browser-spezifisch (z. B. "das funktioniert nicht gut mit Firefox oder IE oder was auch immer").

Am besten wäre so etwas wie dieses:

var distance = getDistance(element1, element2); 

oder in jQuery Notation:

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

Antwort

22

ich nie jQuery verwendet, nur API nachgeschlagen, so kann ich annehmen, dass Sie folgendes tun:

 
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

Dies funktioniert nicht, da .offset() nur die relative Position zum übergeordneten Element zurückgibt. Da die übergeordneten Elemente nicht identisch sind, können die Werte nicht verwendet werden. Der Diagonalabstand ist nicht wichtig, da ich linke und obere Werte erwartet habe ;-) – davil

+0

Nun, ich stimme dir nicht zu. Laut der jQuery-Referenz (http://docs.jquery.com/CSS) erhält der Offset "den aktuellen Offset des ersten übereinstimmenden Elements relativ zum Viewport". Ansichtsfenster ist das Schlüsselwort, es ist nicht das offsetParent –

+0

Das Beispiel auf der Offset-Seite ist ziemlich irreführend. Die Beispiele werden in iframes geladen, was es so aussehen lässt, als ob die Position nur relativ zum Eltern ist, während sie tatsächlich relativ zum Dokument ist (in diesem Fall der Iframe) – nickf

1

Mit reinem 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

Das gleiche wie bei Sergey's Antwort ... OffsetLeft und OffsetTop funktionieren nur im selben Elternelement. – davil

1

Was ist mit den folgenden?

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

Dieser 'isIE'-Test wird nicht benötigt. Warum nicht einfach 'obj = obj.offsetParent || obj.parentElement' (oder was auch immer benötigt wird). – alex