Events propagation trong Javascript [JAVASCRIPT]


Events propagation có 2 loại là bubbling và capturing.

Events Bubbling

Ta có ví dụ sau :

<div id='mydiv1'>
  <p id='myheader1'>Welcome to javascript</p>
</div>

<script>
  var myDiv1 = document.getElementById('mydiv1');
  myDiv1.addEventListener('click', runEvent);
  

  function runEvent(e){
    console.log(e.target); 
    // <p id='myheader1'>Welcome to javascript</p>

    console.log(e.currentTarget);
    
   // <div id='mydiv1'>
     // <p id='myheader1'>Welcome to javascript</p>.  
   // </div>
  }

</script>

Events Bubbling là khi ta click vào element con sẽ được lan ra element cha. Ta xem ví dụ trên. Ta add sự kiện vào div, khi click vào thẻ p thì e.target là thẻ p. còn e.currentTarget là thẻ div cha của p. Ta nhớ mở developer tool để xem log nhé. Firefox là F12.

Welcome to javascript

Nếu ta chỉ chạy sự kiện ở chỉ element mà ta click thôi, không chạy sự kiện ở element cha ta có dùng. e.stopPrapagation();

Ta thêm sự kiện vào thẻ p. Khi click vào p thì chỉ chạy sự kiện tại thẻ p. không chạy sự kiện tại div nên e.target và e.currentTarget đều là thẻ p.

<div id='mydiv2'>
  <p id='myheader2'>Welcome to javascript</p>
</div>

<script>
  var myDiv2 = document.getElementById('mydiv2');
  myDiv2.addEventListener('click', runEvent);
  

  var myHeader2 = document.getElementById('myheader2');
  myHeader2.addEventListener('click', runEvent);

  function runEvent(e){
    e.stopPropagation();
    console.log(e.target);
    // <p id='myheader2'>Welcome to javascript</p>
    
    console.log(e.currentTarget);
    // <p id='myheader2'>Welcome to javascript</p>
    
  }

</script>

Welcome to javascript

Events Capturing

Mặc định event là bubbling. Ta có thể chỉnh sang event capturing bằng cách thêm true vào tham số thứ 3 của aaddEventListener. Thì capturing sẽ đi từ element cha sang element con, ngược so với bubbling. Ta xem ví dụ sau:

<div id='mydiv3'>
  <p id='myheader3'>Welcome to javascript</p>
</div>

<script>
  var myDiv3 = document.getElementById('mydiv3');
  myDiv3.addEventListener('click', runEvent, true);
  

  var myHeader3 = document.getElementById('myheader3');
  myHeader3.addEventListener('click', runEvent);

  function runEvent(e){
    console.log(e.target);
    console.log(e.currentTarget);
  }

</script>

Welcome to javascript

Khi click vào "Welcome to javascript" thì sẽ log ra như sau:

<p id="myheader3">Welcome to javascript</p>
<div id="mydiv3">...</div>
<p id="myheader3">Welcome to javascript</p>
<p id="myheader3">Welcome to javascript</p>

dòng đầu là e.target của p. dòng 2 là e.currentTarget của div. 2 dòng sau là sự kiện đi vào bên trong thẻ p.

Tóm lại:

  1. Events Bubbling : đi từ element con ra element cha.
  2. Events Capturing: đi từ element cha xuống element con.

Ta thử áp dụng vào ví dụ sau. Khi Ta click vào chữ X thì sẽ thêm class completed, class này sẽ gạch ngang chữ. Khi click 1 lần nữa sẽ trở lại ban đầu.

<style>
  .completed {
    text-decoration: line-through;
  }
</style>

<ul id='list'>
  <li><a class='delete-item' >Item 1 <i>X</i></a> </li>
  <li><a class='delete-item' >Item 2 <i>X</i></a> </li>
  <li><a class='delete-item' >Item 3 <i>X</i></a> </li>
  <li><a class='delete-item' >Item 4 <i>X</i></a> </li>

</ul>

<script>
  var list = document.getElementById('list');
  list.addEventListener('click', runCode);

  function runCode(e){
    if (e.target.parentElement.classList.contains('delete-item')) {
       e.target.parentElement.parentElement.classList.toggle('completed');

    }
  }
</script>

Ở ví dụ này ta dùng Event bubbling. Ta add event vào ul. khi click vào thẻ i thì sẽ truy cập vào element cha là thẻ a xét coi trong classList có delete-item không, nếu có thì sẽ add class completed vào thẻ li.

Như vậy ta đã tìm hiểu xong Event Propagation trong javascript.