事件捕获jQuery

19

我需要捕获事件而不是让其冒泡。这就是我想要的:

<body>
   <div>
   </div>
</body>

我有一段示例代码,其中绑定了div和body的点击事件。我希望先调用body事件。该怎么做?


jQuery不支持捕获,因为IE不支持它。 - Felix Kling
3
吹毛求疵:jQuery 就是 JavaScript。你必须诉诸于“普通”的DOM API ;) - Felix Kling
你是指你从来没有编写过代码,还是建议其他人不要使用纯JS编码? - Oybek
3个回答

41

使用事件捕获代替:

$("body").get(0).addEventListener("click", function(){}, true);

默认情况下,请检查“addEventListener”的最后一个参数,它为false并处于事件冒泡模式。如果设置为true,则将以捕获事件工作。

用于跨浏览器实现。

var bodyEle = $("body").get(0);
if(bodyEle.addEventListener){
   bodyEle.addEventListener("click", function(){}, true);
}else if(bodyEle.attachEvent){
   document.attachEvent("onclick", function(){
       var event = window.event;
   });
}

默认情况下,IE8及更早版本使用事件冒泡。因此,我将事件附加到文档上而不是body上,所以您需要使用事件对象来获取目标对象。对于IE浏览器,您需要非常巧妙。


我要试一下这个:https://github.com/private-face/jquery.bind-first。希望它能达到我的预期效果。 - Toosick
1
@FelixKling 这将在IE 9中工作,但不适用于它之前的版本。我正在进行更新。 - pvnarula
如何使用事件委托来实现 - Strikers
嗨@challet,jQuery是兼容浏览器的。他们所做的就是始终将事件监听器保持在冒泡模式下。你无法在jQuery中更改它。他们试图使其在所有浏览器中都能正常工作,因此没有例外。我希望这回答了你的问题。 - pvnarula
嗨@pvnarula,它确实回答了我的问题,谢谢。我尝试通过特殊的jQuery命名空间事件在其捕获阶段捕获事件。它应该从一个被黑客攻击的jQuery事件处理程序重新触发,但对我来说似乎是一条死路。 - challet
显示剩余8条评论

3
我会这样做:

$("body").click(function (event) {
  // Do body action

  var target = $(event.target);
  if (target.is($("#myDiv"))) {
    // Do div action
  }
});

@AlwinKesler 这不是正确的答案吗?它以最易读和简洁的方式实现了 OP 想要的功能。 - Jonathan
完全同意。我的意思是我看到有人对你的答案给了一个踩的评价。 我只是表达了我的观点,认为这种方法有助于最小化事件处理。 但是,我不能确定哪种方法更快。 - Alwin Kesler
2
问题的第一句话明确说明了它是关于捕获而不是冒泡的:“我需要捕获一个事件而不是让它冒泡。” - 这个答案没有涉及到捕获和冒泡,因此被点了踩。 - xorcus
这个答案是不正确的。jQuery的 click 事件绑定在冒泡阶段。冒泡阶段发生在捕获阶段之后。jQuery不支持事件捕获(解释:https://dev59.com/2mw05IYBdhLWcg3wkik-)。 - Elliot B.
1
@ElliotB。我知道它们之间的区别,但对我来说似乎是一个XY问题:“我想先调用body事件。我该怎么做?” - 这是实现此行为的一种方法。但你是对的,这与事件捕获阶段无关。 - Jonathan
显示剩余2条评论

1
更一般地说,比@pvnarula的回答更广泛:
var global_handler = function(name, handler) {
    var bodyEle = $("body").get(0);
    if(bodyEle.addEventListener) {
        bodyEle.addEventListener(name, handler, true);
    } else if(bodyEle.attachEvent) {
        handler = function(){
            var event = window.event;
            handler(event)
        };
        document.attachEvent("on" + name, handler)
    }
    return handler
}
var global_handler_off = function(name, handler) {
    var bodyEle = $("body").get(0);
    if(bodyEle.removeEventListener) {
       bodyEle.removeEventListener(name, handler, true);
    } else if(bodyEle.detachEvent) {
       document.detachEvent("on" + name, handler);
    }
}

然后使用:

shield_handler = global_handler("click", function(ev) {
    console.log("poof")
})

// disable
global_handler_off("click", shield_handler)
shield_handler = null;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接