提高编码和调试技能的建议
您更新的代码(您在其中解决了缺少该overlaps
功能的问题)失败了,因为不应该以这种方式使用 jQuery 插件。在尝试解决此类问题之前,请考虑阅读有关创建 jQuery 插件的信息,并尽可能多地阅读有关 javascript 调试的信息。
debugger
设置断点后(或使用代码中的语句),尝试通过在控制台中执行以下所有操作来提高您的调试能力:
- 一步步播放相关代码
- 检查变量值
- 通过堆栈跟踪
- 将命令放入控制台以查看代码在该上下文中的行为方式
例如,为了解决这个问题,我在控制台中使用了一些 jQuery:
> $(".Assemble_station") // this returned elements with [visibility:hidden] so I tried:
> $(".Assemble_station:visible") // but I got the same results, so I ended up using:
> $(".taskNameItem").remove() // then I checked again:
> $(".Assemble_station") // and now the results are different :)
所有这些都是在控制台中完成的,无需更改代码。因此,当您的代码处于断点时,您可以通过在控制台中输入命令来真正学到很多东西。但是在 jsFiddle 中,请记住使用控制台底部的下拉菜单从 更改<top frame>
为框架。result
代码中的实际问题
改成 jQuery 插件的问题overlaps
是,jQuery 插件可以同时在多个项目上调用。因此很难将其作为插件进行调整以使其正常工作,最好使用原始版本。
但是使用原始函数的问题在于它适用于普通的 HTML 元素,但是您的元素并不是那么简单(因为您隐藏了部分,并且容器具有位置,而内容具有大小)。所以我不得不破解getPosition
里面的函数overlaps
,让它与你奇怪的 HTML 一起工作:
var overlaps = (function () {
function getPositions( elem ) {
var obj = $( elem );
var pos = obj.position();
//HACK: weird HTML force me to use its first child's dimensions
var child = obj.children(":first-child");
var width = child.width();
var height = child.height();
return [ [ pos.left, pos.left + width ], [ pos.top, pos.top + height ] ];
}
看看这个关于如何使用overlaps
函数的新代码(在第二个each
中,我不仅删除了 firstobj,还删除了之前循环中已经测试过的所有其他对象,使用i1 + 1
作为起点):
var stations = $('.Assemble_station');
stations.each(function(i1, firstobj) {
stations.slice(i1 + 1).each(function(i2, secondobj) {
if(overlaps(firstobj, secondobj)) {
var obj1 = $(firstobj);
var obj2 = $(secondobj);
var objToMove = obj1.position().left >= obj2.position().left ? obj1 : obj2;
var newTop = objToMove.position().top + 18;
objToMove.css("top", newTop + 'px');
}
});
});
您的另一个问题是您页面上的几个元素正在共享ID
。如果你给一个元素一个 id,它应该是整个页面中唯一具有该 id 的元素。如果您不遵守这个基本的 HTML 假设,jQuery 将无法按预期工作。我通过删除(而不是隐藏)标题和黄色条(并在通过 id 获取对象之前执行此操作)来解决此问题,因此它们不会干扰碰撞检测。
完整的解决方案
你可以在这里玩我的 jsFiddle:http: //jsfiddle.net/protron/NxWxU/8/