【问题标题】:Prevent ko click binding on draggable?防止可拖动的ko点击绑定?
【发布时间】:2013-12-28 07:00:41
【问题描述】:

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

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

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

【问题讨论】:

  • 您想要实现的究竟是什么?您可以通过在小提琴中执行以下操作来阻止默认点击操作:点击:function(e) {e.preventDefault();}.
  • 我想我错过了一些东西。拖动后松开鼠标按钮不应该触发点击事件吗?
  • 正确,拖动后松开鼠标按钮应该不会触发点击事件。

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


【解决方案1】:

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

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.

【讨论】:

  • 效果很好,只是它似乎不像默认的点击绑定那样传递事件。我使用 e.ctrlKey 来检测 CTRL+点击。这很容易解决吗?
  • @ScottBeeson 两个字 :) 我已经更新了 mouseupHandler 以传递事件。
  • 谢谢!并且 +1 用于理解问题:)
  • 其实,还有一件事……我以为我能弄明白,但我运气不好。它还需要传递viewModel。我应该预先指定所有这些。对不起。
  • 您是否尝试将mouseupHandler 中的clickHandler(event) 更改为clickHandler(bindingContext, event)clickHandler(viewModel, event)
猜你喜欢
  • 2010-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-15
  • 1970-01-01
  • 2013-08-04
相关资源
最近更新 更多