6.8. Travailler avec JavaScript/jQuery dans Drupal. Que sont les behaviors ?
Pour commencer, revenons à la manière d’inclure des fichiers JavaScript personnalisés dans notre thème. Dans le fichier .libraries.yml, vous devez inclure js :
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
Il est important de respecter l'indentation de deux espaces. Ainsi, nous avons inclus le fichier js/custom.js. Mais cela ne suffit pas pour que jQuery fonctionne. En effet, le noyau Drupal ne requiert pas jQuery et ne l’inclut pas automatiquement. Il doit être inclus séparément :
dependencies:
- core/jquery
Nous allons aussi utiliser jQuery.once(), un plugin séparé pour jQuery, permettant d’attacher des événements et méthodes au sélecteur une seule fois.
dependencies:
- core/jquery
- core/jquery.once
En fait, nous allons écrire du code JavaScript appelé plusieurs fois par Drupal lors de différents événements. C’est pourquoi nous avons besoin de la méthode .once().
Passons maintenant à un exemple dans le fichier custom.js :
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
$(context).find('.click-me').once('myCustomBehavior').click(function () {
alert('Hello, World!');
});
}
};
})(jQuery);
Expliquons étape par étape.
(function ($) {
})(jQuery);
Nous enveloppons le code jQuery dans cette construction car jQuery dans Drupal fonctionne en mode .noConflict(). Cela permet d’utiliser le signe dollar $ sans conflit avec d’autres frameworks JavaScript comme Prototype ou MooTools. Même si vous n’êtes pas susceptible de les rencontrer, vous devez toujours envelopper votre code jQuery dans ce cadre.
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
}
};
})(jQuery);
Venons-en aux behaviors. Si vous écrivez du code jQuery dans Drupal, vous devez d’abord l’envelopper dans la fonction ($), puis dans un behavior. Le nom du behavior doit être unique, ici myModuleBehavior, mais vous devez en écrire un pour chaque behavior :
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
}
};
Drupal.behaviors.productPageBehavior = {
attach: function (context, settings) {
}
};
})(jQuery);
Utilisez la notation camelCase pour nommer le behavior. Le behavior est appelé lors du chargement de la page, et pour chaque requête AJAX. Ainsi, lorsque de nouveaux contenus sont chargés et insérés dans la structure existante, le code du behavior est exécuté à chaque fois. Cela diffère nettement de :
$(document).ready(function () {
// Faites des choses sympas.
// Ne pas utiliser ce code dans Drupal.
});
qui n’est appelé qu’une seule fois au chargement de la page.
Si vous avez commencé à utiliser les behaviors et remarquez des événements étranges, par exemple un bloc ajouté plusieurs fois via jQuery :
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Le behavior est appelé plusieurs fois sur la page, n’oubliez pas d’utiliser .once().
$('.inner').append('<p>Test</p>');
}
};
})(jQuery);
À chaque requête AJAX, un paragraphe Test supplémentaire sera ajouté. Il faut donc utiliser la fonction .once() :
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Le behavior est appelé plusieurs fois sur la page, pensez à utiliser la fonction .once().
$('.inner').once('add-paragraph').append('<p>Test</p>');
}
};
})(jQuery);
Une autre particularité du behavior est la variable context. Chaque fois que du nouveau contenu est ajouté à la page, que ce soit au chargement ou via AJAX, ce contenu se trouve dans la variable context. Ainsi, il n’est pas nécessaire de parcourir tout le DOM après chaque requête AJAX pour attacher un événement au sélecteur. Le contexte suffit :
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Le behavior est appelé plusieurs fois sur la page, n’oubliez pas d’utiliser .once().
$(context).find('.inner').once('add-paragraph').append('<p>Test</p>');
}
};
})(jQuery);
Maintenant le paragraphe est écrit dans le style Drupal correct. Bien sûr, vous pouvez utiliser l’ancienne méthode document.ready(), mais cela ne fonctionnera qu’une fois et sera plus lent que via les behaviors.
Si vous avez des questions sur jQuery/JavaScript ou des suggestions pour des thèmes supplémentaires, écrivez dans les commentaires.