Capturing và bubbling Event trong Javascript
Trong JavaScript, sự kiện có thể lan truyền qua các phần tử theo hai cách chính: Bubbling và Capturing. Đồng thời, ta cũng có thể sử dụng event.target để xác định phần tử đã kích hoạt sự kiện. Trong bài viết này, mình sẽ tìm hiểu cách sử dụng và kiểm soát Bubbling
, Capturing
và event.target
, kèm theo ví dụ minh họa.
Bubbling trong JavaScript
Bubbling là quá trình khi một sự kiện được kích hoạt trên một phần tử con, nó sẽ lan truyền lên các phần tử cha của nó. Điều này có nghĩa là các xử lý sự kiện được gọi trên các phần tử cha sau khi nó được gọi trên phần tử con.
Ví dụ:
<!DOCTYPE html> <html> <head> <title>Bubbling Event Example</title> </head> <body> <div id="outer"> <div id="inner"> Click me! </div> </div> <script> document.getElementById('outer').addEventListener('click', function() { console.log('Outer div clicked - Bubbling'); }); document.getElementById('inner').addEventListener('click', function() { console.log('Inner div clicked - Bubbling'); }); </script> </body> </html>
Khi bạn nhấp vào phần tử "inner", sự kiện sẽ lan truyền từ phần tử "inner" lên phần tử "outer", kết quả được ghi vào console:
Bài viết này được đăng tại [free tuts .net]
event.target
Trong quá trình xử lý sự kiện, event.target
là phần tử mà sự kiện đang xảy ra trên. Điều này cho phép mình xác định chính xác phần tử đã kích hoạt sự kiện.
Ví dụ:
<!DOCTYPE html> <html> <head> <title>Event.target Example</title> </head> <body> <ul id="myList"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <script> document.getElementById('myList').addEventListener('click', function(event) { console.log('Clicked on ' + event.target.textContent); }); </script> </body> </html>
Khi bạn nhấp vào một mục trong danh sách, event.target
sẽ là phần tử li mà bạn đã nhấp vào, và nó sẽ được ghi vào console:
Stopping Bubbling
Đôi khi, mình có thể muốn ngăn chặn sự kiện lan truyền (bubbling) từ phần tử con lên phần tử cha. Điều này có thể được thực hiện bằng cách sử dụng phương thức stopPropagation()
trên đối tượng sự kiện.
Ví dụ:
<!DOCTYPE html> <html> <head> <title>Stopping Bubbling Example</title> </head> <body> <div id="outer"> <div id="inner"> Click me! </div> </div> <script> document.getElementById('outer').addEventListener('click', function() { console.log('Outer div clicked'); }); document.getElementById('inner').addEventListener('click', function(event) { console.log('Inner div clicked'); event.stopPropagation(); // Ngăn chặn sự kiện lan truyền lên phần tử cha }); </script> </body> </html>
Khi bạn nhấp vào phần tử "inner", sự kiện sẽ chỉ được ghi vào console là "Inner div clicked", và không có ghi nhận về phần tử "outer".
Capturing trong JavaScript
Trái ngược với Bubbling, Capturing là quá trình khi một sự kiện được kích hoạt trên một phần tử cha, nó sẽ lan truyền xuống các phần tử con của nó trước khi đến phần tử mục tiêu.
Ví dụ:
<!DOCTYPE html> <html> <head> <title>Capturing Event Example</title> </head> <body> <div id="outer"> <div id="inner"> Click me! </div> </div> <script> document.getElementById('outer').addEventListener('click', function() { console.log('Outer div clicked - Capturing'); }, true); document.getElementById('inner').addEventListener('click', function() { console.log('Inner div clicked - Capturing'); }, true); </script> </body> </html>
Khi bạn nhấp vào phần tử "inner", các xử lý sự kiện sẽ được gọi trước trên phần tử "outer", sau đó mới đến phần tử "inner". Điều này được ghi vào console:
Làm thế nào để chặn Capturing và Bubbling trong JavaScript?
Chặn Capturing trong JavaScript
- Để chặn capturing, mình có thể sử dụng phương thức
addEventListener()
với tham số thứ ba được đặt là true. Khi tham số này được đặt là true, sự kiện sẽ được xử lý trong quá trình capturing. - Để chặn capturing, mình có thể sử dụng phương thức
event.stopPropagation()
trong hàm xử lý sự kiện của phần tử con. Điều này sẽ ngăn chặn sự kiện lan truyền từ phần tử cha xuống phần tử con.
Ví dụ:
Trong ví dụ này, mình sẽ có một phần tử cha và một phần tử con. Khi nhấp vào phần tử con, sự kiện sẽ bắt đầu từ phần tử cha (capturing) và sau đó đến phần tử con. Tuy nhiên, mình sẽ chặn capturing để không in ra thông báo từ phần tử cha.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Capturing Example</title> </head> <body> <div id="parent"> <button id="child">Click me</button> </div> <script> document.getElementById('parent').addEventListener('click', function() { console.log('Parent clicked - Capturing'); }, true); document.getElementById('child').addEventListener('click', function(event) { event.stopPropagation(); // Chặn capturing console.log('Child clicked'); }); </script> </body> </html>
Khi bạn nhấp vào nút "Click me", chỉ có thông báo "Child clicked" được in ra, và thông báo "Parent clicked - Capturing" không xuất hiện.
Chặn Bubbling trong JavaScript
- Để chặn bubbling, mình cũng có thể sử dụng phương thức
event.stopPropagation()
trong hàm xử lý sự kiện của phần tử con. Điều này sẽ ngăn chặn sự kiện lan truyền từ phần tử con lên phần tử cha. - Bên cạnh đó, mình cũng có thể sử dụng phương thức
event.stopImmediatePropagation()
để không chỉ ngăn chặn sự kiện hiện tại lan truyền lên phần tử cha, mà còn ngăn chặn bất kỳ sự kiện bubbling nào khác trên phần tử đó.
Ví dụ:
Trong ví dụ này, mình có cùng cấu trúc với ví dụ trước, nhưng lần này mình sẽ chặn bubbling để không in ra thông báo từ phần tử cha.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Bubbling Example</title> </head> <body> <div id="parent"> <button id="child">Click me</button> </div> <script> document.getElementById('parent').addEventListener('click', function() { console.log('Parent clicked'); }); document.getElementById('child').addEventListener('click', function(event) { event.stopPropagation(); // Chặn bubbling console.log('Child clicked'); }); </script> </body> </html>
Khi bạn nhấp vào nút "Click me", chỉ có thông báo "Child clicked" được in ra, và thông báo "Parent clicked" không xuất hiện.
Việc hiểu và quản lý capturing và bubbling trong JavaScript là quan trọng để kiểm soát hành vi của ứng dụng trong việc xử lý sự kiện.
Kết bài
Bubbling, Capturing và event.target là các khái niệm quan trọng trong xử lý sự kiện trong JavaScript. Hiểu và sử dụng chúng sẽ giúp bạn kiểm soát sự kiện trong ứng dụng web của mình một cách hiệu quả.