+5

Event Propagation, Event delegation, bubbling và capturing là gì?

Không vòng vo đi thẳng vào vấn đề nhé

Khái niệm

  • Propagation (sự lan truyền)
  • Bubbling (nổi bọt) : ý chỉ sự đi từ bên dưới rễ lên gốc thân cây
  • Capturing : ý chỉ đi từ gốc thân cây xuống
  • Target : nơi phần tử DOM đăng kí 1 event (href, onclick, scroll,...)

Nhìn hình này là hiểu
alt

Event capturing

Khi ta tiến hành click thẻ a nó sẽ capturing từ thẻ cấp cao nhất đi xuống

  • Capturing : window -> document -> html -> body -> div#wrap -> p.hint -> a
  • Target : ở đây là href ='#'
  • Bubbling : nó đi ngược lại vs capturing

Flow hoạt động như sau khi có 1 event - đa phần trường hợp : Capturing > target > bubbling

Event Delegation

Delegation (sự ủy quyền) tức là khi ta tạo 1 sự kiện cho class cha, thì các class con bên trong cũng nhận được event đó.

<ul id="taskList"> 
  <li class="1">Task 1</li>
  <li class="2">Task 2</li>
  <li class="3">Task 3</li>
</ul>

Ta tiến hành gắn sự kiện cho taskList

document.getElementById('taskList').addEventListener('click', function(event) {
  if (event.target.tagName === 'LI') { 
    console.log(event.target.classList.value)
    // Handle the click event on a list item 
    // event.target.classList.toggle('completed');
  }
});

Lười thì vô đây copy paste code cho nhanh, cái này nó có nhắc lệnh gõ sướng, gõ clg ra console.log(), gõ div ra full syntax, nhưng mà gõ nhiều nó bảo thêm tiền đi em iu : https://playcode.io/new

Khi ta click li nào thì nó console.log ra cái class tương ứng đó. Sự ủy quyền - delegation (từ cha sang con) ở đây tức là ta chỉ cần gắn 1 event cho thẻ cha. Cho dù có bao nhiêu thẻ li bên trong thì vẫn nhận được sự kiện này.

Event Bubbling

Ví dụ 1 : Có code như sau
 <form onclick="alert('form')">
    form tag
    <div onclick="alert('div')">
      div tag
      <p onclick="alert('p')">
        p tag
      </p>
    </div>
  </form>

Khi ta tiến hành click thẻ p nó sẽ alert ra tất cả p > div > form

Khi ta tiến hành click thẻ div nó sẽ alert ra tất cả div > form. Rồi xong dễ hiểu chứ.

Click vào con đồng nghĩa với việc bạn cũng click vào phần tử cha !!!

Ví dụ 2 :
 <div class="1">
    div 1
    <div class="2">
      div 2
      <div class="3">
        div 3
      </div>
    </div>
  </div>
const divs = document.querySelectorAll('div');  // dom hết thẻ div
function logClassName(event) {
  console.log(this.classList.value); // log class ra
}
divs.forEach(div => div.addEventListener('click', logClassName));

Khi ta click vào div3 nó log ra 3 -> 2 -> 1 y như thằng trên thôi.

event.stopPropagation - stop bubbling

const divs = document.querySelectorAll('div');
 function logClassName(event) {
     event.stopPropagation();  // ngăn việc cá hồi bơi ngược dòng
     console.log(this.classList.value);
 }
 divs.forEach(div => div.addEventListener('click', logClassName));

Giờ click div nào nó sẽ chỉ log ra cái class của div đó thôi hết !!!

Tổng kết

Đó là gần như là tất cả về Propagation trong js. Chúc bro có 1 ngày làm việc vui vẻ và tốt lành.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí