在javascript中反向事件冒泡

时间:2011-11-18 12:21:16

标签: javascript jquery javascript-events

如您所知,事件通常在javascript中冒泡,因此首先执行触发事件的元素的事件处理程序,然后调用父元素的事件处理程序,依此类推。这种行为会导致我正在处理的项目出现一些问题,我宁愿将执行顺序颠倒过来。

我想出了一个使用超时的解决方案:

$(element).mouseover(function(){
    var that = this;
    setTimeout(function() {
       //actual event handler, but references to "this" are replaced with "that"
    },$(this).parents().length)
 });

基本上,事件处理程序在短暂超时后执行,等待时间取决于DOM树中元素的深度: html元素的事件处理程序立即执行,body元素的事件处理程序在等待1ms后执行,依此类推。所以事件的执行顺序是相反的。

我的第一次测试结果是积极的,但我仍然不确定此解决方案是否存在任何问题或缺点。您如何看待这个解决方案?关于如何解决这些问题的其他想法也受到高度赞赏。

3 个答案:

答案 0 :(得分:18)

反向事件冒泡称为捕获阶段。

请参阅DOM event architecture

true作为第3个参数传递给Event.addEventListener,使其在捕获阶段触发

el.addEventListener("click", function () {
  console.log("i run in capture");
}, true);

当然,它不会在传统平台上工作。您需要一个DOM3事件填充程序来模拟事件系统。随意为DOM-shim

做出贡献

答案 1 :(得分:0)

我可以看到你的解决方案的一个巨大缺点是事实,对于每个处理过的事件,你必须从this开始向上遍历DOM以建立父母的数量。

在每个事件处理程序中以这种方式遍历=低性能。

答案 2 :(得分:0)

你可以尝试模仿它,但可能会造成很多麻烦。

这是一个非常简单的例子(在jsfiddle上)。 我们的想法是聚合来自每个事件的回调,并在document事件处理程序中以相反的顺序调用它们(我们也清除了我们的列表,以确保下次单击时有新的队列)。

<div id="a">
    <div id="b">
        <a href="/test">Click Me!</a>
    </div>
</div>
var cb = [];

$(document).click(function(evt){

    cb.unshift(function(){
        console.log('document');
    });
    var i;
    for(i=0; i<cb.length; ++i){
        cb[i].call(null, evt);
    }
    cb = [];
});

$("#a").click(function(){
    cb.unshift(function(){
        console.log('div#a');
    });
});

$("#b").click(function(){
    cb.unshift(function(){
        console.log('div#b');
    });
});

$('a').click(function(evt){
    cb.unshift(function(evt){
        evt.preventDefault();
        console.log('a');
    });
});

也许你需要改变你的设计?您可以发布更多信息,为什么需要事件捕获?