jQuery UI –可拖动的“快照"事件 [英] jQuery UI – draggable 'snap' event
问题描述
我正在寻找一种绑定snap
事件的方法.
当我将一个元素拖动到我的表面上并且 draggable 元素被 snapped 到一个声明的捕捉位置时,我想触发一个事件.
类似这样的东西:
$(".drag").draggable({
snap: ".grid",
snaped: function( event, ui ) {}
});
加分点:引用.grid
元素,其中可拖动元素被捕捉.
draggable
小部件没有立即显示此类事件.您可以修改它并维护您的自定义版本,或者更好的是,从中派生一个新的小部件并在那里实现新的事件.但是,还有第三种方式.
从此问题,我们知道该小部件在其snapElements
中存储了一系列潜在的可扣紧"元素财产.反过来,如果当前可拖动的辅助对象已被捕捉到该元素,则此数组中的每个元素都显示一个true
属性,该属性为true
,否则显示为false
(该辅助对象可以同时捕捉到多个元素).>
对于每个drag
事件,都会更新snapElements
数组,因此在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'...
}
});
但是,上面的代码仍然可以改进.就目前情况而言,只要可拖动的辅助对象仍然捕捉到某个元素,就会为每个drag
事件(发生很多 )触发一个snapped
事件.此外,捕捉结束时不会触发任何事件,这不太实际,并且有损于此类事件成对发生的惯例(snapped-in
,snapped-out
).
幸运的是,snapElements
数组是持久性的,因此我们可以使用它来存储状态.我们可以为每个数组元素添加一个snappingKnown
属性,以跟踪是否已经触发了该元素的snapped
事件.此外,我们可以使用它来检测自上次调用以来某个元素已被抢购并做出相应的反应.
请注意,下面的代码没有引入另一个snapped-out
事件,而是选择在ui
对象中传递一个附加的snapping
属性(反映该元素的当前状态)(当然,这仅仅是一个问题).偏好):
$(".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;
// ...
}
});
您可以在此处进行测试.
最后,与drag
事件一样,另一个改进可能是使snapped
事件可取消.为此,如果对_trigger()
的调用之一返回了false
,则必须从drag
处理程序中返回false
.不过,您可能需要三思而后行,因为在通常情况下,取消对管理单元或管理单元的拖动操作看起来并不像一个非常用户友好的功能.
更新: :从jQuery UI 1.9起, 代替: 在1.9中仍支持使用非限定名称,但已弃用,而在1.10中将不再支持. I'm looking a way to binding the When I'm dragging an element over my surface and the draggable element is snapped to a declared snap position I want to trigger an event. Something like this: Bonus point: with a reference to the The From this question, we know the widget stores an array of the potentially "snappable" elements in its The The code above, however, can still be improved. As it stands, a Luckily, the Note that rather than introducing another You can test this solution here. In closing, another improvement might be to make the Update: From jQuery UI 1.9 onwards, the Instead of: Using the unqualified name is still supported in 1.9 but is deprecated, and support will be dropped in 1.10. 这篇关于jQuery UI –可拖动的“快照"事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!var draggable = $(this).data("draggable");
snap
event. $(".drag").draggable({
snap: ".grid",
snaped: function( event, ui ) {}
});
.grid
element where the draggable element was snapped.draggable
widget does not expose such an event out of the box (yet). You could modify it and maintain your custom version or, better, derive a new widget from it and implement the new event there. There is, however, a third way.snapElements
property. In turn, each element in this array exposes a snapping
property that is true
if the draggable helper is currently snapped to this element and false
otherwise (the helper can snap to several elements at the same time).snapElements
array is updated for every drag
event, so it is always up-to-date in drag
handlers. From there, we only have to obtain the draggable
widget instance from the associated element with data(), and call its _trigger()
method to raise our own snapped
event (actually dragsnapped
under the hood). In passing, we can $.extend() the ui
object with a jQuery object wrapping the snapped element:$(".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
event will be triggered for every drag
event (which occurs a lot) as long as the draggable helper remains snapped to an element. In addition, no event is triggered when snapping ends, which is not very practical, and detracts from the convention for such events to occur in pairs (snapped-in
, snapped-out
).snapElements
array is persistent, so we can use it to store state. We can add a snappingKnown
property to each array element in order to track that we already have triggered a snapped
event for that element. Moreover, we can use it to detect that an element has been snapped out since the last call and react accordingly.snapped-out
event, the code below chooses to pass an additional snapping
property (reflecting the element's current state) in the ui
object (which is, of course, only a matter of preference):$(".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
event cancelable, as the drag
event is. To achieve that, we would have to return false
from our drag
handler if one of the calls to _trigger()
returns false
. You may want to think twice before implementing this, though, as canceling a drag operation on snap-in or snap-out does not look like a very user-friendly feature in the general case.data()
key becomes the widget's fully qualified name, with dots replaced by dashes. Accordingly, the code used above to obtain the widget instance becomes:var draggable = $(this).data("ui-draggable");
var draggable = $(this).data("draggable");