防止可拖动的ko点击绑定?

时间:2013-12-10 16:31:58

标签: javascript jquery jquery-ui knockout.js click

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

Demo 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())。

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

1 个答案:

答案 0 :(得分:2)

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

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之前运行。

Updated fiddle