16
头图

Hello everyone, I am Qiufeng.

Hmm... I'm here again, this time again in... Nan Xihe's discussion.

What's the matter?

cause

Recently, Nanxi was reading articles related to the incident, and then came to discuss with me that the execution effect of the following code is inconsistent with the article on the Internet. 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>

The above is a very simple event registration code, and then we click button .

Without looking at the results, think about it.

image-20210521001552341

Then let's take a look at the result

2021-05-21-00.14.55

For most of the front-end veterans, they will blurt out the following sequence.

capture div
bubble btn
capture btn
bubble div

explore

But whether it is MDN, or most tutorials on the Internet, it is said that this order.

image-20210521002720918

image-20210523200131631

image-20210521002556311

I am very confused about this phenomenon. I vaguely remember that Chrome did not act like this a few months ago. Is it because of the Chrome version?

The Chrome version of the above animation is 90.0.4430.212

So I found a Chrome version of 84.0.4109.0 for testing.

image-20210523200535044

Sure enough, it was a version issue, but it was still difficult to track things. I searched the specifications and checked some information on Google, which did not help me solve this doubt very well. I am not sure whether it is because of the bug introduced by Chrome or the appearance of the bug. what is the problem.

So I reported this problem to chromium.

image-20210523200757839

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

https://github.com/whatwg/dom/issues/685

image-20210523200912482

https://github.com/whatwg/dom/issues/746

image-20210523201105578

As you can see in the above issues, the cause is https://bugs.webkit.org/show_bug.cgi?id=174288 . Someone pointed out that the current event model in webkit will lead to the inclusion of Shadow DOM. Below, the capture event of the child element will be triggered prior to the capture event of the parent element.

image-20210523194802633

In the old model, once AT_TARGET is reached, all registered listeners will be triggered in order, regardless of whether they are marked as captured. Since Shadow DOM will create multiple targets, the sequence of events is incorrect.

However, the above problem works normally in Gecko (Mozilla Firefox's typesetting engine) (first capture and then bubbling). For this reason, whatwg proposes a new model structure to solve this problem.

image-20210523195228563

in conclusion

So far, all the questions have been solved, and now I will sort out our problems for us.

1. Follow the old version of the event trigger mechanism
which performedThe target element trigger event sequence is related to the registration event sequence
2. New event trigger mechanism
which performedThe target element trigger event sequence is triggered in the order of capturing first and then bubbling

The dividing line for this version is Chrome 89.0.4363.0 and 89.0.4358.0.

And Chrome 89.0.4363.0 was released on 2020-12-22, that is, in recent months, so if your Chrome is updated in recent months, you will encounter the same phenomenon as mine.

In Chrome 89.0.4363.0 and later versions, the trigger event sequence of the order of registration! is executed sequentially in the form of capturing first and then bubbling!

Then let's take a look at how this modification will affect us.

  1. First of all, we must make it clear that most of the previous articles on the Internet are no longer applicable to the current new version of Chrome!
  2. If there is a trigger sequence that depends on related events in our business, please check carefully!

Give me a 🌰

<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>

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

How to transform some online code changes at this stage?

improve proposals

So now we can't control which version of the browser users use, how can we solve this problem to avoid online problems?

it's actually really easy.

We only need to write the capture event code first and then write the bubbling event code in the order of all target element codes to be compatible with this update.

Thinking

All things are not static, whether it is for some relatively official articles or tutorials, we must be skeptical and believe what we see. Perhaps my remarks in this article will be a wrong example many years later, but it is a record of the current problem. This article also has many shortcomings, if you have any questions, please point out in the comments.

Reference

https://chromium.cypress.io/

https://github.com/whatwg/dom/issues/685

https://bugs.webkit.org/show_bug.cgi?id=174288

https://github.com/whatwg/dom/issues/746

https://dom.spec.whatwg.org/#dispatching-events

Conclusion

+ like + favorite + comment + forward , original is not easy, encourage the author to create better articles

Pay attention to the notes of the Autumn Wind, a front-end public account that focuses on front-end interviews, engineering, and open source


程序员秋风
3k 声望3.9k 粉丝

JavaScript开发爱好者,全栈工程师。