jQuery Once: Drupal 8 vs Drupal 7

Chi ha avuto modo di cimentarsi nella stesura di qualche riga di codice JS in Drupal 8 si sarà sicuramente imbattuto in un problema, quello di jQuery once che non funziona a dovere, o almeno così pare.

utilities:
  version: 1.x
  js:
    js/throbber.js: {}
  dependencies:
  - core/drupalSettings
  - core/jquery
  - core/jquery.once

Cosa è successo?

In primis c’è da capire qual è la versione di jQuery utilizzata.

Drupal 7

In tal senso con il modulo contrib jQuery update di Drupal 7 era possibile passare dalla versione 1.4 di jQuery ad una versione superiore a scelta (oggi arrivata alla 1.10) e che il modulo non è più disponibile in Drupal 8.

In Drupal 7 avremmo fatto una cosa del genere:

# source: https://www.drupal.org/node/2457769
/**
 * Attach my behavior to the .mybehavior elements.
 */
Drupal.behaviors.mybehavior = {
  attach: function(context) {
    // Set the initial state of the toolbar.
    $('.mybehavior', context).once('mybehavior', function() {
      // Do something to the elements.
      $(this).css('background-color', 'red');
    });
  }
};

Drupal 8

In Drupal 8 la versione di jQuery è la 3.2.1 (questo al 24/07/2018 quando è appena uscita l’alpha di Drupal 8.6.0-alpha1; vedi immagine).

Quindi molto più avanzata rispetto a quella di Drupal 7.

Questo ha fatto sì che il modo di invocare determinate funzioni (come il once) sia cambiato.

Come rilevato nel ticket aperto dalla community di Drupal c’è un problema di funzionamento con jQuery once che deve essere invocato in un altro modo, dopo che esso è stato aggiornato alla versione 2.0.

Ebbene tutto ciò è stato realizzato discusso, analizzato e risolto in un ticket sulla community, questo: https://www.drupal.org/node/2457769.

Per comodità riporto di seguito l’esempio ivi riportato:

# source: https://www.drupal.org/node/2457769
/**
 * Attach my behavior to the .mybehavior elements.
 */
Drupal.behaviors.mybehavior = {
  attach: function(context) {
    // Set the initial state of the toolbar.
    $(context).find('[data-mybehavior]').once('mybehavior').each(function() {
      // Do something to the elements.
      $(this).css('background-color', 'red');
    });
  }
};

Come è possibile vedere adesso il once si ottiene in maniera sequenziale, senza gli innesti che erano necessari qualche versione fa.

EDIT 08/01/2019

Per evitare che l’utente anonimo abbia problemi con jQuery Once è necessario includere quanto segue, tra le dipendenze di un modulo che usa jQuery Once.

Riferimento: https://www.drupal.org/project/ultimenu/issues/2562829