jQuery UI的 - 可拖动的“捕捉”事件(jQuery UI – draggable '

2019-06-26 11:26发布

我正在寻找一种方式来绑定snap事件。

当我拖着一个元素在我的面和拖动元素捕捉到一个声明的对齐位置我想触发一个事件。

事情是这样的:

$(".drag").draggable({
  snap: ".grid",
  snaped: function( event, ui ) {}
});

奖金点:与所述参考.grid其中拖动元件卡扣元件。

Answer 1:

draggable窗口小部件不公开这样的事件开箱即用(还)。 你可以修改和维护您的自定义版本,或者更好,能从中得到一个新的部件,有落实新的事件。 然而,有,第三种方式。

从这个问题 ,我们知道小部件存储在其潜在的“snappable”元素的数组snapElements属性。 反过来,此数组中的每个元素暴露出snapping属性,该属性是true ,如果拖动辅助目前捕捉到该元素和false否则(助手可以同时捕捉到几个元件)。

snapElements阵列为每个更新drag事件,所以它始终是最新的drag处理程序。 从那里,我们只需要获得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事件将被触发,每drag事件(发生了很多 ),只要拖动助手仍然捕捉到的元素。 此外,抢购结束,这是不是很实用时不触发事件,并从成对发生此类事件的惯例有损( snapped-insnapped-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从我们的drag处理程序,如果调用一个_trigger()返回false 。 你可能想实现这一点,虽然,如取消对管理单元或扣出的拖动操作不像在一般情况下,一个非常人性化的功能之前,要三思而后行。

更新:从jQuery UI的1.9起, 该data()键变成了小部件的全名,由破折号替代点 。 因此,上述用于获得窗口小部件实例的代码变为:

var draggable = $(this).data("ui-draggable");

代替:

var draggable = $(this).data("draggable");

使用不合格的名称仍支持的1.9,但不建议,并支持将在1.10被丢弃。



Answer 2:

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


文章来源: jQuery UI – draggable 'snap' event