Drupal'da JavaScript'i Uysallaştırma (SSS'leri içerir)

Yayınlanan: 2023-02-07

Etkileşimli web deneyimleri, kullanıcılar için daha ilgi çekici ve eğlenceli bir deneyim sağlar. Kullanıcı memnuniyetinin artmasına ve bir web sitesinin olumlu algılanmasına yol açar. Örneğin, kullanıcıyı sayfa yenilemek için bekletmek yerine anında geri bildirim ve doğrulama sağlayan bir form, kullanıcı deneyimini önemli ölçüde iyileştirebilir.

JavaScript, bir Drupal web sitesinin ön yüzündeki kullanıcılar için dinamik ve etkileşimli deneyimler oluşturma araçları sağlayarak Drupal'da önemli bir rol oynar. Geliştiricilerin, sayfanın tamamını yenilemek zorunda kalmadan formlar, bağlantılar veya diğer DOM öğeleri gibi bir sayfadaki belirli öğelerin davranışını değiştirmesine olanak tanır. Drupal Davranışları, bir sayfada belirli olaylar meydana geldiğinde yürütülen JavaScript işlevleridir. Davranışlar, temel HTML kodunu değiştirmeleri gerekmediğinden, geliştiricilerin bir siteyi bakımını ve yükseltmesini kolaylaştırır. Makalede Drupal Davranışları hakkında bilmek istediğiniz her şeyi öğrenin.

Drupal'da JavaScript'i evcilleştirme

Drupal Davranışlar nelerdir?

Drupal.behaviors , uygulamanın yürütülmesi sırasında belirli zamanlarda yürütülecek işlevleri eklememizi sağlayan Drupal'daki Javascript yapısının içindeki bir nesnedir. DOM tamamen yüklendiğinde çağrılır, ancak bu davranışlar tekrar çağrılabilir. Drupal'ın resmi JavaScript belgeleri, modüllerin Drupal.behaviors'a mantık ekleyerek JavaScript'i uygulaması gerektiğini önerir.

Neden Drupal davranışlarına ihtiyacımız var?

Davranışların avantajı, AJAX aracılığıyla yüklenen herhangi bir içeriğe otomatik olarak yeniden uygulanmalarıdır. DOM'daki yeni eklemeleri veya değişiklikleri temsil eden bir bağlamla herhangi bir zamanda çağrılabilirler. Bu, kodun yalnızca bir kez çalıştırıldığı $(document).ready() veya DOMContentLoaded belgesinden daha iyidir.

Drupal davranışları ne zaman istenmez?

Drupal davranışları, Javascript'i Drupal'da yazmak için her zaman mükemmel çözüm değildir. Bazı durumlarda, aşağıda belirtildiği gibi, Drupal davranışlarına hiç gerek yoktur!

  • DOM'u etkilemeyen bazı kodları çalıştırmamız gerektiğinde. Örneğin. Google Analytics gibi harici bir komut dosyası başlatılıyor
  • Sayfa yüklendiğinde öğenin kullanılabilir olacağını bilerek DOM'da bazı JS işlemlerinin yalnızca bir kez gerçekleştirilmesi gerektiğinde (Bu senaryo, Bir Kez kullanmaktan farklıdır).

Drupal Davranışları ne zaman çağrılır?

  • Sayfaya bir yönetim yerleşimi yüklendikten sonra.
  • AJAX Form API'si bir form gönderdikten sonra.
  • Bir AJAX isteği, ajax_command_replace() gibi HTML'yi değiştiren bir komut döndürdüğünde.

Drupal Davranışların çağrıldığı diğer zamanlar

  • Bir modal yüklendikten sonra CTools onu çağırır.
  • Medya, medya tarayıcısı yüklendikten sonra onu çağırır.
  • Paneller, yerinde düzenleme tamamlandıktan sonra onu çağırır.
  • Görünümler, AJAX kullanan yeni bir sayfa yükledikten sonra onu çağırır.
  • Görünümler Daha Fazla Yükle, sonraki öğe yığınını yükledikten sonra çağırır.
  • Özel modüllerdeki JavaScript, sayfanın bölümlerini eklediklerinde veya değiştirdiklerinde Drupal.attachBehaviors() öğesini çağırabilir.

Drupal davranışlar olmadan kod yazma

Bu kodda, .views-row sınıfına, bu satıra kaç kez tıkladığımızı hesaplayan bir tıklama olay dinleyicisi ekliyoruz. Ancak ilk sayfa yüklemesi sırasında DOM'a gelen öğelere yalnızca bir kez eklenir. Daha Fazla Yükle'ye tıklayıp daha fazla öğe yükledikten sonra, tıklama dinleyicisi yeni yüklenen öğeler üzerinde çalışmıyor.

 // 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; }); }); })(); 
olay dinleyicisi

Drupal Davranışlarını nasıl kullanırız?

Cevap: Ekleme yöntemini kullanma

Hatırlanacak şeyler:

  • Yeni nesnenin en azından bir iliştirme yöntemine sahip olması gerekir.
  • Drupal.attachBehaviors her çağrıldığında, tüm davranış nesnelerini yineler ve ilgili ekleme yöntemlerini çağırır.

Drupal davranışını kodumuza eklemek

Drupal Behaviors'ı ekledikten sonra, kod şuna benzer.

 (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);

Ancak Daha Fazla Yükle'ye tıkladığımızda üstte garip bir şey beliriyor:

davranış

Bunun nedeni, Drupal davranışının birçok kez çağrılması ve ardından bazı istenmeyen davranışlar elde etmemizdir.

“Drupal bağlamında” Bağlam nedir?

  • Drupal, tüm davranışlar için iliştirme yöntemini çağırırken bir bağlam parametresi iletir.
  • Geçirilen bağlam parametresi, genellikle hangi DOM öğesinin işlenmekte olduğu hakkında daha iyi bir fikir verebilir.
  • İlk sayfa yüklemesi sırasında bu, eksiksiz HTML Belgesi olacaktır; sonraki aramalarda, bu sadece sayfaya eklenen veya değiştirilen öğeler olacaktır.

Bağlam nasıl eklenir?

Önceki sorun, Drupal Behaviors tarafından sağlanan bağlam parametresi kullanılarak çözülebilir. Bu durumda, sayfa ilk yüklendiğinde, HTML Belgesinin tamamını bağlam olarak alırız ve işte o zaman başlığı ekleriz. Daha sonraki işlemler için, kodun Drupal Davranışlarından etkilenen kısmı olacaktır ve dolayısıyla kodun o kısmı güvenli bir şekilde kontrol edilir.

 (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);

Daha Fazla Yükle'ye tıkladığımızda yine bazı garip davranışlar var. Başlangıçta yüklenen gıda maddeleri iyi çalışıyor. Ancak Daha Fazla Yükle'ye tıkladıktan sonra, yeni öğeler tıklama dinleyicisini alır ve normal şekilde çalışır. Ancak başlangıçta yüklenen öğeler, dinleyicinin tekrar bağlanmasını sağlar ve üzerlerine tıklamak, birden çok kez tıklama olayını çağırır!

Daha fazla yükle

Drupal Davranışları ne zaman yaramazlık yapmaya başlar?

  • Bir Kez ve Bağlam kullanmadan tüm olay dinleyicilerini Drupal davranışları içinde yazmak.
  • Drupal davranışları içinde istenmeyen işlevlerin bildirilmesi, iliştirme yöntemi her çağrıldığında işlevlerin yeniden bildirilmesine yol açar.

Kurtarmaya “bir kez”

  • Once, kod yürütüldükten sonra bir DOM öğesine bir kez veri özniteliği ekleyerek bir şeyin yalnızca bir kez işlenmesini sağlar.
  • Davranış tekrar çağrılırsa, bir kez veri özniteliğine sahip öğe daha fazla yürütme için atlanır.
  • Once, jQuery.once'nin modern bir uygulamasıdır ( jQuery'den uzaklaşma çabasıdır )
  • Bir kez, bağlamla birlikte, tüm işlevselliği ihtiyacımız olduğu gibi mükemmel bir şekilde kontrol eder.

