如何使用 Hammer.js 2.0 stopPropagation() ?

问题描述 投票:0回答:8

我有一个父子分区。对子级进行平移/拖动不应影响父级。 这是一个类似的问题,但一年前就被问到了,我正在使用带有 jQuery 包装器的较新版本的 Hammer.js。

我的假设是我必须以某种方式 stopPropagation() 但我不太确定如何使用它。

我已经模拟了在 JsFiddle 上展示了我的问题的演示。我还评论了我尝试过的几件事。

$(".outer-box").hammer().bind("panright", function(event){
    // do stuff when panning
    // panning here should move both boxes
});
$(".outer-box").hammer().bind("panend", function(event){
    // do stuff when panning ends
});

$(".inner-box").hammer().bind("panright", function(event){
    // do stuff when panning
    // panning here should only affect the inner box
});
$(".inner-box").hammer().bind("panend", function(event){
    // do stuff when panning ends
});

有什么建议或提示吗?谢谢!

javascript jquery hammer.js stoppropagation
8个回答
8
投票

在Hammer 2.0.6中,正如其他人已经回答的那样,您可以拨打

event.srcEvent.stopPropagation()
。需要注意的是,您必须根据文档设置
domEvents=true

Hammer 能够使用选项 domEvents: true 触发 DOM 事件。这将为您提供诸如 stopPropagation() 之类的方法,因此您可以使用事件委托。 Hammer 不会解绑已绑定的事件。

示例代码

var mc = new Hammer.Manager(elem);
mc.options.domEvents=true; // enable dom events
var pinch = new Hammer.Pinch();
mc.add(pinch);
mc.get('pinch').set({ enable: true });
mc.on("pinch",function(e){e.srcEvent.stopPropagation();});

var hammertime = new Hammer(elem);
hammertime.domEvents = true;
hammertime.on("panstart", function(e){e.srcEvent.stopPropagation();});

此技术列在文档的提示页面上,此处 http://hammerjs.github.io/tips/


5
投票

尝试

event.srcEvent.stopPropagation()
。 Hammer 将自身包裹在本机事件对象周围;
srcEvent
使您可以访问事件对象的“通常”功能。


3
投票

我遇到了同样的问题,特别是嵌套的 Hammer 组件没有正确停止传播。就我而言,我想要一个模态容器(这是最高级别的父组件,带有不透明黑色背景的全屏)来处理关闭整个模态的单击事件。子组件保存内容,我想取消这些子组件的传播。换句话说,所需的行为是:在模式内部单击不执行任何操作,但在模式外部单击会关闭模式。

react-hammerjs
库增加了额外的抽象层,包括指示不正确的事件传播的潜在错误报告,这使情况变得更加复杂。

无论我做什么,我都无法让

stopPropagation()
工作。即使
options.domEvents
设置为 true。我也尝试深入研究
event.srcEvent.stopPropagation()
(和变体),但没有成功。

我发现使用

stopImmediatePropagation()
可以按预期工作,无论
domEvents
设置如何。我知道
stopImmediatePropagation()
可能更极端,但我没有经历任何副作用。子项内的单击处理程序(如按钮)仍然可以正常工作,我可以通过单击容器来取消模式。

这是我的最终片段,效果很好:

const myComponent = (props) => (
   <Hammer onTap={() => { ... cancel modal ... }} >
      <div className={'modal-container'} >
         <Hammer onTap={(e) => e.srcEvent.stopImmediatePropagation()}>
            <div className={'modal-content'}>
               ... modal content
               <Hammer onTap={() => { ... button handler ... }}>
                  <button>Take Action</button>
               </Hammer>
            </div>
         </Hammer>
      </div>
   </Hammer>
)

2
投票

不幸的是,

stopPropagation()
不起作用。您需要检查手势的目标,以了解事件是从哪里触发的。

例如:

$(parent_element).hammer().bind(gesture_type, function(event) {
    if (event.gesture.target.className === correctClass)
        doStuff();
});

1
投票

这就是有效的:

$(".outer-box").hammer({
  preventDefault: true,
  domEvents: true
}).on("panright", function() { });

0
投票

我也遇到过类似的情况,我有两个可滑动的容器,彼此叠在一起,只希望最上面的一个来处理事件。由于某种原因,

event.srcEvent.stopPropagation
无法正常工作。

事实证明,存在一个通过事件传播扩展 Hammer.js 的库,称为 propagating-hammerjs。我将其纳入我的项目中,它解决了我的问题。


0
投票

有同样的问题,但是能够通过启用 domEvents 来解决这个问题。

Hammer.defaults.domEvents = true;

一旦启用,event.stopPropagation();效果很好。


0
投票

肖恩。我非常喜欢你的解决方案,但是,如何将此配置放入 HammerGestureConfig 中?

© www.soinside.com 2019 - 2024. All rights reserved.