6

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()?

1
  • Are you using Drupal 7, or Drupal 8? The method is slightly different depending on the version. Commented Aug 24, 2017 at 8:53

2 Answers 2

28

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. }); 
1
  • 2
    You need to add core/jquery.once as dependency in the .libraries.yml file. Commented Dec 14, 2020 at 0:02
6

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.