0

简短的问题是:event.preventDefault()无论您在哪个元素上设置事件处理程序,只要该元素是“捕获”、“at”和“冒泡”阶段的一部分,你能做到吗?

我想让页面上的所有内容都无法选择,所以起初我想做

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

这样当它在捕获阶段的最开始时,它不会传播到页面内容元素,那么不会进行任何选择。

但看起来即使它停止传播,默认操作仍会执行。

然后,我尝试在捕获阶段执行此操作:

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

然后将 更改truefalse以使处理程序在冒泡阶段被调用:

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

它也有效。

我曾经认为“preventDefault”是每个元素。

那么,在整个捕获阶段、at 阶段和冒泡阶段,您是否可以调用ev.preventDefault()它并且它是完全相同的事件对象,并且无论您将处理程序设置在哪个元素上,您都可以阻止默认操作,只要元素在“捕获”、“在”和“冒泡”循环中?

4

1 回答 1

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 也是如此。

于 2017-04-28T16:09:31.487 回答