Due to a module, the Drupal behavior I implemented is called five times instead of once.
(function ($) { Drupal.behaviors.myFunction = { attach: function (context, settings) { // … } }; })(jQuery); How do I correctly use jQuery once()?
Due to a module, the Drupal behavior I implemented is called five times instead of once.
(function ($) { Drupal.behaviors.myFunction = { attach: function (context, settings) { // … } }; })(jQuery); How do I correctly use jQuery once()?
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. }); Drupal provides the jquery plugin once(), which allows you to ensure a function is run only once on any single element. You can use this within your behaviour.
See Drupal.behaviours here: https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview