Menjinakkan JavaScript di Drupal (Termasuk FAQ)

Diterbitkan: 2023-02-07

Pengalaman web interaktif memberikan pengalaman yang lebih menarik dan menyenangkan bagi pengguna. Ini mengarah pada peningkatan kepuasan pengguna dan persepsi positif tentang situs web. Misalnya, formulir yang memberikan umpan balik dan validasi instan, alih-alih membuat pengguna menunggu penyegaran halaman, dapat meningkatkan pengalaman pengguna secara signifikan.

JavaScript memainkan peran penting dalam Drupal dengan menyediakan sarana untuk menciptakan pengalaman yang dinamis dan interaktif bagi pengguna di bagian depan situs web Drupal. Ini memungkinkan pengembang untuk mengubah perilaku elemen tertentu pada halaman, seperti formulir, tautan, atau elemen DOM lainnya, tanpa harus me-refresh seluruh halaman. Perilaku Drupal adalah fungsi JavaScript yang dijalankan saat peristiwa tertentu terjadi di halaman. Perilaku memudahkan pengembang untuk memelihara dan memutakhirkan situs karena mereka tidak perlu mengubah kode HTML yang mendasarinya. Cari tahu semua yang ingin Anda ketahui tentang Perilaku Drupal di artikel.

Menjinakkan JavaScript di Drupal

Apa itu Perilaku Drupal?

Drupal.behaviors adalah objek di dalam struktur Javascript di Drupal, yang memungkinkan kita melampirkan fungsi untuk dieksekusi pada waktu tertentu selama eksekusi aplikasi. Ini dipanggil saat DOM dimuat penuh, tetapi perilaku ini bisa dipanggil lagi. Dokumentasi JavaScript resmi Drupal menunjukkan bahwa modul harus mengimplementasikan JavaScript dengan melampirkan logika ke Drupal.behaviors .

Mengapa kita membutuhkan perilaku Drupal?

Keuntungan dari Behaviors adalah mereka secara otomatis diterapkan kembali ke konten apa pun yang dimuat melalui AJAX. Mereka dapat dipanggil kapan saja dengan konteks yang mewakili penambahan atau perubahan baru pada DOM. Ini lebih baik daripada $(document).ready() atau document DOMContentLoaded di mana kode hanya dijalankan sekali.

Kapan perilaku Drupal tidak diinginkan?

Perilaku Drupal tidak selalu merupakan solusi sempurna untuk menulis Javascript di Drupal. Dalam beberapa kasus, seperti yang dinyatakan di bawah perilaku Drupal tidak diperlukan sama sekali!

  • Saat kita perlu mengeksekusi beberapa kode yang tidak memengaruhi DOM. Misalnya. Menginisialisasi skrip eksternal seperti Google Analytics
  • Ketika beberapa operasi JS perlu dilakukan pada DOM sekali saja mengetahui bahwa elemen akan tersedia saat halaman dimuat (Skenario ini berbeda dengan menggunakan Once).

Kapan Perilaku Drupal dipanggil?

  • Setelah overlay administrasi telah dimuat ke dalam halaman.
  • Setelah AJAX Form API mengirimkan formulir.
  • Saat permintaan AJAX mengembalikan perintah yang mengubah HTML, seperti ajax_command_replace() .

Di lain waktu ketika Perilaku Drupal dipanggil

  • CTools memanggilnya setelah modal dimuat.
  • Media memanggilnya setelah browser media dimuat.
  • Panels memanggilnya setelah pengeditan di tempat selesai.
  • Views memanggilnya setelah memuat halaman baru yang menggunakan AJAX.
  • Views Load More memanggilnya setelah memuat potongan item berikutnya.
  • JavaScript dari modul khusus dapat memanggil Drupal.attachBehaviors() saat mereka menambah atau mengubah bagian halaman.

Menulis kode tanpa perilaku Drupal

Dalam kode ini, kami menambahkan click event listener ke kelas .views-row yang menghitung berapa kali kami mengklik baris ini. Tapi itu ditambahkan hanya sekali ke elemen yang ada di DOM selama pemuatan halaman awal. Setelah mengklik Muat Lebih Banyak dan memuat lebih banyak item, pendengar klik tidak berfungsi pada item yang baru dimuat.

 // No Drupal Behaviors (function () { let header = document.querySelector(".food-list-header"); if (header) { let greatFoodSpan = document.createElement("span"); greatFoodSpan.textContent = "Get ready for great food!!!!!!"; header.append(greatFoodSpan); } // Add the event listener for each click on the food let foods = document.querySelectorAll(".views-row"); foods.forEach((food) => { food.addEventListener("click", () => { let foodCounter = food.querySelector(".food-click-counter"); let timesClicked = parseInt(foodCounter.textContent.trim()); foodCounter.textContent = ++timesClicked; }); }); })(); 
pendengar acara

Bagaimana kita menggunakan Perilaku Drupal?

Jawab: Menggunakan metode attach

