6.8. Werken met JavaScript/jQuery in Drupal. Wat zijn behaviors?
Om te beginnen bekijken we hoe we aangepaste JavaScript-bestanden aan ons thema kunnen toevoegen. In het bestand .libraries.yml
moet je het JavaScript-bestand opnemen:
global-styling:
version: 1.x
css:
theme:
css/style.css: {}
css/print.css: { media: print }
js:
js/custom.js: {}
dependencies:
- core/jquery
- core/jquery.once
Het is belangrijk om de inspringingen correct te gebruiken — twee spaties per niveau.
Zo hebben we het bestand js/custom.js
toegevoegd. Maar dat is niet voldoende om jQuery te laten werken.
Het is namelijk zo dat de Drupal-core jQuery niet automatisch inschakelt. Je moet jQuery expliciet toevoegen:
dependencies:
- core/jquery
We gebruiken ook jQuery.once()
. Dit is een aparte plug-in voor jQuery waarmee je ervoor zorgt dat een event of functie slechts één keer aan een element wordt gekoppeld.
dependencies:
- core/jquery
- core/jquery.once
We doen dit omdat we JavaScript-code gaan schrijven die door Drupal meerdere keren kan worden uitgevoerd bij verschillende gebeurtenissen. Daarom hebben we de methode .once()
nodig.
Voeg nu wat code toe aan het bestand custom.js
:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
$(context).find('.click-me').once('myCustomBehavior').click(function () {
alert('Hello, World!');
});
}
};
})(jQuery);
Laten we dit stap voor stap doornemen.
(function ($) {
})(jQuery);
We wikkelen onze jQuery-code in deze constructie omdat jQuery in Drupal wordt uitgevoerd in .noConflict()
-modus.
Dit is nodig zodat we het dollarteken $
kunnen gebruiken zonder conflicten met andere JavaScript-frameworks zoals Prototype of MooTools.
Hoewel je die frameworks tegenwoordig zelden tegenkomt, moet al je jQuery-code in Drupal altijd in deze structuur worden geplaatst.
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
}
};
})(jQuery);
Hier komen we bij het begrip behavior.
Wanneer je jQuery-code in Drupal schrijft, moet je deze niet alleen in een (function ($))
-constructie plaatsen, maar ook in een Drupal.behaviors
-object.
De naam van het behavior moet uniek zijn. In ons voorbeeld is dat myModuleBehavior
, maar voor elk behavior gebruik je een eigen naam:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
}
};
Drupal.behaviors.productPageBehavior = {
attach: function (context, settings) {
}
};
})(jQuery);
Gebruik camelCase bij het benoemen van behaviors. Een behavior wordt uitgevoerd telkens wanneer de pagina laadt of bij elke AJAX-aanroep. Wanneer er dus nieuwe content via AJAX op de site wordt geladen, wordt de code in het behavior automatisch opnieuw uitgevoerd. Dat is een belangrijk verschil met de klassieke aanpak:
$(document).ready(function () {
// Doe iets leuks.
// Gebruik deze code niet in Drupal.
});
De bovenstaande code wordt slechts één keer uitgevoerd bij het laden van de pagina.
Als je behaviors gebruikt en merkt dat er vreemde dingen gebeuren — bijvoorbeeld dat een blok meerdere keren wordt toegevoegd via jQuery — dan komt dat omdat het behavior meerdere keren wordt aangeroepen:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Behavior wordt meerdere keren aangeroepen op de pagina.
// Vergeet niet .once() te gebruiken.
$('.inner').append('<p>Test</p>');
}
};
})(jQuery);
Bij elke AJAX-aanroep wordt er opnieuw een <p>Test</p>
-element toegevoegd.
Daarom moet je altijd de .once()
-functie gebruiken:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Behavior wordt meerdere keren aangeroepen op de pagina.
// Vergeet niet .once() te gebruiken.
$('.inner').once('add-paragraph').append('<p>Test</p>');
}
};
})(jQuery);
Een ander belangrijk onderdeel van een behavior is de context-variabele.
Telkens wanneer er nieuwe content wordt toegevoegd aan de pagina — bij het laden of via AJAX — bevindt alle nieuwe content zich binnen deze context
.
Je hoeft dus niet meer de volledige DOM opnieuw te doorlopen om events te koppelen aan nieuwe elementen. Het is voldoende om binnen context
te zoeken:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Behavior wordt meerdere keren aangeroepen op de pagina.
// Vergeet niet .once() te gebruiken.
$(context).find('.inner').once('add-paragraph').append('<p>Test</p>');
}
};
})(jQuery);
Op deze manier wordt de paragraaf toegevoegd volgens de correcte Drupal-standaard.
Je kunt nog steeds de oude manier met document.ready()
gebruiken, maar dat werkt slechts één keer en is trager dan de behavior-methode.
Als je vragen hebt over jQuery of JavaScript in Drupal, of suggesties voor aanvullende onderwerpen, laat dan een reactie achter.