我正在寻找绑定 snap
事件的方法。
当我将一个元素拖动到我的表面上并且可拖动元素被吸附到一个声明的吸附位置时,我想要触发一个事件。
类似于这样:
$(".drag").draggable({
snap: ".grid",
snaped: function( event, ui ) {}
});
附加分:需要引用 .grid
元素,该元素是 draggable 元素被 snapped 到的位置。
我正在寻找绑定 snap
事件的方法。
当我将一个元素拖动到我的表面上并且可拖动元素被吸附到一个声明的吸附位置时,我想要触发一个事件。
类似于这样:
$(".drag").draggable({
snap: ".grid",
snaped: function( event, ui ) {}
});
附加分:需要引用 .grid
元素,该元素是 draggable 元素被 snapped 到的位置。
draggable
小部件默认情况下不会暴露这样的事件。您可以修改它并维护您的自定义版本,或者更好的是从中派生一个新小部件,并在那里实现新事件。然而,还有第三种方法。snapElements
属性中存储了一组可能“可捕捉”的元素。反过来,此数组中的每个元素都公开了一个snapping
属性,如果可拖动的帮助器当前被卡住到该元素,则该属性为true,否则为false(helper可以同时吸附到多个元素)。
snapElements
数组会在每个drag
事件中更新,因此在drag
处理程序中始终是最新的。从那里,我们只需要从相关元素中使用data()获取draggable
小部件实例,并调用其_trigger()
方法来触发我们自己的snapped
事件(实际上是底层的dragsnapped
)。顺便说一句,我们可以使用$.extend()将ui
对象与包装被卡住的元素的jQuery对象扩展。$(".drag").draggable({
drag: function(event, ui) {
var draggable = $(this).data("draggable");
$.each(draggable.snapElements, function(index, element) {
if (element.snapping) {
draggable._trigger("snapped", event, $.extend({}, ui, {
snapElement: $(element.item)
}));
}
});
},
snap: ".grid",
snapped: function(event, ui) {
// Do something with 'ui.snapElement'...
}
});
上面的代码仍然可以改进。目前为止,只要可拖动助手仍然吸附在一个元素上,每次发生拖动事件(这种情况非常频繁),都会触发一次“snapped”事件。此外,当吸附结束时不会触发任何事件,这不是很实用,并且与事件成对出现(“snapped-in”,“snapped-out”)的约定相违背。$(".drag").draggable({
drag: function(event, ui) {
var draggable = $(this).data("draggable");
$.each(draggable.snapElements, function(index, element) {
ui = $.extend({}, ui, {
snapElement: $(element.item),
snapping: element.snapping
});
if (element.snapping) {
if (!element.snappingKnown) {
element.snappingKnown = true;
draggable._trigger("snapped", event, ui);
}
} else if (element.snappingKnown) {
element.snappingKnown = false;
draggable._trigger("snapped", event, ui);
}
});
},
snap: ".grid",
snapped: function(event, ui) {
// Do something with 'ui.snapElement' and 'ui.snapping'...
var snapper = ui.snapElement.attr("id"),snapperPos = ui.snapElement.position(),
snappee = ui.helper.attr("id"), snappeePos = ui.helper.position(),
snapping = ui.snapping;
// ...
}
});
你可以在这里测试这个解决方案。
总之,另一个改进可能是使snapped
事件可以被取消,就像drag
事件一样。为了实现这一点,如果_trigger()
的某个调用返回false
,我们必须从drag
处理程序中返回false
。不过,在一般情况下,取消捕捉或退出捕捉拖动操作并不像一个非常用户友好的功能,你可能需要三思而后行。
更新:从jQuery UI 1.9版本开始,data()
键变成小部件的完全限定名称,其中点号被破折号代替。因此,上面用于获取小部件实例的代码变为:
var draggable = $(this).data("ui-draggable");
改为:
var draggable = $(this).data("draggable");
在1.9版本中仍支持使用未经修饰的名称,但已弃用,并且在1.10版中将不再支持。
drag: function(event, ui) {
var draggable = $(this).data("ui-draggable")
$.each(draggable.snapElements, function(index, element) {
if(element.snapping) {
draggable._trigger("snapped", event, $.extend({}, ui, {
snapElement: $(element.item)
}));
}
});
}
ui.helper
中可用,而“snapped to”元素是ui.snapElement
,当ui.snapping
为true
时。 - Frédéric Hamidi