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.
Then let's take a look at the result
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.
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.
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.
Finally, with the help of Chrome developers, I found these two discussions
https://github.com/whatwg/dom/issues/685
https://github.com/whatwg/dom/issues/746
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.
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.
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 performed | The target element trigger event sequence is related to the registration event sequence |
2. New event trigger mechanism | |
which performed | The 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.
- 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!
- 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://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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。