我正在寻找一种绑定snap
事件的方法。
当我在我的表面上拖动一个元素并且可拖动元素被捕捉到声明的捕捉位置时,我想触发一个事件。
像这样的东西:
$(".drag").draggable({
snap: ".grid",
snaped: function( event, ui ) {}
});
加分项:引用.grid
了可拖动元素被捕捉的元素。
我正在寻找一种绑定snap
事件的方法。
当我在我的表面上拖动一个元素并且可拖动元素被捕捉到声明的捕捉位置时,我想触发一个事件。
像这样的东西:
$(".drag").draggable({
snap: ".grid",
snaped: function( event, ui ) {}
});
加分项:引用.grid
了可拖动元素被捕捉的元素。
小draggable
部件(目前)还没有公开这样的事件。您可以修改它并维护您的自定义版本,或者更好的是,从中派生一个新小部件并在那里实现新事件。然而,还有第三种方式。
从这个问题snapElements
中,我们知道小部件在其属性中存储了一个潜在“可对齐”元素的数组。反过来,该数组中的每个元素都会公开一个snapping
属性,true
即可拖动助手当前是否对齐到该元素,false
否则(助手可以同时对齐多个元素)。
该snapElements
数组会针对每个事件进行更新,因此它在处理程序drag
中始终是最新的。drag
从那里,我们只需要使用data()draggable
从关联元素中获取小部件实例,并调用它的方法来引发我们自己的事件(实际上是在幕后)。顺便说一句,我们可以$.extend()使用jQuery 对象包装捕捉到的元素:_trigger()
snapped
dragsnapped
ui
$(".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
为每个drag
事件(发生很多)触发一个事件。此外,捕捉结束时不会触发任何事件,这不是很实用,并且有损于此类事件成对发生(snapped-in
,snapped-out
)的约定。
幸运的是,snapElements
数组是持久的,所以我们可以用它来存储状态。我们可以snappingKnown
为每个数组元素添加一个属性,以跟踪我们已经snapped
为该元素触发了一个事件。此外,我们可以使用它来检测自上次调用以来元素已被抢购并做出相应的反应。
请注意,下面的代码没有引入另一个事件,而是snapped-out
选择在对象中传递一个附加snapping
属性(反映元素的当前状态)ui
(当然,这只是一个偏好问题):
$(".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
事件一样。为了实现这一点,如果对返回的调用之一,我们将不得不false
从我们的处理程序返回。不过,在实现此功能之前,您可能需要三思而后行,因为在一般情况下,取消对 snap-in 或 snap-out 的拖动操作看起来并不是一个非常用户友好的功能。drag
_trigger()
false
更新:从 jQuery UI 1.9 开始,键data()
成为小部件的完全限定名称,点被替换为破折号。因此,上面用于获取小部件实例的代码变为:
var draggable = $(this).data("ui-draggable");
代替:
var draggable = $(this).data("draggable");
1.9 中仍支持使用非限定名称,但已弃用,并且将在 1.10 中删除支持。
在 jquery-ui 1.10.0 中,上面的代码不起作用。拖动功能是:
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)
}));
}
});
}