简体   繁体   中英

In JavaScript, can an event be set to preventDefault action in any of the capturing or bubbling phase?

Short question is: can you do event.preventDefault() no matter which element you set the event handler on, as long as the element is part of the "capturing", "at", and "bubbling" phase?

I wanted to make everything not selectable on the page, so at first I wanted to do

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

so that when it is at the very beginning of the capturing phase, it doesn't propagate down to the page content elements, then no selection will be done.

But it looks like even when it stops propagation, the default action will still be done.

And then, I tried to do this in the capturing phase:

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

and then change the true to false to make the handler get invoked during bubbling phase:

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

and it also works.

I used to think that the "preventDefault" is per element.

So is it true that, all along the capturing phase, at phase, and bubbling phase, you can call ev.preventDefault() and it is the very same event object, and you can prevent default action no matter which element you set the handler on, as long as the element is on the "capturing", "at", and "bubbling" loop?

It's either literally the same event object, or the implementation behaves as though it is. I've never proven to myself which of those is the case across browsers. :-) Fairly sure it's literally the same object. (See below.)

But yes, calling preventDefault on the event tells the browser not to perform the default action, regardless of when you do that.


Let's prove it's the same object:

 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> 

Just tried that code on IE9, IE11, Chrome, and Firefox. It was the same object on all of them. Scott Marcus tells us Edge does the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM