When porting some front-end code from Drupal 7 to Drupal 8, I ran into an unexpected change in the use of jQuery.once()
. In Drupal 7, you’d do this in a behavior:
//DRUPAL 7
Drupal.behaviors.exampleBehavior = {
attach: function(context, settings) {
$('.example', context).once('example-behavior', function() {
// Do stuff.
});
},
detach: function(context, settings, trigger) {
$('.example', context).removeOnce('example-behavior', function() {
// Undo stuff.
});
}
};
In Drupal 8, however, you can’t pass in a function to jQuery.once()
, as the API for that jQuery plugin has changed. It now acts like jQuery.filter()
, in that it filters out any elements that have already been processed so they aren’t processed more than once, and returns a jQuery collection. So, in Drupal 8, the example would be:
//DRUPAL 8-9
Drupal.behaviors.exampleBehavior = {
attach: function(context, settings) {
$('.example', context).once('example-behavior').each(function() {
// Do stuff.
});
},
detach: function(context, settings, trigger) {
$('.example', context).removeOnce('example-behavior').each(function() {
// Undo stuff.
});
}
};
In order to have access to jquery and the Drupal JS features you need to add this in your custom libraries yml file
search_results:
version: VERSION
css:
theme:
css/search_results.css: {}
js:
js/search_results.js: {}
dependencies:
- core/drupal
- core/js-cookie
- core/jquery
- core/jquery.once
Where search_results is my custom "library" in the custom_modules.libraries.yml file.
And then in your search_results.js file you will have something like this
/**
* Attaches the single_datetime behavior.
*
* @type {Drupal~behavior}
*/
(function ($, Drupal, drupalSettings) {
'use strict';
Drupal.behaviors.rangeSliderDistance = {
attach: function (context, drupalSettings) {
$(context).find("#distance-slider").once("apply_range_slider_distance").each(function () {
// Do magic JS here
}); //end of once filter
}
};
})(jQuery, Drupal);
From: https://ambientimpact.com/web/snippets/drupal-8-behaviors-and-jquery-on…