Hal-hal untuk diingat:

  • Objek baru harus memiliki setidaknya metode attach.
  • Setiap kali Drupal.attachBehaviors dipanggil, Drupal.attachBehaviors akan melakukan iterasi melalui semua objek perilaku dan memanggil metode attach masing-masing.

Menambahkan perilaku Drupal ke kode kita

Setelah menambahkan Perilaku Drupal, kodenya terlihat seperti ini.

 (function (Drupal) { Drupal.behaviors.exampleBehaviour1 = { attach: (context, settings) => { // Add a delicious text to the top of the document let header = document.querySelector(".food-list-header"); // jQuery Equivalent // $(".food-list-header"); if (header) { let greatFoodSpan = document.createElement("span"); greatFoodSpan.textContent = "Get ready for great food!!!!!!"; header.append(greatFoodSpan); } // Add the event listener for each click on the food let foods = document.querySelectorAll(".views-row"); foods.forEach((food) => { food.addEventListener("click", () => { let foodCounter = food.querySelector(".food-click-counter"); let timesClicked = parseInt(foodCounter.textContent.trim()); foodCounter.textContent = ++timesClicked; }); }); }, }; })(Drupal);

Tapi sesuatu yang aneh muncul di atas ketika kita mengklik Load More:

perilaku

Ini karena perilaku Drupal dipanggil berkali-kali dan selanjutnya kami mendapatkan beberapa perilaku yang tidak diinginkan.

Apa itu Konteks dalam "konteks Drupal"?

  • Saat memanggil metode attach untuk semua perilaku, Drupal meneruskan parameter konteks .
  • Parameter konteks yang diteruskan seringkali dapat memberikan gambaran yang lebih baik tentang elemen DOM apa yang sedang diproses.
  • Selama pemuatan halaman awal, ini akan menjadi Dokumen HTML lengkap; selama panggilan berikutnya, ini hanya akan menjadi elemen yang ditambahkan ke halaman atau dimodifikasi.

Bagaimana cara menambahkan Konteks?

Masalah sebelumnya dapat diselesaikan dengan menggunakan parameter konteks yang disediakan oleh Drupal Behaviors. Dalam hal ini, pertama kali halaman dimuat, kami mendapatkan seluruh Dokumen HTML sebagai konteks dan saat itulah kami melampirkan tajuk. Untuk operasi lebih lanjut, itu akan menjadi bagian dari kode yang dipengaruhi oleh Perilaku Drupal dan karenanya bagian dari kode tersebut dikontrol dengan aman.

 (function (Drupal) { Drupal.behaviors.exampleBehaviour2 = { attach: (context, settings) => { // Add a delicious text to the top of the document. // The context parameter now can be used for adding // certain functionality which removes unwanted repeatability let header = context.querySelector(".food-list-header"); // jQuery Equivalent // $(".food-list-header", context); if (header) { let greatFoodSpan = document.createElement("span"); greatFoodSpan.textContent = "Get ready for great food!!!!!!"; header.append(greatFoodSpan); } // Add the event listener for each click on the food let foods = context.querySelectorAll(".views-row"); foods.forEach((food) => { food.addEventListener("click", () => { let foodCounter = food.querySelector(".food-click-counter"); let timesClicked = parseInt(foodCounter.textContent.trim()); foodCounter.textContent = ++timesClicked; }); }); }, }; })(Drupal);

Sekali lagi ada beberapa perilaku aneh saat kita mengklik Load More . Item makanan yang awalnya dimuat berfungsi dengan baik. Tapi Setelah mengklik Muat Lebih Banyak, item baru mendapatkan pendengar klik dan berfungsi normal. Tetapi item yang dimuat pertama kali membuat pendengar terpasang lagi dan mengekliknya akan memanggil acara klik lebih dari sekali!

Muat lebih banyak

Kapan Perilaku Drupal mulai berperilaku buruk?

  • Menulis semua pendengar acara di dalam perilaku Drupal tanpa menggunakan Sekali dan Konteks.
  • Mendeklarasikan fungsi yang tidak diinginkan di dalam perilaku Drupal yang mengarah ke deklarasi ulang fungsi setiap kali metode attach dipanggil.

"Sekali" untuk menyelamatkan

  • Once memastikan bahwa sesuatu diproses hanya sekali dengan menambahkan atribut data-once dalam elemen DOM setelah kode dieksekusi.
  • Jika perilaku dipanggil lagi, elemen dengan atribut data-once akan dilewati untuk eksekusi lebih lanjut.
  • Once adalah implementasi modern jQuery.once (yang merupakan upaya untuk menjauh dari jQuery)
  • Sekali, dalam kombinasi dengan konteks, mengontrol seluruh fungsionalitas dengan sempurna seperti yang kita butuhkan.

Menambahkan Sekali untuk memperbaiki pendengar acara dalam kode kami

 (function (Drupal, once) { Drupal.behaviors.exampleBehaviour3 = { attach: (context, settings) => { once("food-header-initialized", ".food-list-header", context).forEach( (header) => { let greatFoodSpan = document.createElement("span"); greatFoodSpan.textContent = "Get ready for great food!!!!!!"; header.append(greatFoodSpan); } ); // jQuery Equivalent // $(".food-list-header", context).once("food-header-initialized", function (header) { // // }); // Add the event listener for each click on the food once("food-initialized", ".views-row", context).forEach((food) => { food.addEventListener("click", () => { let foodCounter = food.querySelector(".food-click-counter"); let timesClicked = parseInt(foodCounter.textContent.trim()); foodCounter.textContent = ++timesClicked; }); }); }, }; })(Drupal, once);
data sekali

Sekarang semuanya berfungsi sebagaimana dimaksud. Kami mendapatkan atribut data-sekali ke elemen tempat pendengar acara dilampirkan dan elemen yang baru dimuat dan elemen yang dimuat sebelumnya berfungsi dengan baik.

Metode Kebutuhan untuk Melepaskan

Metode Detach bertindak seperti anti-hero (bukan jahat), menghilangkan apa pun yang kita lakukan dalam metode attach. Kode apa pun dalam metode detach akan dipanggil setiap kali konten dihapus dari DOM. Ini membantu kita untuk membersihkan aplikasi kita. Misalnya, metode Detach memungkinkan kita menghapus event listener yang tidak diinginkan yang menghabiskan sumber daya seperti situasi polling yang berkelanjutan.

Contoh Detasemen

Asumsikan bahwa kita memiliki formulir ajax untuk diisi dan kita menggunakan pengatur waktu untuk menunjukkan waktu yang telah berlalu. Kami menggunakan setTimeOut untuk mengatur timer. Kami mencatat penghitung waktu ini di konsol untuk pemantauan.

 (function (Drupal, once) { let counter = 0; Drupal.behaviors.exampleBehaviour4 = { attach: (context, settings) => { once("timer-initalized", ".contact-timer", context).forEach((ele) => { const timer = context.querySelector(".contact-timer-sec"); timer.textContent = counter; // Set the timer for user to see the time elapsed setInterval(() => { console.log("This is logging"); const timer = document.querySelector(".contact-timer-sec"); timer.textContent = ++counter; }, 1000); }); }, }; })(Drupal, once);
mengatur batas waktu

Pada pengiriman formulir, pengatur waktu pada DOM dihapus tetapi konsol mulai membuat kesalahan. Ini karena elemen tempat setTimeOut bertindak telah dihapus dari DOM:

melepaskan

Untuk menghindarinya kita bisa menggunakan metode detach seperti ini:

 (function (Drupal, once) { let counter = 0; let intervalStopper; Drupal.behaviors.exampleBehaviour4 = { attach: (context, settings) => { // Set the timer for user to see the time elapsed once("timer-initialized", ".contact-timer", context).forEach((ele) => { const timer = context.querySelector(".contact-timer-sec"); timer.textContent = counter; intervalStopper = setInterval(() => { const timer = document.querySelector(".contact-timer-sec"); timer.textContent = ++counter; console.log("This is logging"); }, 1000); }); }, // Clear the timer on confirmation detach: (context, settings, trigger) => { const timer = context.querySelector(".contact-timer-sec"); if (trigger == "unload" && timer) { clearInterval(intervalStopper); } }, }; })(Drupal, once);

Ini menghilangkan timer saat membongkar dan seperti yang terlihat dari logger, kesalahan tidak terjadi.

Demo JS

Ekspresi Fungsi Segera Dipanggil (IIFE) - Pembungkus untuk JS

Kami telah menggunakan IIFE untuk menulis kode Drupal kami. Tanda kurung buka awal menentukan fungsi anonim yang membantu mencegah ruang lingkup fungsi mencemari ruang lingkup global seluruh aplikasi. Anda bisa meneruskan argumen ke fungsi anonim Anda dengan memasukkannya sebagai argumen di akhir definisi fungsi.

Ini juga membantu kita untuk menamai parameter sesuai keinginan kita untuk digunakan.

Contoh:

 // Function name crisis!!!! // The function is vulnearble to // be replaced by some other function function someFunction() { // Some code for this function } (function (Drupal) { // Function name crisis averted! function someFunction() { // Some code for this other function } Drupal.behaviors.exampleBehaviour6 = { attach: (context, settings) => { someFunction(); }, }; })(Drupal);

Pikiran Akhir

Menerapkan perilaku Drupal memungkinkan interaktivitas dinamis, interaksi pengguna yang disederhanakan, umpan balik pengguna yang lebih baik, pengembangan yang efisien, dan peningkatan pengalaman pengguna situs web Anda secara keseluruhan. Drupal.behaviors bersifat fleksibel dan modular, karena dapat dijalankan berkali-kali pada halaman, dapat mengesampingkan dan memperluas perilaku yang ada, dan dapat diterapkan kembali secara otomatis ke konten apa pun yang dimuat melalui Ajax.

Mencari agen pengembangan Drupal untuk membantu Anda membangun pengalaman web interaktif, memanfaatkan Drupal sebaik mungkin? Kami ingin sekali berbicara!