Cara menggunakan delegasi objek dalam javascript

Sebelum mempelajari Delegasi Acara di JavaScript, kita harus terbiasa dengan fase https acara JavaScript. // www. geeksforgeeks. org/fase-of-javascript-event/

Show

    Delegasi Acara pada dasarnya adalah pola untuk menangani acara secara efisien. Alih-alih menambahkan pendengar acara ke setiap elemen serupa, kita dapat menambahkan pendengar acara ke elemen induk dan memanggil acara pada target tertentu menggunakan. properti target dari objek acara

    Mari kita lihat contoh dengan dan tanpa delegasi acara

    const customUI = document.createElement('ul');
    
    for (var i = 1; i <= 10; i++) {
        const newElement = document.createElement('li');
        newElement.textContent = "This is line " + i;
        newElement.addEventListener('click', () => {
            console.log('Responding')
        })
        customUI.appendChild(newElement);
    }
    

    The above code will associate the function with every

  • element that is shown in the below image. We are creating an
      element, attaching too many
    • elements, and attaching an event listener with a responding function to each paragraph as we create it.

      Cara menggunakan delegasi objek dalam javascript

      Tanpa Delegasi Acara

      Menerapkan fungsi yang sama dengan pendekatan alternatif. Dalam pendekatan ini, kami akan mengaitkan fungsi yang sama dengan semua event listener. Kami membuat terlalu banyak fungsi respons (semuanya benar-benar melakukan hal yang persis sama). Kita dapat mengekstrak fungsi ini dan hanya mereferensikan fungsi tersebut alih-alih membuat terlalu banyak fungsi

      const customUI = document.createElement('ul');
      
      function responding() {
          console.log('Responding')
      }
      
      for (var i = 1; i <= 10; i++) {
          const newElement = document.createElement('li');
          newElement.textContent = "This is line " + i;
          newElement.addEventListener('click', responding)
          customUI.appendChild(newElement);
      }
      
      _

      Fungsi kode di atas ditunjukkan di bawah ini –

      Cara menggunakan delegasi objek dalam javascript

      Tanpa Delegasi Acara

      Dalam pendekatan di atas, kita masih memiliki terlalu banyak event listener yang mengarah ke fungsi yang sama. Sekarang menerapkan fungsi yang sama menggunakan satu fungsi dan satu acara

      const customUI = document.createElement('ul');
      
      function responding() {
          console.log('Responding')
      }
      
      for (var i = 1; i <= 10; i++) {
          const newElement = document.createElement('li');
          newElement.textContent = "This is line " + i;
          customUI.appendChild(newElement);
      }
      customUI.addEventListener('click', responding)
      

      Cara menggunakan delegasi objek dalam javascript

      Now there is a single event listener and a single responding function. In the above-shown method, we have improved the performance, but we have lost access to individual

    • elements so to resolve this issue, we will use a technique called event delegation. 

      The event object has a special property call .target which will help us in getting access to individual

    • elements with the help of phases.

      Langkah

        • element is clicked.
        • Acara berlangsung dalam fase penangkapan
        • It reaches the target (
        • in our case).
        • Ini beralih ke fase menggelegak
        • When it hits the
            element, it runs the event listener.
          • Di dalam acara fungsi pendengar. target adalah elemen yang diklik
          • Event.target provides us access to the
          • element that was clicked.

          Itu. properti nodeName dari. target memungkinkan kita untuk mengidentifikasi node tertentu. Jika elemen induk kita mengandung lebih dari satu elemen anak maka kita dapat mengidentifikasi elemen tertentu dengan menggunakan. properti nodeName

          Menangkap dan menggelegak memungkinkan kita untuk mengimplementasikan salah satu pola penanganan peristiwa paling kuat yang disebut delegasi peristiwa

          Idenya adalah jika kita memiliki banyak elemen yang ditangani dengan cara yang sama, maka alih-alih menugaskan penangan untuk masing-masing elemen – kita menempatkan satu penangan pada leluhur bersama mereka

          Di handler kita mendapatkan event.target untuk melihat di mana peristiwa itu sebenarnya terjadi dan menanganinya

          Mari kita lihat sebuah contoh – diagram Ba-Gua yang mencerminkan filosofi Tiongkok kuno

          Ini dia

          HTMLnya seperti ini

          <table>
            <tr>
              <th colspan="3"><em>Bagua</em> Chart: Direction, Element, Color, Meaning</th>
            </tr>
            <tr>
              <td class="nw"><strong>Northwest</strong><br>Metal<br>Silver<br>Elders</td>
              <td class="n">...</td>
              <td class="ne">...</td>
            </tr>
            <tr>...2 more lines of this kind...</tr>
            <tr>...2 more lines of this kind...</tr>
          </table>

          Tabel memiliki 9 sel, tetapi mungkin ada 99 atau 9999, tidak masalah

          Tugas kita adalah menyorot sel <td> saat diklik

          Alih-alih menetapkan penangan

          let selectedTd;
          
          table.onclick = function(event) {
            let target = event.target; // where was the click?
          
            if (target.tagName != 'TD') return; // not on TD? Then we're not interested
          
            highlight(target); // highlight it
          };
          
          function highlight(td) {
            if (selectedTd) { // remove the existing highlight if any
              selectedTd.classList.remove('highlight');
            }
            selectedTd = td;
            selectedTd.classList.add('highlight'); // highlight the new td
          }
          0 untuk setiap <td> (bisa banyak) – kita akan menyiapkan penangan "catch-all" pada elemen
          let selectedTd;
          
          table.onclick = function(event) {
            let target = event.target; // where was the click?
          
            if (target.tagName != 'TD') return; // not on TD? Then we're not interested
          
            highlight(target); // highlight it
          };
          
          function highlight(td) {
            if (selectedTd) { // remove the existing highlight if any
              selectedTd.classList.remove('highlight');
            }
            selectedTd = td;
            selectedTd.classList.add('highlight'); // highlight the new td
          }
          2

          Ini akan menggunakan event.target untuk mendapatkan elemen yang diklik dan menyorotnya

          Kode

          let selectedTd;
          
          table.onclick = function(event) {
            let target = event.target; // where was the click?
          
            if (target.tagName != 'TD') return; // not on TD? Then we're not interested
          
            highlight(target); // highlight it
          };
          
          function highlight(td) {
            if (selectedTd) { // remove the existing highlight if any
              selectedTd.classList.remove('highlight');
            }
            selectedTd = td;
            selectedTd.classList.add('highlight'); // highlight the new td
          }
          _

          Kode seperti itu tidak peduli berapa banyak sel yang ada di tabel. Kami dapat menambah/menghapus <td> secara dinamis kapan saja dan penyorotan akan tetap berfungsi

          Tetap saja, ada kekurangannya

          Klik mungkin terjadi bukan pada ________42______, tetapi di dalamnya

          Dalam kasus kami, jika kami melihat ke dalam HTML, kami dapat melihat tag bersarang di dalam <td>, seperti

          let selectedTd;
          
          table.onclick = function(event) {
            let target = event.target; // where was the click?
          
            if (target.tagName != 'TD') return; // not on TD? Then we're not interested
          
            highlight(target); // highlight it
          };
          
          function highlight(td) {
            if (selectedTd) { // remove the existing highlight if any
              selectedTd.classList.remove('highlight');
            }
            selectedTd = td;
            selectedTd.classList.add('highlight'); // highlight the new td
          }
          7

          <td>
            <strong>Northwest</strong>
            ...
          </td>
          _

          Secara alami, jika klik terjadi pada

          let selectedTd;
          
          table.onclick = function(event) {
            let target = event.target; // where was the click?
          
            if (target.tagName != 'TD') return; // not on TD? Then we're not interested
          
            highlight(target); // highlight it
          };
          
          function highlight(td) {
            if (selectedTd) { // remove the existing highlight if any
              selectedTd.classList.remove('highlight');
            }
            selectedTd = td;
            selectedTd.classList.add('highlight'); // highlight the new td
          }
          _7 itu, maka itu menjadi nilai event.target

          Di handler

          <td>
            <strong>Northwest</strong>
            ...
          </td>
          0 kita harus mengambil event.target tersebut dan mencari tahu apakah klik itu ada di dalam <td> atau tidak

          Berikut kode yang ditingkatkan

          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };

          Penjelasan

          1. Metode
            <td>
              <strong>Northwest</strong>
              ...
            </td>
            _3 mengembalikan leluhur terdekat yang cocok dengan pemilih. Dalam kasus kami, kami mencari <td> dalam perjalanan naik dari elemen sumber
          2. Jika event.target tidak ada di dalam <td>, maka panggilan akan segera kembali, karena tidak ada hubungannya
          3. Dalam kasus tabel bersarang, event.target mungkin <td>, tetapi terletak di luar tabel saat ini. Jadi kami memeriksa apakah itu benar-benar <td> meja kami
          4. Dan, jika demikian, maka sorot

          Hasilnya, kami memiliki kode penyorotan yang cepat dan efisien, yang tidak peduli dengan jumlah total <td> dalam tabel

          Ada kegunaan lain untuk delegasi acara

          Katakanlah kita ingin membuat menu dengan tombol "Simpan", "Muat", "Cari", dan seterusnya. Dan ada objek dengan metode

          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          1,
          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          2,
          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          3… Bagaimana cara mencocokkannya?

          Ide pertama mungkin untuk menetapkan penangan terpisah untuk setiap tombol. Tapi ada solusi yang lebih elegan. Kita dapat menambahkan handler untuk seluruh menu dan

          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          4 atribut untuk tombol yang memiliki metode untuk memanggil

          <button data-action="save">Click to Save</button>

          Handler membaca atribut dan mengeksekusi metode. Lihatlah contoh kerja

          <div id="menu">
            <button data-action="save">Save</button>
            <button data-action="load">Load</button>
            <button data-action="search">Search</button>
          </div>
          
          <script>
            class Menu {
              constructor(elem) {
                this._elem = elem;
                elem.onclick = this.onClick.bind(this); // (*)
              }
          
              save() {
                alert('saving');
              }
          
              load() {
                alert('loading');
              }
          
              search() {
                alert('searching');
              }
          
              onClick(event) {
                let action = event.target.dataset.action;
                if (action) {
                  this[action]();
                }
              };
            }
          
            new Menu(menu);
          </script>

          Perhatikan bahwa

          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          _5 terikat dengan
          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          6 di
          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          7. Itu penting, karena jika tidak
          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          _6 di dalamnya akan mereferensikan elemen DOM (
          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          9), bukan objek
          <button data-action="save">Click to Save</button>
          0, dan
          <button data-action="save">Click to Save</button>
          1 tidak akan menjadi yang kita butuhkan

          Jadi, keuntungan apa yang diberikan delegasi kepada kita di sini?

          • Kita tidak perlu menulis kode untuk menetapkan handler ke setiap tombol. Buat saja metode dan taruh di markup
          • Struktur HTML fleksibel, kita dapat menambah/menghapus tombol kapan saja

          Kita juga bisa menggunakan kelas

          <button data-action="save">Click to Save</button>
          _2,
          <button data-action="save">Click to Save</button>
          3, tetapi atribut
          table.onclick = function(event) {
            let td = event.target.closest('td'); // (1)
          
            if (!td) return; // (2)
          
            if (!table.contains(td)) return; // (3)
          
            highlight(td); // (4)
          };
          4 lebih baik secara semantik. Dan kita juga bisa menggunakannya dalam aturan CSS

          Kita juga dapat menggunakan delegasi acara untuk menambahkan "perilaku" ke elemen secara deklaratif, dengan atribut dan kelas khusus

          Polanya memiliki dua bagian

          1. Kami menambahkan atribut khusus ke elemen yang menjelaskan perilakunya
          2. Penangan sepanjang dokumen melacak peristiwa, dan jika suatu peristiwa terjadi pada elemen yang dikaitkan – melakukan tindakan

          Misalnya, di sini atribut

          <button data-action="save">Click to Save</button>
          _5 menambahkan perilaku. "tingkatkan nilai saat klik" ke tombol

          Counter: <input type="button" value="1" data-counter>
          One more counter: <input type="button" value="2" data-counter>
          
          <script>
            document.addEventListener('click', function(event) {
          
              if (event.target.dataset.counter != undefined) { // if the attribute exists...
                event.target.value++;
              }
          
            });
          </script>

          Jika kita mengklik tombol – nilainya meningkat. Bukan tombol, tetapi pendekatan umum penting di sini

          Ada banyak atribut dengan

          <button data-action="save">Click to Save</button>
          5 seperti yang kita inginkan. Kami dapat menambahkan yang baru ke HTML kapan saja. Menggunakan delegasi acara, kami "memperluas" HTML, menambahkan atribut yang menjelaskan perilaku baru

          Untuk penangan tingkat dokumen – selalu

          <button data-action="save">Click to Save</button>
          7

          Saat kita menugaskan event handler ke objek

          <button data-action="save">Click to Save</button>
          8, kita harus selalu menggunakan
          <button data-action="save">Click to Save</button>
          7, bukan
          <div id="menu">
            <button data-action="save">Save</button>
            <button data-action="load">Load</button>
            <button data-action="search">Search</button>
          </div>
          
          <script>
            class Menu {
              constructor(elem) {
                this._elem = elem;
                elem.onclick = this.onClick.bind(this); // (*)
              }
          
              save() {
                alert('saving');
              }
          
              load() {
                alert('loading');
              }
          
              search() {
                alert('searching');
              }
          
              onClick(event) {
                let action = event.target.dataset.action;
                if (action) {
                  this[action]();
                }
              };
            }
          
            new Menu(menu);
          </script>
          0, karena yang terakhir akan menyebabkan konflik. penangan baru menimpa yang lama

          Untuk proyek nyata, normal jika ada banyak penangan pada

          <button data-action="save">Click to Save</button>
          8 yang diatur oleh berbagai bagian kode

          Satu lagi contoh perilaku. Klik pada elemen dengan atribut

          <div id="menu">
            <button data-action="save">Save</button>
            <button data-action="load">Load</button>
            <button data-action="search">Search</button>
          </div>
          
          <script>
            class Menu {
              constructor(elem) {
                this._elem = elem;
                elem.onclick = this.onClick.bind(this); // (*)
              }
          
              save() {
                alert('saving');
              }
          
              load() {
                alert('loading');
              }
          
              search() {
                alert('searching');
              }
          
              onClick(event) {
                let action = event.target.dataset.action;
                if (action) {
                  this[action]();
                }
              };
            }
          
            new Menu(menu);
          </script>
          2 akan menampilkan/menyembunyikan elemen dengan
          <div id="menu">
            <button data-action="save">Save</button>
            <button data-action="load">Load</button>
            <button data-action="search">Search</button>
          </div>
          
          <script>
            class Menu {
              constructor(elem) {
                this._elem = elem;
                elem.onclick = this.onClick.bind(this); // (*)
              }
          
              save() {
                alert('saving');
              }
          
              load() {
                alert('loading');
              }
          
              search() {
                alert('searching');
              }
          
              onClick(event) {
                let action = event.target.dataset.action;
                if (action) {
                  this[action]();
                }
              };
            }
          
            new Menu(menu);
          </script>
          3 yang diberikan

          <button data-toggle-id="subscribe-mail">
            Show the subscription form
          </button>
          
          <form id="subscribe-mail" hidden>
            Your mail: <input type="email">
          </form>
          
          <script>
            document.addEventListener('click', function(event) {
              let id = event.target.dataset.toggleId;
              if (!id) return;
          
              let elem = document.getElementById(id);
          
              elem.hidden = !elem.hidden;
            });
          </script>

          Mari kita catat sekali lagi apa yang kita lakukan. Sekarang, untuk menambahkan fungsionalitas toggling ke elemen – ​​tidak perlu mengetahui JavaScript, cukup gunakan atribut

          <div id="menu">
            <button data-action="save">Save</button>
            <button data-action="load">Load</button>
            <button data-action="search">Search</button>
          </div>
          
          <script>
            class Menu {
              constructor(elem) {
                this._elem = elem;
                elem.onclick = this.onClick.bind(this); // (*)
              }
          
              save() {
                alert('saving');
              }
          
              load() {
                alert('loading');
              }
          
              search() {
                alert('searching');
              }
          
              onClick(event) {
                let action = event.target.dataset.action;
                if (action) {
                  this[action]();
                }
              };
            }
          
            new Menu(menu);
          </script>
          2

          Itu mungkin menjadi sangat nyaman – tidak perlu menulis JavaScript untuk setiap elemen tersebut. Hanya menggunakan perilaku. Penangan tingkat dokumen membuatnya berfungsi untuk semua elemen halaman