DEV Community

Cover image for Event Delegation - JavaScript
boibolang
boibolang

Posted on

Event Delegation - JavaScript

Event delegation dalam JavaScript adalah suatu teknik untuk menangani event bubbling lebih efisien ? Apa itu event bubbling ? Sebelum kesana kita perlu paham dulu mengenai event capturing, bubbling dan propagation. Bubbling dan capturing adalah 2 fase dari propagation. Sederhananya bubbling adalah DOM traversal dari target ke root, sedangkan capturing adalah kebalikannya yaitu DOM traversal dari root ke target. Target adalah elemen yang dikenakan event (children), root adalah induk (parent) dari elemen yang dikenakan event. Misal kita punya kode html seperti ini :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="styles.css" />
    <title>Event Delegation</title>
  </head>
  <body>
    <header>
      <ul>
        <li><a class="btn btnScroll1" href="#section-1">Section 1</a></li>
        <li><a class="btn btnScroll2" href="#section-2">Section 2</a></li>
        <li><a class="btn btnScroll3" href="#section-3">Section 3</a></li>
      </ul>
    </header>
    <section class="section" id="section-1">
      <p>This is section 1</p>
    </section>
    <section class="section" id="section-2">
      <p>This is section 2</p>
    </section>
    <section class="section" id="section-3">
      <p>This is section 3</p>
    </section>
    <script src="eventDel.js"></script>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

Jika kita mengaplikasikan click event misalnya kepada salah satu elemen button, maka gambarannya sebagai berikut :

result

Capturing sangat jarang digunakan sehingga kita akan fokus pada bubbling. Berikut kode JavaScript-nya :

'use strict';

const header = document.querySelector('header');
const button1 = document.querySelector('.btnScroll1');

function printHead() {
  console.log('header');
}
function printBtn() {
  console.log('button1');
}

button1.addEventListener('click', printBtn);
header.addEventListener('click', printHead);

Enter fullscreen mode Exit fullscreen mode

Apabila kita klik tombol Section 1 maka hasil di console sebagai berikut :

result

Terlihat bahwa sebenarnya eksekusi event handler 'click' tidak hanya pada target saja (button1), tapi juga pada parent element (header) sehingga muncul keduanya di console. Bagaimana caranya supaya event handler hanya mengeksekusi target saja ? Kita gunakan event.stopPropagation() untuk mencegah event bubbling ke parent element sebagai berikut :

function printBtn(event) {
  event.stopPropagation();
  console.log('button1');
}
Enter fullscreen mode Exit fullscreen mode

result

Terlihat bahwa console hanya menampilkan button1 dan tidak header. addEventListener sebenarnya memiliki 1 parameter terakhir selain event dan function yaitu bolean (tru/false). Parameter ini secara default bernilai false sehingga tidak perlu ditulis, jika diisi true maka akan mengaktifkan capturing phase dan menonaktifkan bubbling phase. Contohnya sebagai berikut :

function printHead() {
  console.log('header');
}
function printBtn() {
  console.log('button1');
}
button1.addEventListener('click', printBtn);
header.addEventListener('click', printHead, true);
Enter fullscreen mode Exit fullscreen mode

result

Terlihat bahwa header akan muncul pertama kali sebelum button1 di console, ini dikarenakan capturing phase dieksekusi pada header kemudian turun ke button1 (target).

Oke sekarang kita masuk ke event delegation, apa itu event delegation ? Jadi semisal kita punya banyak sekali tombol navigasi dalam suatu div, bagaimana kita mengakses dan mengeksekusi tombol-tombol tersebut ?

  1. Memakai perintah querySelectarAll() dan forEach seperti yang pernah kita lakukan pada contoh smooth scrolling. Cara ini efektif jika elemennya tidak banyak tapi akan sangat mempengaruhi performa jika elemennya terlalu banyak.
  2. Memakai event delegation, dengan cara menyeleksi parent element (root) dan memastikan elemen (tombol) yang dieksekusi serta meng-assign (delegate) perintah kepada masing-masing tombol.
// Event delegation
// Menambahkan event listener ke parent element
document.querySelector('header').addEventListener('click', function (e) {
  e.preventDefault();

  // Memastikan elemen yang dieksekusi dan meng-assign perintah
  if (e.target.classList.contains('btn')) {
    const id = e.target.getAttribute('href');
    document.querySelector(id).scrollIntoView({
      behaviour: 'smooth',
    });
  }
});
Enter fullscreen mode Exit fullscreen mode

Hasilnya sama dengan smooth scrolling seperti sebelumnya, namun kali ini dengan event delegation.

result

Top comments (0)