search
HomeWeb Front-endJS TutorialAn introduction to JavaScript's event flow

An introduction to JavaScript's event flow

Free learning recommendation: js video tutorial

##About JavaScript event flow

##Foreword
  • Text
  • What is an event?
    • What Is it event streaming?
    • Event bubbling vs event capturing
    • DOM event hierarchy
    • DOM0 event
    • DOM2 event
    Conclusion
Preface

Before reading this article, I suggest you take a look at the JavaScript event loop. Of course, for those who already know it No need! This article will discuss the event flow of js.

Text

We all know that when we perform certain types of operations on a web page, such as clicking, sliding, etc., some corresponding events will be triggered. We also know that the entire web page is actually parsed into a DOM tree by the browser. When a node generates an event, the event will be propagated in a certain order between the node and the root node, and all nodes passing through this propagation path will receive the event. This entire process is called

DOM event flow

.

What are events?

The interaction between js and html is actually achieved through "events". All user clicks, selections, slides, etc. on web pages are all events in the js world.

For events, when an event occurs, there must be a response. In js, the so-called response is the listener. Just like the observer pattern, the event is our subject, and when the event occurs, all listeners corresponding to the event (subject) must be notified to perform corresponding responses.

What is event flow?

Event flow describes the order in which events are received from the page. Mainly divided into the following two types:

IE's event bubbling
  • Netscape's event capture
Event bubbling vs event capture

The event flow model proposed by IE is event bubbling, that is, from bottom to top, it propagates upward step by step from the element triggered by the target, all the way to the document object.


The event flow model proposed by Netscape is event capturing. Contrary to event bubbling, it is from top to bottom, that is, it is propagated from the document object to the target object step by step.


The above is the event flow mechanism under the DOM0 standard. Later, ECMAScript further standardized the event flow in DOM2. In DOM2, the event stream contained in an event is divided into the following three stages:

Event capture stage (capture)
  1. Target stage (target)
  2. Event bubbling stage (bubble)

DOM event classification

When an event occurs on a DOM node, of course you need to do the corresponding Department, and DOM events are divided into 4 levels, as follows:


Among them, the more important ones are DOM0/DOM2, so we will focus on them below.

DOM0 event

There are two main ways to implement DOM0-level events. The first is the inline model, which directly uses the function name as the event attribute in the html tag. attribute value. As follows:

// js code// eventDOM.jsfunction btnClick() {
    console.log('Hello World')}
<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p></p>
        <script></script>
    

However, the inline model has obvious shortcomings, that is, it violates the W3C requirement for the separation of content (html) and behavior (js). So there is the second type, which is the script model (dynamic binding model). The specific method is to select a specific DOM node through a js script, and then add event attributes and attribute values ​​to the node. As follows:

// js code// eventDOM.jslet btn = document.getElementById('btn')let btnClick = function() {
    console.log('Hello World')}btn.onclick = btnClick
<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p></p>
        <script></script>
    

Click and

Hello World

will appear, no problem. But the script model also has shortcomings. Based on the above html code, add a little js, as follows: <pre class="brush:php;toolbar:false">// js code// eventDOM.jslet btn = document.getElementById('btn')let btnClick = function() {     console.log('Hello World')}let btnClick2 = function() {     console.log('Hello World again')}btn.onclick = btnClick btn.onclick = btnClick2</pre>We found that now clicking only

Hello World again

will appear. Therefore, the script model only allows one node to add events of the same type once, and subsequent ones will overwrite the previous ones. Finally let us look at an interesting example:

<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p>
            btn3            </p><p>
                btn2                </p><p>
                    btn1                </p>
            
        
        <script></script>
    
// js code// eventDOM.jslet btn1 = document.getElementById('btn1')let btn2 = document.getElementById('btn2')let btn3 = document.getElementById('btn3')btn1.onclick = function() {
    console.log('1')}btn2.onclick = function() {
    console.log('2')}btn3.onclick = function() {
    console.log('3')}

When we click btn3, the output is as follows:

It is in line with expectations, but what if we click btn1? The output is as follows:

This is a bit strange, Obviously we only added one listener for btn1, why does it feel like we added it together with btn2 and btn3? ​​The reason is because, although DOM0 has two models: event bubbling proposed by IE and event capturing proposed by Netscape, in fact DOM0 only supports event bubbling. Therefore, the event flow of clicking btn1 is as follows:

