-2

In the series of problems I have with the usage of once method, I wonder how I can refactor simply that code with the once method and be able to toggle local storage on a set of clickable elts:

(function ($, Drupal) {
  'use strict';
  /** 
   *
   * @type {Drupal~behavior}
   */
  Drupal.behaviors.recherche = {
    attach: function (context) {

 const els = document.querySelectorAll(".block-facet-blocktype h2, .block-facet-blockaxe h2, .block-expertisescientifique h2, .block-domainedapplication h2");
    for (const el of els) {
      el.addEventListener("click", handler);
    }

    function handler(event) {
      event.preventDefault();
      var selector = $(this);
      toggleLocalStorage(selector, 'expanded');
    }
}}
})
(jQuery, Drupal);

What happens at the moment is one click call the toggle function 6times and have then no effect.

1
  • Is this a Drupal Q? I've noticed, more so with D9 and the core once library, that I have some unknowns. once('myBehavior', 'html', context).forEach( function (element) has the potential to run before the full DOM is loaded, and placing the global context inside an if () check doesn't run. This is also a bit trickier when getting an element by ID to which you may not have any .forEach() functions in your scripts. I have the same Q as above, when adding an event listener, how do you go about running once()? Must you use the global context and set once() against html or body? Jun 8, 2022 at 22:42

1 Answer 1

2

once is a jQuery plugin; it doesn't really make sense to mix it with vanilla JS event handlers, as you're already using jQuery by that point, and it's easier to attach events with jQuery.

After you've refactored your code to use jQuery, its usage is well explained, with examples, in the Drupal javascript docs. There are many permutations, here is one example for attaching an event handler:

$('a.foo', context).once('bar').each(function () {
    // You could also use this.addEventListener here, but as you're already in a jQuery context it doesn't really make sense to.
    $(this).click(function() {
      // ...
    });
});
3
  • thanks it works only if i remove the ",context"
    – Matoeil
    Aug 30, 2019 at 10:12
  • 1
    Using that assumes your code is wrapped in a Drupal behavior (which is recommended). The same docs linked above explain that too
    – Clive
    Aug 30, 2019 at 10:14
  • it was wrapped, as edited
    – Matoeil
    Aug 30, 2019 at 13:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.