Hello, I am Qiu Feng.

B: well… Here I am again, this time at… Issues arising from the discussion of Nan Xi and.

So how did it go?

The cause of

Recently, Nan Xi was reading an article related to the event, and then she came to me and discussed that the execution effect of the following code was not consistent with the online article. The code is as follows:

<div>
	<button>123</button>
</div>
<script>
  var btn = document.querySelector('button');
  var div = document.querySelector('div');
  btn.addEventListener('click'.function () {
    console.log('bubble'.'btn');
  }, false);
  btn.addEventListener('click'.function () {
    console.log('capture'.'btn');
  }, true);
  div.addEventListener('click'.function () {
    console.log('bubble'.'div');
  }, false);
  div.addEventListener('click'.function () {
    console.log('capture'.'div');
  }, true);
</script>
Copy the code

This is a very simple code for event registration, and then we click button.

Think about it without looking at the results.

And then we’ll look at the results

For most of the old-timers, the following order rolls off the tongue.

capture div
bubble btn
capture btn
bubble div
Copy the code

explore

But both MDN and most tutorials on the web are in this order.

I was puzzled by this phenomenon. I vaguely remember that a few months ago Chrome did not behave like this.

The GIF above is available in Chrome 90.0.4430.212

So I found a Chrome version 84.0.4109.0 to test.

As expected, there is a problem with the version, but it is still difficult to track the matter. Because I searched the specification and checked some materials on Google, it did not help me to solve the problem well. I am not sure whether it is because of the bug introduced by Chrome or what the problem is.

So I reported the problem to Chromium.

Finally, with the help of Chrome developers, these two discussions were found

Github.com/whatwg/dom/…

Github.com/whatwg/dom/…

As can be seen from the above issues, the cause is at bugs.webkit.org/show_bug.cg… In webKit, it is pointed out that the current event model in WebKit causes the child element’s capture event to take precedence over the parent element’s capture event in the case of Shadow DOM.

In the old model, once AT_TARGET was reached, all registered listeners were fired sequentially, regardless of whether they were marked for capture or not. Because Shadow DOM creates multiple targets, the sequence of events is incorrect.

Gecko (Mozilla Firefox’s typography engine) works fine (catch first, bubble later). The WHATWG proposed a new model structure to solve this problem.

conclusion

All the questions have been solved. Now let’s sort out our problems for us.

1. Use the event triggering mechanism of an earlier version
performance The order in which the target element fires events is related to the order in which the events are registered
2. New event triggering mechanism
performance The target element fires events in the order of capture and then bubble

The release boundaries are 89.0.4363.0 and 89.0.4358.0 for Chrome.

Chrome 89.0.4363.0 was released on 2020-12-22 in the last few months, so if you update Chrome in the last few months you will see the same phenomenon as I did.

In Chrome 89.0.4363.0 and later, target elements no longer trigger in the order they were registered! Instead, it captures and then bubbles!

Then we’ll see how this change affects us.

  1. First let’s be clear: yes, most of the previous articles on the web are no longer applicable to the current version of Chrome!
  2. If there is a dependency related event firing sequence in our business, check it out!

An 🌰

<div>
	<button>123</button>
</div>
<script>
  var a = [];
  var btn = document.querySelector('button');
  var div = document.querySelector('div');
  btn.addEventListener('click'.function () {
    console.log('bubble'.'btn');
    a.push(1);
  }, false);
  btn.addEventListener('click'.function () {
    console.log('capture'.'btn');
    a.push(2);
  }, true);
  div.addEventListener('click'.function () {
    console.log('bubble'.'div');
  }, false);
  div.addEventListener('click'.function () {
    console.log('capture'.'div');
  }, true);
</script>
Copy the code

In the new version, when the button element is clicked, the final result of a is [2,1], whereas in the old version, the result is [1,2].

So how to transform some online code at this stage?

The improved scheme

So now that we have no control over which browser users use, how can we solve this problem to avoid online problems?

It’s really simple.

All we need to do is to write the capture event code first and then the bubble event code in order for all the target elements to be compatible with this update.

thinking

Nothing is set in stone, and whether it’s a relatively official article or tutorial we should take it with a grain of salt and trust what we see. This may be a wrong example years from now, but it is a record of the issues at hand. This article also has many shortcomings, if any questions please point out in the comments.

subsequent

The new description has been submitted to MDN and has been incorporated into PR

The resources

chromium.cypress.io/

Github.com/whatwg/dom/…

Bugs.webkit.org/show_bug.cg…

Github.com/whatwg/dom/…

Dom.spec.whatwg.org/#dispatchin…

Go back to my previous articles and you may get more!

  • 2021 Front End Learning Path Book List — The Path to Personal Growth: 570+ likes

  • Teach you to achieve micro channel 8.0 “fried crack” 🎉 facial effects: 400+ likes

  • From a design website on the front-end watermarking (detailed tutorial) : 790+ likes

  • From king of Glory I learned the front-end novice guide: 260+ likes

  • Unlock the secrets of “file download” : 140+ likes

  • 10 cross-domain solutions (with the ultimate trick) : 940+ likes

conclusion

❤️ follow + like + favorites + comments + forward ❤️, original is not easy, encourage the author to create better articles

Follow public accountNotes on the autumn wind, a focus on front-end interview, engineering, open source front-end public number