Jquery ui jQuery UI–可拖动的“快照”事件

Jquery ui jQuery UI–可拖动的“快照”事件,jquery-ui,jquery-ui-draggable,Jquery Ui,Jquery Ui Draggable,我正在寻找绑定快照事件的方法 当我在曲面上拖动一个元素,可拖动的元素被捕捉到一个声明的捕捉位置时,我想触发一个事件 大概是这样的: $(".drag").draggable({ snap: ".grid", snaped: function( event, ui ) {} }); 额外的一点:引用了.grid元素,在该元素中抓拍了可拖动元素。可拖动小部件还没有公开这样的事件。您可以修改它并维护您的自定义版本,或者更好的是,从它派生一个新的小部件并在那里实现新事件。然而,还有第三种方法

我正在寻找绑定快照事件的方法

当我在曲面上拖动一个元素,可拖动的元素被捕捉到一个声明的捕捉位置时,我想触发一个事件

大概是这样的:

$(".drag").draggable({
  snap: ".grid",
  snaped: function( event, ui ) {}
});
额外的一点:引用了.grid元素,在该元素中抓拍了可拖动元素。

可拖动小部件还没有公开这样的事件。您可以修改它并维护您的自定义版本,或者更好的是,从它派生一个新的小部件并在那里实现新事件。然而,还有第三种方法

从中,我们知道小部件在其snapElements属性中存储了一个可能可捕捉的元素数组。反过来,此数组中的每个元素都会公开一个捕捉属性,如果可拖动辅助对象当前捕捉到此元素,则该属性为true;否则,辅助对象可以同时捕捉多个元素,则该属性为false

snapElements数组会针对每个拖动事件进行更新,因此它在拖动处理程序中始终是最新的。从那里,我们只需要从关联的元素中获取draggable小部件实例,并调用它的_trigger方法来引发我们自己的快照事件,该事件实际上是在引擎盖下拖动的。在此过程中,我们可以使用jQuery对象包装捕捉的元素来创建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'...
    }
});
然而,上面的代码仍然可以改进。目前,只要可拖动辅助对象保持捕捉到某个图元,就会为经常发生的每个拖动事件触发捕捉事件。此外,在捕捉结束时不会触发任何事件,这是不太实际的,并且有损于这种事件成对发生的惯例,即捕捉到、捕捉到

幸运的是,snapElements数组是持久的,因此我们可以使用它来存储状态。我们可以向每个数组元素添加snappingKnown属性,以便跟踪我们已经为该元素触发了快照事件。此外,我们可以使用它来检测自上次调用以来元素已被捕捉,并做出相应的反应

请注意,下面的代码没有引入另一个捕捉事件,而是选择传递一个额外的捕捉属性,该属性反映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;
        // ...
    }
});
您可以测试此解决方案

最后,另一个改进可能是使快照事件可以取消,就像拖动事件一样。要实现这一点,如果对_trigger的调用之一返回false,我们必须从拖动处理程序返回false。不过,在实现此功能之前,您可能需要三思而后行,因为在一般情况下,取消对管理单元或管理单元的拖动操作看起来并不是一个非常用户友好的功能

更新:从jQueryUI1.9开始。因此,上面用于获取小部件实例的代码变为:

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)
      }));
    }
  });
}

您是否会非常友好,并使用捕捉id和捕捉到的元素更新您的捕捉-我使用1.9.1,但需要找出捕捉与捕捉到的元素相关的位置-如果内容在上方、下方、左侧或右侧,则内容会有所不同-但现在我只找到了捕捉对象及其位置position@mplungjan,如果我正确理解你的评论,那么这些信息已经存在了。捕捉元素在ui.helper中可用,当ui.snap为true时,捕捉到的元素为ui.snapElement。-尚未有人接受:需要注意的是,$this.datadraggable在较新版本中已重命名为$this.dataui-draggable…@Andrew,您是否完整阅读了我的答案,包括最后的更新?我知道我的答案有点长,但您是否尝试完整阅读了它?:区别在于$this.data'draggable'在1.10+中不存在。您必须改用“ui可拖动”。他真的应该这么说,而不是仅仅发布整个代码集。