使用JavaScript获取两个DOM元素之间的相对位置

14

我用jQuery实现了一组可拖动的元素,可以将它们放入某些容器中。我需要一个动画效果,可以将一个元素移动到特定的容器,而不需要用户交互。问题在于,这些元素和容器在DOM的完全不同部分,并且大多数情况下使用浮动进行定位。

我需要的仅仅是一些代码,以获取两个浮动DOM元素之间的绝对位置差异,最好使用jQuery。我找到的唯一的东西是一些解析DOM的黑科技,但总是非常依赖于浏览器(例如,“这在Firefox或IE或其他浏览器中无法正常工作”)。

最好的解决方法是这样的:

var distance = getDistance(element1, element2);

或者用jQuery的表示方式:

var distance = $(element1).distanceTo($(element2));
3个回答

22

我从未使用过jQuery,只是查看了API文档,所以我可以假设您可以执行以下操作:

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

这不起作用,因为.offset()只返回相对于父元素的位置。由于父元素不同,所以这些值不能使用。顺便说一下,对角线距离部分并不重要,我期望得到左和上的值;-) - davil
好的,我不同意你的观点。根据jQuery参考文档(http://docs.jquery.com/CSS),offset获取的是“第一个匹配元素相对于视口的当前偏移量”。视口是关键词,而不是offsetParent。 - Sergey Ilinsky
偏移量页面上的示例非常误导人。这些示例是在iframes中加载的,这使得它看起来位置仅相对于父级,而实际上它是相对于文档(在本例中是iframe)。 - nickf
我可以确认这个答案是正确的:在这里可以看到我的工作示例:http://jsbin.com/ojede - nickf
嗯...看来信任文档并不总是那么好。下次我会在花费数小时寻找不必要的解决方案之前先尝试一下。它完美地运行了,非常感谢! - davil
1
$(elem1).偏移量({ 相对于 : elem2 })。 - Sugendran

1

以下这个怎么样?

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

那个 isIE 测试是不必要的。为什么不直接使用 obj = obj.offsetParent || obj.parentElement(或者其他所需的内容)呢? - alex

1

使用纯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));

和Sergey的答案一样... offsetLeft和offsetTop只在同一个父元素内起作用。 - davil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接