每当您开始拖动 adraggable
以确定哪些droppable
s 有资格接收draggable
.
var m = $.ui.ddmanager.droppables[t.options.scope] || [];
var type = event ? event.type : null; // workaround for #2317
var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
droppablesLoop: for (var i = 0; i < m.length; i++) {
if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
m[i].offset = m[i].element.offset();
m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
}
正如您所看到的,代码并非微不足道,并且可以解释为什么每次开始拖动时都会看到性能缓慢。
需要注意的一点是,检查的第一件事droppablesLoop
是是否droppable
禁用。
因此,为了提高性能,您总是可以手动禁用适当的droppable
小部件,这将使您快速跳出上面的代码块。您可以使用 上的start
事件来执行此操作,该事件draggable
将首先触发。
$('.draggable').draggable({
start: function() {
$('.invalid-droppable-elements').droppable('option', 'disabled', true);
},
stop: function() {
$('.invalid-droppable-elements').droppable('option', 'disabled', false);
}
});
这基本上使您自己实现accept
/scope
逻辑,性能影响取决于您的算法。不过实施起来应该没那么糟糕。插件之所以这么慢,是因为它们必须处理很多不同的情况。
jQuery UI 不支持向单个draggable
/droppable
元素添加多个范围,但您可以自己滚动该功能。
我在这里举了一个例子来展示这个 - http://jsfiddle.net/tj_vantoll/TgQTP/1/。