That is, the event flow also passes through btn2 and btn3, so their event processing is triggered. But obviously, this is not the result we want.

DOM2 events

After further specification, there is a DOM2-level event handler. Two methods are defined:

  • addEventListener() Add event listener
  • removeEventListener() Remove event listener

These two functions There are three parameters in the following table:

##eventStringThe name of the event to be monitored, such as 'click'. Note that there is no need to "on" herecallbackfunctionThe callback function to be executed to trigger the eventuseCaptureBoolean(default:false)Whether the event is processed in the capture phase

DOM2 中就可以對同一個節點綁定兩個以上的同類型事件監聽器了,看看下面例子:

<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p></p>
        <script></script>
    
// js code// eventDOM.jslet btn = document.getElementById('btn')function hello() {
    console.log("Hello World")}function helloAgain() {
    console.log("Hello World again")}btn.addEventListener('click', hello, false)btn.addEventListener('click', helloAgain, false)

輸出如下:

解決了 DOM0 只能綁定一個同類型事件監聽器的缺點啦!值得注意的是,如果綁定同樣的監聽器兩次以上,仍然只會觸發一次。

再回到上面三個 p 的那個例子進行改寫如下:

<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p>
            btn3            </p><p>
                btn2                </p><p>
                    btn1                </p>
            
        
        <script></script>
    
// js code// eventDOM.jslet btn1 = document.getElementById('btn1')let btn2 = document.getElementById('btn2')let btn3 = document.getElementById('btn3')btn1.addEventListener('click', function() {
    console.log('1')}, true)btn2.addEventListener('click', function() {
    console.log('2')}, true)btn3.addEventListener('click', function() {
    console.log('3')}, true)

注意,這邊我們把 addEventListener 的第三個參數設為 true,也就是事件會在捕獲階段觸發。點擊 btn1 輸出如下:

看到順序與 DOM0 的順序反過來了。首先最外層(btn3)的節點先被觸發了,而因為第三個參數被設為 true,事件會在捕獲階段就被處理,所以輸出才會是 3,2,1。如果都是 false,就會是 1,2,3。

可見 DOM2 的事件處理機制有了更彈性的操作空間。我們也可以在不同階段綁定事件監聽器,看看下面例子:

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

改變一下順序,如下:

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)

點擊 btn1 輸出如下:

注意 btn1 的輸出。雖然捕獲階段先發生了,但是因為 btn1 本身就是目標節點,所以在這種情況下,總結出規律:在目標元素上不區分冒泡還是捕獲,是根據腳本中的順序來執行。

有時候,我們希望對於某節點,不要再經過冒泡階段了,DOM2 也提供了相應函數,stopPropagation

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function(e) {
    e.stopPropagation()
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

可以看到,因為我們在 btn2 的捕獲階段就阻止了 btn2 的冒泡階段,所以 btn2 在捕獲後就不再繼續執行下去,確保不會冒泡,事件流如下:

加強一下前面提到的知識點,如果是在 btn1 阻止冒泡,會變成怎樣呢?

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function(e) {
    e.stopPropagation()
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

雖然我們對 btn1 阻止了冒泡,但是為什麼還是輸出了 btn bubble呢?原因就是前面提到了,目標節點不區分 捕獲/冒泡 階段,但是後面也就不會繼續冒泡了,算是個比較特殊的情況,可以稍微留意下。

結語

本篇大致介紹了 js 的事件流的各種模型以及階段上的工作任務,個人認為應該還算詳細。雖然個人感覺好像對編程本身沒有太明顯的幫助,但是還是算是 js 的一個重要的知識點,學習下也沒甚麼不好。若內容有誤,還歡迎指點!

相关免费学习推荐:javascript(视频)

Parameter Type Description

The above is the detailed content of An introduction to JavaScript's event flow. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:CSDN. If there is any infringement, please contact admin@php.cn delete
Understanding the JavaScript Engine: Implementation DetailsUnderstanding the JavaScript Engine: Implementation DetailsApr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

From C/C   to JavaScript: How It All WorksFrom C/C to JavaScript: How It All WorksApr 14, 2025 am 12:05 AM

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment