防止拖动上的ko点击绑定

Prevent ko click binding on draggable?

本文关键字:绑定 ko 拖动      更新时间:2024-06-27

我发现了一些问题来阻止拖动时的事件传播,包括我现在尝试的解决方案:

演示Fiddle

$('div').draggable({
    start: function(event, ui) {
        ui.helper.bind("click.prevent",
            function(event) { event.preventDefault(); });
    },
    stop: function(event, ui) {
        setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
    }       

这根本不起作用。该问题与KO点击绑定无关。我发现的唯一一个相关的,没有被接受的答案(唯一的答案很模糊,说要尝试preventDefault())。

那么,在拖动项目后释放鼠标按钮时,如何防止单击绑定呢?

您可以使用自定义绑定来解决此问题:

ko.bindingHandlers.clickUnlessDragged = {
  init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
      var $element     = $(element),
          clickHandler = ko.utils.unwrapObservable(valueAccessor()),
          wasDragged   = false,
          mouseupHandler,
          dragstartHandler,
          dragstopHandler;
      mouseupHandler = function mouseupHandler(event) {
          if (!wasDragged) {
              clickHandler(event);
          }
      };
      dragstartHandler = function dragstartHandler() {
          wasDragged = true;
      };
      dragstopHandler = function dragstopHandler() {
          wasDragged = false;
      };
      $element.on('mouseup', mouseupHandler);
      $element.on('dragstart', dragstartHandler);
      $element.on('dragstop', dragstopHandler);
      $element.draggable();
      // clean up after ourselves if KO removes the element
      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
        $element.off('mouseup', mouseupHandler);
        $element.off('dragstart', dragstartHandler);
        $element.off('dragstop', dragstopHandler);
        $element.draggable("destroy");
      });
  }
};

将其用于:

<!-- ko foreach: name -->
<div data-bind="text: name, clickUnlessDragged: function() {console.log('clicked')}"></div>
<!-- /ko -->

所有三个事件处理程序共享相同的闭包,因此我们能够使用wasDragged标志来通信拖动是否已经开始。

mouseup事件后拖动停止;由于我们首先绑定自己的mouseup处理程序,所以它在dragstop之前运行。

更新的小提琴。