Kodumuzdaki olay dinleyicilerini düzeltmek için Bir Kez Ekleme

 (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);
veri bir kez

Şimdi her şey amaçlandığı gibi çalışıyor. Olay dinleyicilerinin eklendiği ve yeni yüklenen öğeler ile daha önce yüklenen öğelerin düzgün çalıştığı öğelere bir kez veri özniteliği alırız.

Need for Detach yöntemi

Detach yöntemi, bir anti-kahraman (kötü değil) gibi davranır ve iliştirme yönteminde yaptığımız her şeyi kaldırır. Ayırma yöntemindeki herhangi bir kod, içerik DOM'dan her kaldırıldığında çağrılır. Bu, uygulamamızı temizlememize yardımcı olur. Örneğin, Detach yöntemi, sürekli yoklama durumu gibi kaynakları tüketen istenmeyen olay dinleyicilerini kaldırmamızı sağlar.

Detach Örnekleri

Doldurmamız gereken bir ajax formumuz olduğunu ve geçen süreyi göstermek için bir zamanlayıcı kullandığımızı varsayalım. Zamanlayıcıyı yönetmek için setTimeOut kullanıyoruz. İzleme için bu zamanlayıcıyı konsola kaydederiz.

 (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);
zaman aşımını ayarla

Form gönderiminde, DOM üzerindeki zamanlayıcı kaldırılır ancak konsol bir hata vermeye başlar. Bunun nedeni, setTimeOut'un etki ettiği öğenin DOM'dan kaldırılmış olmasıdır:

ayırmak

Bundan kaçınmak için ayırma yöntemini şu şekilde kullanabiliriz:

 (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);

Bu, boşaltma sırasındaki zamanlayıcıyı kaldırır ve günlükçüden görüldüğü gibi hata oluşmaz.

JS Demosu

Hemen Çağrılan İşlev İfadeleri (IIFE) - JS için sarıcı

Drupal kodumuzu yazmak için IIFE kullanıyoruz. İlk açılış parantezleri, işlevin kapsamının tüm uygulamanın genel kapsamını kirletmesini önlemeye yardımcı olan anonim bir işlevi tanımlar. Bağımsız değişkenleri, işlev tanımının sonuna bağımsız değişkenler olarak ekleyerek anonim işlevinize iletebilirsiniz.

Bu aynı zamanda parametreleri kullanmalarını istediğimiz şekilde adlandırmamıza da yardımcı olur.

Örnek:

 // 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);

Son düşünceler

Drupal davranışlarını uygulamak, web sitenizin dinamik etkileşimi, kolaylaştırılmış kullanıcı etkileşimi, iyileştirilmiş kullanıcı geri bildirimi, verimli geliştirme ve genel olarak gelişmiş kullanıcı deneyimi sağlar. Drupal.behaviors, bir sayfada birden çok kez yürütülebilmeleri, mevcut davranışı geçersiz kılabilmeleri ve genişletebilmeleri ve Ajax aracılığıyla yüklenen herhangi bir içeriğe otomatik olarak yeniden uygulanabilmeleri açısından esnek ve modülerdir.

Etkileşimli web deneyimleri oluşturmanıza ve Drupal'dan en iyi şekilde yararlanmanıza yardımcı olacak bir Drupal geliştirme ajansı mı arıyorsunuz? Konuşmayı çok isteriz!