How to stopPropagation() w/ Hammer.js 2.0?
Solution 1
In Hammer 2.0.6, as others have answered, you can call event.srcEvent.stopPropagation()
. One caveat, you have to set domEvents=true
as per the documentation.
Hammer is able to trigger DOM events with the option domEvents: true. This will give your methods like stopPropagation(), so you can use event delegation. Hammer will not unbind the bound events.
Sample Code
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();});
or
var hammertime = new Hammer(elem);
hammertime.domEvents = true;
hammertime.on("panstart", function(e){e.srcEvent.stopPropagation();});
This technique is listed on the tips page of the docs, here http://hammerjs.github.io/tips/
Solution 2
Try event.srcEvent.stopPropagation()
. Hammer wraps itself around the native event object; srcEvent
gives you access to the 'usual' affordances of the event object.
Solution 3
I was having the same problem, specifically that a nested Hammer component was not properly stopping propagation. In my case, I wanted a modal container (which was the highest level parent component, full screen with an opaque black background) to handle a click event that closed the whole modal. The children components hold the content and I wanted to cancel propagation with those children. In other words, the desired behavior is: a click inside the modal does nothing, but a click outside the modal closes the modal.
This is further complicated by the react-hammerjs
library that adds an extra layer of abstraction, including potential bug reports that indicate improper event propagation.
No matter what I did, I could not get stopPropagation()
to work. Even with the options.domEvents
set to true. I also tried digging into the event.srcEvent.stopPropagation()
(and variants) with no success.
I found that using stopImmediatePropagation()
works as intended, regardless of the domEvents
setting. I understand that stopImmediatePropagation()
may be more extreme, but I experience no side effects. Click handlers inside the children (like buttons) still work fine, and I can cancel the modal by clicking on the container.
Here's my final snippet that works fine:
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>
)
Solution 4
Unfortunately, stopPropagation()
doesn't work. You need to check the target of your gesture to understand from where the event has been triggered.
For example:
$(parent_element).hammer().bind(gesture_type, function(event) {
if (event.gesture.target.className === correctClass)
doStuff();
});
Solution 5
That just works:
$(".outer-box").hammer({
preventDefault: true,
domEvents: true
}).on("panright", function() { });
Admin
Updated on July 04, 2022Comments
-
Admin almost 2 years
I have a parent and child div. Panning/dragging on the child should not affect the parent. This is a similar question but was asked a year ago, and I'm using a newer version of Hammer.js w/ the jQuery wrapper.
My assumption was that I'd have to somehow stopPropagation() but I'm not really sure how to use it.
I've mocked up a demo showing my problem on JsFiddle. I've also commented out the couple things I've tried.
$(".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 });
Any suggestions or tips? Thanks!
-
br4nnigan over 5 yearsThat's terrible, I'll stop using HammerJs
-
Cully about 5 years
stopImmediatePropagation
worked for me, when juststopPropagation
was not. Thank you! -
WeakPointer over 4 yearsAt first the stopImmediatePropagation seemed to work for me too. But it ended up with side effects I couldn't explain. Once it was called once, the outer element's handler wouldn't fire, even when other clicks should have been caught by it. I ended up not using it but setting a new property within the srcEvent that a higher level could look for as it is bubbled. In one sense cleaner, in another not so. Now I have to standardize on this new property for any level above. But getting the handlers registered in the proper order was key. Thanks.