Javascript 带有点击事件的 stopPropagation()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11019868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:03:03  来源:igfitidea点击:

stopPropagation() with tap event

javascriptjqueryhammer.jsstoppropagation

提问by TimPetricola

I'm using hammer.jsand it appears that I event.stopPropagation()doesn't work with tap event.

我正在使用hammer.js,但似乎event.stopPropagation()无法使用点击事件。

If I click on the child, the associated event is triggered but parent's event is also triggered and I don't want that.

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

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

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

Here is an example: http://jsfiddle.net/Mt9gV/

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

? I also tried with jGesturesand the issue seems to be the same. How can I achieve this result with one of those library? (or another one if it is needed)

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

采纳答案by rharper

As mentioned in another comment, one would expect, as you did, that calling event.stopPropagation()would be all that is require to stop the event from bubbling up to the parent.

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

Details:However, in Hammer.js this is not so. Hammer creates a new gesture state machine for each element on which you call $(el).hammer(). So when a touch event is fired on the child by the browser it is processed first by the logic for child and then again by the logic on the parent. As such to stop the parent from getting the tapevent you must prevent the parent's hammer state machine from getting the original touch event. Generally, calling event.stopPropagation()will also stop the propagation of the original event. However, hammer.js's tapevent is fired on touchendbut the originalEventis the cached touchstartevent. As such, stopping propagation on the original event has no effect because the touchstartevent has long ago bubbled up through the DOM.

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

Solution?I believe this is a bug in hammer- submit a pull request that corrects the originalEventin the tap event. As others have suggested you could check the event's target, but that's always the parent element - another bug in my opinion. So instead check the event.originalEvent.target. Here's a JS fiddlewith this mediocre solution implemented: http://jsfiddle.net/HHRHR/

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

回答by Leo

I had a similar problems with the touch events.

我对触摸事件有类似的问题。

I solved it by using

我通过使用解决了它

return false;

which is the same as calling e.preventDefault(); e.stopPropagation();

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

回答by TimPetricola

As I couldn't get this work, I used a variable to know if the child event has already been triggered. It works quite well with jGestures (I have not tried with hammer.js)

由于我无法完成这项工作,因此我使用了一个变量来了解子事件是否已被触发。它与 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');
});

?

?

回答by Jay

If you can't get this to work.. just call another method on the tap after verifying the needful (arguments.calleeis where I would start in such a case) , this would have the added benefits of letting other users hook the button also...

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

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

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

回答by chrisf

You could try checking e.currentTarget(or is it e.target?) inside the parent handler to find out which element was tapped; if it's the child element then just return immediately, else continue with the function.

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