我需要能够链接点击事件,并暂时暂停它们之间的事件传播。
因此,对于给定元素,它会运行三个不同的单击事件,但第二个需要用户输入,因此当用户填写表单然后继续时,它会暂停传播。
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]并手动调用函数。
$._data( $(element)[0], 'events' ).click[].handler()
答案 0 :(得分:3)
我自己有类似的问题,我希望我的解决方案令人满意,因为我发现它可能不会直接适用于您的情况。但是,希望我在这里展示的原则可以帮助您找到自己的解决方案。
问题(如果我理解正确的话)是,如果父元素基本上同时触发了同一事件,则需要一种方法来阻止子元素触发事件。而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语句执行所需的任务。或者执行一个功能,然后完成回调。
在演示中,效果是在div元素的左边缘和底边缘上,允许每个div元素单独触发事件。但是在div2的顶部和右侧边缘,允许触发事件的唯一元素是div1。
同样,从你原来的帖子中,我认为你是在略微不同之后。但也许这种方法会以某种方式帮助你。
答案 1 :(得分:0)
尝试类似
的内容elem.on('event',function(e) {
e.stopPropagation();
goDoSomething(function(){
elem.parent().trigger(e);
});
});
goDoSomething()
可以执行AJAX调用或其他异步操作,然后无论如何调用回调以继续事件传播