javascript Javascript暂停事件传播

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21043970/
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-10-27 19:54:21  来源:igfitidea点击:

Javascript pause event propagation

javascriptjqueryevents

提问by Aaron Harun

I need to be able to chain click events, and temporarily pause event propagation between them.

我需要能够链接点击事件,并暂时暂停它们之间的事件传播。

So, for a given element, it runs three different click events, but the second one needs user input, so it pauses propagation while the user fills in the form and then continues.

因此,对于给定的元素,它运行三个不同的点击事件,但第二个需要用户输入,因此它在用户填写表单时暂停传播,然后继续。

clickAction2 = ->
  #Pause event propagation
  somehow.pauseEventPropegationRightHere()

  #Go and handle the dialogs, user input, JS requests
  goDoSomething().thenDoCallback( ->
     #User is now authenticated completely.
     somehow.continueEventPropegationAsIfNothingHappened()
  )

In an effort to allow single responsibility, and events chained higher/lower shouldn't have knowledge that the event propagation was paused and nothing should be called twice.

为了允许单一责任,上级/下级链接的事件不应该知道事件传播已暂停,并且不应两次调用任何内容。

No, the three click events can't be called sequentially from another function or any similar primitive solution.

不,不能从另一个函数或任何类似的原始解决方案顺序调用三个点击事件。

This is in relation to AngularJS directives, but the solution does not need to rely on it.

这与 AngularJS 指令有关,但解决方案不需要依赖它。

There is a similar question but none of the answers are satisfactory: How to continue event propagation after cancelling?.

有一个类似的问题,但没有一个令人满意的答案:如何在取消后继续事件传播?.

Edit:

编辑:

What I need is a cleaner way to call e.stopImmediatePropagation(), and then continue from that point. As of right now, my best option is by manually entering the jQuery "private' data[1] and calling the functions manually.

我需要的是一种更简洁的调用方式e.stopImmediatePropagation(),然后从那一点继续。到目前为止,我最好的选择是手动输入 jQuery“私有”数据 [1] 并手动调用函数。

  1. $._data( $(element)[0], 'events' ).click[].handler()
  1. $._data( $(element)[0], 'events' ).click[].handler()

回答by user3207952

I had a similar issue myself and I hope my solution is satisfactory because I realize it may not directly apply to your situation. However hopefully the principle I show here helps you find a solution of your own.

我自己也有类似的问题,我希望我的解决方案令人满意,因为我意识到它可能不直接适用于您的情况。但是希望我在这里展示的原则可以帮助您找到自己的解决方案。

The problem (if I understand correctly) is that you need a way to prevent a child element from triggering an event if a parent element has triggered the same event at essentially the same time. Whereas e.stopImmediatePropagation()prevents event bubbling, effectively halting any parent elements from triggering the event. I believe the solution is using a setTimeout()with a zero millisecond delay to perform the desired function and if the triggering event ever occurs again while the setTimeout()is in use, use clearTimeout()to stop the previous event from occuring. The best way I can demonstrate this approach is by creating a parent and child element and watching the mouseleaveevent.

问题(如果我理解正确的话)是,如果父元素基本上在同一时间触发了相同的事件,则您需要一种方法来防止子元素触发事件。而e.stopImmediatePropagation()防止事件冒泡,有效地阻止任何父元素触发事件。我相信解决方案是使用setTimeout()具有零毫秒延迟的 a 来执行所需的功能,并且如果setTimeout()在使用时再次发生触发事件,则使用它clearTimeout()来阻止前一个事件的发生。我可以演示这种方法的最佳方式是创建父元素和子元素并观看mouseleave事件。

Here is the JS/jQuery:

这是 JS/jQuery:

var timerActive = false;
$('#div1, #div2').mouseleave(function(e) {
    var trigger = $(this).attr('id'); // for monitoring which element triggered the event
    if (timerActive) {
        clearTimeout(announce); // stops the previous event from performing the function
    }
    window.announce = setTimeout(function() {
        alert('mouse exited'+trigger); // trigger could be use in an if/else to perform unique tasks
        timerActive = false;
    },0);
    timerActive = true;
});

Here is a JSFiddle demo: http://jsfiddle.net/XsLWE/

这是一个 JSFiddle 演示:http: //jsfiddle.net/XsLWE/

Since the events are triggered sequentially from child to parent, clearing each previous timeout effectively waits for the last or top-most element to trigger the event. At which point you could use an IF/ELSE statement to perform desired tasks. Or perform one function then a callback on complete.

由于事件是从子级到父级顺序触发的,因此清除每个先前的超时有效地等待最后一个或最顶部的元素触发事件。此时您可以使用 IF/ELSE 语句来执行所需的任务。或者执行一个函数,然后在完成时回调。

In the demo, the effect is that on the left and bottom edges of the div elements, each div element is allowed to trigger the event individually. However on the top and right edges of div2, the only element allowed to trigger the event is div1.

在demo中,效果是在div元素的左右边缘,允许每个div元素单独触发事件。但是在 div2 的上边缘和右边缘,唯一允许触发事件的元素是 div1。

Again, from your original post, I take it you are after something slightly different. But perhaps this approach will help you in some way.

同样,从您的原始帖子中,我认为您所追求的东西略有不同。但也许这种方法会以某种方式帮助你。

回答by pstenstrm

Try something like

尝试类似

elem.on('event',function(e) {
    e.stopPropagation();

    goDoSomething(function(){
        elem.parent().trigger(e);
    });
});

goDoSomething()could do an AJAX call or something else async, and then for whatever reason call the callback to have the event propagation continue

goDoSomething()可以执行 AJAX 调用或其他异步操作,然后出于任何原因调用回调以使事件传播继续