You can use $.once()
, which is available in both Drupal 7 and Drupal 8. The code called inside $.once()
will only be executed a single time for the HTML element it is called on.
For Drupal 7, you can do this.
(function ($, Drupal) {
function someElementWatcher(context) {
// $.once acts like $.each, and loops through the found elements.
// The code inside $.once() will act on each element in the jQuery object
// a single time.
$(context).find(".some_element").once("some-arbitrary-but-unique-key", function () {
// $(this) refers to the current instance of $(".some_element")
$(this).click(function () {
// Do something clicky.
});
});
}
Drupal.behaviors.someUniqueKey = {
attach:function (context) {
someElementWatcher();
}
};
}(jQuery, Drupal));
In Drupal 8, the $.once()
functionality has changed under the hood, and the method of setting it has changed on the front end. In Drupal 8, $.once()
needs to be combined with $.each()
. You need to change the following part.
$(context).find(".some_element").once("some-arbitrary-but-unique-key", function () {});
Instead, you need to use this.
$(context).find(".some_element").once("some-arbitrary-but-unique-key").each(function () {});
In Drupal 9, once()
stopped to be a jQuery function. To use once()
library, first add core/once as dependency of the relevant library in the .libraries.yml file.
some_library:
css:
...
js:
...
dependencies:
- core/once
You can now use once()
to retrieve a list of elements and loop through them.
const elements = $(context).find(".some_element").once("some-arbitrary-but-unique-key");
elements.each(function () {
// Do something with the current element.
});