【问题标题】:stopPropagation() with tap event带有点击事件的 stopPropagation()
【发布时间】:2012-06-16 16:55:35
【问题描述】:

我正在使用hammer.js,但我的event.stopPropagation() 似乎不适用于点击事件。

如果我点击孩子,关联的事件会被触发,但父母的事件也会被触发,我不希望这样。

$('#parent').hammer().bind('tap', function(e) {
    $(this).css('background', 'red');
});​​​​​​​​

$('#child').hammer().bind('tap', function(e) {
    e.stopPropagation();
    $(this).css('background', 'blue');
});

这里是一个例子:http://jsfiddle.net/Mt9gV/

​ 我也试过jGestures,问题似乎是一样的。 如何使用其中一个库实现此结果? (如果需要,也可以另外一个)

【问题讨论】:

  • 我认为这可能与您在父元素和子元素上都设置了“锤子”的事实有关。但是,我不是 100% 确定。
  • 很遗憾,如果我不对两个元素都使用锤子,则点击事件将不起作用。

标签: javascript jquery hammer.js stoppropagation


【解决方案1】:

正如另一条评论中提到的,人们会像您一样期望调用 event.stopPropagation() 将是阻止事件冒泡到父级所需要的全部内容。

详细信息:但是,在 Hammer.js 中并非如此。 Hammer 为您调用$(el).hammer() 的每个元素创建一个新的手势状态机。因此,当浏览器在子级上触发触摸事件时,它首先由子级逻辑处理,然后再次由父级逻辑处理。因此,要阻止父级获取 tap 事件,您必须阻止父级的锤子状态机获取原始触摸事件。通常,调用event.stopPropagation() 也会停止原始事件的传播。但是,hammer.js 的 tap 事件在 touchend 上触发,但 originalEvent 是缓存的 touchstart 事件。因此,停止对原始事件的传播没有任何效果,因为 touchstart 事件很久以前就通过 DOM 冒泡了。

解决方案?我相信这是 锤子中的错误 - 提交一个拉取请求以更正点击事件中的 originalEvent。正如其他人建议的那样,您可以检查事件的目标,但这始终是父元素 - 我认为这是另一个错误。所以改为检查event.originalEvent.target。这是一个JS fiddle,实现了这个平庸的解决方案:http://jsfiddle.net/HHRHR/

【讨论】:

  • 注意:我对这个问题的回答已经过时了——自发布以来,hammer.js 已经发生了重大变化。
  • 我们使用与 TimPetricola 的原始 sn-p 几乎相同的代码。我可以确认它可以与 Hammer.JS - v1.0.5 - 2013-04-07 一起按预期工作。看起来 Hammer.js 认真对待了这个问题并修复了它。
【解决方案2】:

由于无法完成这项工作,我使用了一个变量来了解子事件是否已被触发。它与 jGestures 配合得很好(我没有尝试过使用hammer.js)

var childTriggered = false;

$('#child').bind('tapone', function(e) {
    $(this).css('background', 'red');
    childTriggered = true;
});

$('#parent').bind('tapone', function(e) {
    if(childTriggered) {
        childTriggered = false;
        return;                
    }
    $(this).css('background', 'blue');
});

【讨论】:

    【解决方案3】:

    我在触摸事件方面遇到了类似的问题。

    我通过使用解决了它

    return false;
    

    这与调用相同 e.preventDefault(); e.stopPropagation();

    【讨论】:

      【解决方案4】:

      如果你不能让它工作.. 只需在验证需要后调用另一个方法(arguments.callee 是我在这种情况下开始的地方),这将有额外的好处让其他用户也钩住按钮...

      function myFn(a) { if(a) $(this).css('background', 'red'); else $(this).css('background', 'blue');}

      $('#parent').hammer().bind('tap', function(e) {
         //Check arguments.callee or other data in event and call myFn
      });​​​​​​​​
      
      $('#children').hammer().bind('tap', function(e) {
        //Same here
      });
      

      【讨论】:

      【解决方案5】:

      您可以尝试检查父处理程序中的e.currentTarget(或者是e.target?)以找出哪个元素被点击;如果它是子元素,则立即返回,否则继续该函数。

      【讨论】:

      • 好主意,但即使我点击子元素,它也会返回父元素。
      • 嗯。我怀疑 Hammer 实际上绑定到 window 对象以进行所有计算,计算出触摸事件的全局 X/Y 坐标,然后确定从中单击了哪个元素。在这种情况下, stopPropagation 不会有任何效果。但我只是从Hammer.js source 的快速浏览中猜测!
      猜你喜欢
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多