【问题标题】:Javascript pause event propagationJavascript 暂停事件传播
【发布时间】:2014-05-19 07:16:54
【问题描述】:

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

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

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

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

为了允许单一职责,并且链接更高/更低的事件不应该知道事件传播已暂停,并且不应调用两次。

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

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

有一个类似的问题,但没有一个令人满意的答案:How to continue event propagation after cancelling?。

编辑:

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

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

【问题讨论】:

  • 你能保证你绑定的导致延迟的特殊事件是第一个绑定的点击事件吗?使气泡在同一元素上的事件列表中间停止的地方拾取比简单地使用特殊标志使当前元素上的所有事件再次发生以阻止该特殊事件被处理要困难得多时间。
  • 没有。它可能是第二个。
  • @Howlin,不,这个问题是 4 个月前提出的,这是在单个元素上暂停和继续事件,不会阻止冒泡到父元素。

标签: javascript jquery events


【解决方案1】:

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

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

这里是 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;
});

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

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

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

再次,从您的原始帖子来看,我认为您追求的东西略有不同。但也许这种方法会在某种程度上对您有所帮助。

【讨论】:

    【解决方案2】:

    试试类似的东西

    elem.on('event',function(e) {
        e.stopPropagation();
    
        goDoSomething(function(){
            elem.parent().trigger(e);
        });
    });
    

    goDoSomething() 可以进行 AJAX 调用或其他异步调用,然后无论出于何种原因调用回调以继续进行事件传播

    【讨论】:

    • 不幸的是,这可以传播父元素单击事件,但不能传播同一对象上的多个单击事件。解决方案需要配合 event.stopImmediatePropagation();
    猜你喜欢
    • 1970-01-01
    • 2017-07-10
    • 2012-08-05
    • 1970-01-01
    • 2013-08-20
    • 2012-05-09
    • 2011-01-29
    • 1970-01-01
    • 2012-05-06
    相关资源
    最近更新 更多