admin管理员组

文章数量:1189388

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!

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!

Share Improve this question edited May 23, 2017 at 11:47 CommunityBot 11 silver badge asked Sep 24, 2014 at 22:08 EricEric 1011 gold badge1 silver badge5 bronze badges
Add a comment  | 

7 Answers 7

Reset to default 8

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/

Try event.srcEvent.stopPropagation(). Hammer wraps itself around the native event object; srcEvent gives you access to the 'usual' affordances of the event object.

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

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();
});

That just works:

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

I had a similar situation in which I had two swipe-able containers on top of each other and only wanted the top one to handle the event. For some reason, event.srcEvent.stopPropagation just wasn't working.

As it turns out, there exists a library that extends Hammer.js with event propagation called propagating-hammerjs. I pulled this into my project it fixed my problem.

Had the same issue, however was able to handle this by enabling domEvents.

Hammer.defaults.domEvents = true;

Once enabled, event.stopPropagation(); worked fine.

本文标签: javascriptHow to stopPropagation() w Hammerjs 20Stack Overflow