在JavaScript中,是否可以将事件设置为在任何捕获或冒泡阶段中阻止默认操作?

时间:2017-04-28 16:06:51

标签: javascript event-handling event-bubbling event-capturing

简短的问题是:无论你在哪个元素上设置事件处理程序,都可以event.preventDefault(),只要该元素是"捕获"," at&#的一部分34;和"冒泡"相位θ

我想让页面上的所有内容都无法选择,所以一开始我想做

document.addEventListener("selectstart", function(ev) {
  ev.stopPropagation();
}, true);

因此,当它处于捕获阶段的最开始时,它不会向下传播到页面内容元素,那么就不会进行任何选择。

但即使它停止传播,它看起来仍然会完成默认操作。

然后,我试图在捕获阶段这样做:

document.addEventListener("selectstart", function(ev) {
  ev.preventDefault();
}, true);

然后将true更改为false,以便在冒泡阶段调用处理程序:

document.addEventListener("selectstart", function(ev) {
  ev.preventDefault();
}, false);

它也有效。

我曾经认为" preventDefault"每个元素。

因此,在捕获阶段,阶段和冒泡阶段,你可以调用ev.preventDefault()并且它是完全相同的事件对象,并且无论你使用哪个元素都可以防止默认操作设置处理程序,只要该元素位于"捕获"," at"和"冒泡"循环?

1 个答案:

答案 0 :(得分:1)

它或者是字面上相同的事件对象,或者实现的行为就像它一样。我从来没有向自己证明过哪些浏览器就是这种情况。 :-)相当确定它实际上是同一个对象。 (见下文。)

但是,是的,在事件上调用preventDefault会告诉浏览器不要执行默认操作,无论你何时这样做。

让我们证明它是同一个对象:

var CAPTURE = true;
var BUBBLING = false
var current = null;
hook(document.body, "body");
hook(document.getElementById("middle"), "middle");
hook(document.getElementById("target"), "target");

function hook(element, name) {
  element.addEventListener("click", function(e) {
    if (element === document.body) {
      console.log(name + " capture");
      current = e;
    } else {
      console.log(name + " capture, same? " + (e === current));
    }
  }, CAPTURE);
  var phase = name === "target" ? "target" : "bubbling";
  element.addEventListener("click", function(e) {
    console.log(name + " " + phase + ", same? " + (current === e));
  }, BUBBLING);
}
<div id="middle">
  <div id="target">Click me</div>
</div>

在IE9,IE11,Chrome和Firefox上试过这个代码。它们都是同一个对象。 Scott Marcus告诉我们Edge也是如此。