views:

3787

answers:

3

I've implemented a set of draggable elements that can be dropped into some containers using jQuery. What I need is an animation that moves an element to a specific container without user interaction. The problem is that the elements and the drop containers are in completely different parts of the DOM and mostly positioned using float.

All I need is some code to get the absolute position difference between 2 floating DOM elements, preferrably using jQuery. The only thing I found were some hacks parsing upwards the DOM but always very browser-specific (e.g. "this does not work well with Firefox or IE or whatever").

Best would be something like this:

var distance = getDistance(element1, element2);

or in jQuery notation:

var distance = $(element1).distanceTo($(element2));
+5  A: 

I never used jQuery, just looked up API, so I can assume you can do the following:

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);
Sergey Ilinsky
This won't work because .offset() only returns the relative position to the parent element. Since the parent elements are not the same the values can't be used.The diagonal distance part isn't important btw, I was expecting left and top values ;-)
davil
Well, I won't agree with you. According to the jQuery reference (http://docs.jquery.com/CSS), offset gets "the current offset of the first matched element relative to the viewport." viewport is the key word, it is not the offsetParent
Sergey Ilinsky
The example on the offset page is quite misleading. The examples are loaded in iframes which makes it look like the position is only relative to the parent, whereas it's actually relative to the document (in this case, the iframe)
nickf
I can verify this answer as correct: see my working example of it here: http://jsbin.com/ojede
nickf
Well... seems like trusting the documentation isn't always that good. Next time I'll just try it before spending hours with searching for a solution that isn't necessary. It works just fine, thanks a lot!
davil
$(elem1).offset({ relativeTo : elem2 })
Sugendran
A: 

Using pure 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));
Claudio
Same here as with Sergey's answer... offsetLeft and offsetTop only work inside the same parent element.
davil
A: 

What about the following?

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);
Claudio