Come impedire che le funzioni associate al comportamento vengano associate due volte?


11

Ho un comportamento che si aggiunge onad alcune caselle di controllo.

(function($) { 
  Drupal.behaviors.mymodule = {
    attach: function (context, settings) {

      $('.skip-line', context).on('change', function(){
        // some code
        if ( confirm(Drupal.t('Apply to all languages?')) ) {
          // applying...
        }
      });
    }
  };
})(jQuery);

Funziona molto bene, ma le caselle di controllo sono nella parte caricata AJAX. Se ricarico quella parte del modulo, facendo clic su di essi viene visualizzato due volte il popup di conferma. Ora so di poter testare la funzione interna se è la prima volta consecutiva che viene chiamata, ma preferirei assicurarmi che venga aggiunta al mio elemento solo una volta, e quindi chiamata solo una volta. Come lo posso fare?

Risposte:


20

La once()funzione aiuterà in questo, ad es

(function($) { 
   Drupal.behaviors.mymodule = {
    attach: function (context, settings) {

      $('.skip-line', context).once('mymodule').on('change', function(){
        // some code
        if ( confirm(Drupal.t('Apply to all languages?')) ) {
          // applying...
        }
      });
    }
  };
})(jQuery);

Uno dei tanti riferimenti


2
Grazie. Ha funzionato come un fascino. Immagino sia uno di questi momenti in cui non riesco semplicemente a chiedere a Google correttamente. Ho chiesto di prevenire due volte e di prevenire più . Se solo avessi chiesto di farlo una volta ...
Mołot

1
@ Mołot Ma grazie al tuo commento indicizzato, l'ho trovato quando ho cercato di prevenire multipli :-D
frazras

7

È necessario utilizzare la funzione once () per raggiungere questo obiettivo. Da questa pagina

Drupal.behaviors.myModule = {
  attach: function (context, settings) {
    $('element', context).once('myModule', function () {
     // any behavior is now applied once
    });
  }
};

La stringa "myModule" passata alla funzione viene impostata come marcatore sugli elementi corrispondenti alla selezione jQuery, quindi la volta successiva che viene chiamata li ignora. Non utilizzare la stessa stringa se si chiama la funzione once più volte per scopi diversi, altrimenti è possibile annullarne lo scopo.


Grazie per la tua spiegazione :) Ho accettato la risposta di Clive poiché il suo codice ha funzionato per me direttamente e tu no, ma mi piace di più la tua descrizione.
Mołot

2

Ecco un esempio che si espande sulla risposta di Frazras:

var searchPagesFoundationAccordionInit = false;
Drupal.behaviors.searchPagesFoundationAccordionInit = {
  attach: function (context, settings) {
    // Attempt to resolve behavior being called multiple times per page load.
    if (context !== document) {
      return;
    }
    if (!searchPagesFoundationAccordionInit) {
      searchPagesFoundationAccordionInit = true;
    }
    else {
      return;
    }

    // Check if component exists.
    if ($('.view-style--search-page .search-section__sidebar .accordion').length > 0) {
     // Code here.
    }
  }
};

Questa soluzione ha funzionato per me. Non ho bisogno di collegare alcuni elementi con l'azione. Devo eseguire solo una funzione. Drupal.behaviors.checkOnce = { attach: function (context, settings) { if (context === document) { check(); } function check() { //code } } };In questo caso la check()funzione verrà eseguita una sola volta, quando il contesto sarà adocument
Vadim Sudarikov il

0

puoi anche fare questo:

(function ($, Drupal, drupalSettings) {
    'use strict';
Drupal.behaviors.someThing = {
        attach: function (context) {
            if (context === document) {
               console.log('called inside'); // Once <-- 
            }
            console.log('called outside'); // can be manny manny  <-- 
         },
    };
})(jQuery, Drupal, drupalSettings);

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.