Wie kann verhindert werden, dass verhaltensbezogene Funktionen zweimal angehängt werden?

11

Ich habe ein Verhalten, ondas einige Kontrollkästchen ergänzt.

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

Es funktioniert sehr gut, aber Kontrollkästchen befinden sich im AJAX-geladenen Teil. Wenn ich diesen Teil des Formulars neu lade, wird durch zweimaliges Klicken ein Bestätigungs-Popup angezeigt. Jetzt weiß ich, dass ich die Innenfunktion testen kann, wenn sie zum ersten Mal in Folge aufgerufen wird, aber ich möchte lieber sicherstellen, dass sie nur einmal zu meinem Element hinzugefügt und daher nur einmal aufgerufen wird. Wie kann ich das machen?

Mołot
quelle

Antworten:

20

Die once()Funktion hilft dabei, z

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

Eine der vielen Referenzen

Clive
quelle
2
Vielen Dank. Lief wie am Schnürchen. Ich denke, das ist einer dieser Momente, in denen ich Google einfach nicht richtig frage. Ich fragte nach zweimalem Verhindern und mehrfachem Verhindern . Wenn nur ich habe über das Tun sie fragte einmal ...
Molot
1
@ Mołot Aber dank Ihres Index indiziert, fand ich es, als ich nach verhindern mehrere suchen :-D
frazras
7

Sie müssen die Funktion Once () verwenden, um dies zu erreichen. Von dieser Seite

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

Die an die Funktion übergebene Zeichenfolge "myModule" wird als Markierung für die Elemente festgelegt, die mit der jQuery-Auswahl übereinstimmen, sodass sie beim nächsten Aufruf ignoriert werden. Verwenden Sie nicht dieselbe Zeichenfolge, wenn Sie die Funktion Once einmal für verschiedene Zwecke aufrufen. Andernfalls können Sie ihren Zweck umgehen.

Alfred Armstrong
quelle
Vielen Dank für Ihre Erklärung :) Akzeptierte Clives Antwort, da sein Code direkt für mich funktionierte und Sie nicht, aber Ihre Beschreibung gefällt mir besser.
Mołot
0

Sie können dies auch tun:

(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);
Taggart Jensen
quelle
0

Hier ist eine andere Möglichkeit, eine Funktion zu haben, die einmal ausgeführt wird:

(function($, Drupal) {

  var initialized;

  function init() {
    if (!initialized) {
      initialized = true;
      // Add your one-time only code here
    }
  }

  Drupal.behaviors.someKey = {
    attach: function() {
      init();
    }
  };

}(jQuery, Drupal));

Quelle: https://www.drupal.org/forum/support/module-development-and-code-questions/2018-06-15/run-js-funtion-once-not-attach-once#comment-12654121

frazras
quelle
0

Hier ist ein Beispiel, das die Antwort von frazras erweitert:

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.
    }
  }
};
Maskedjellybean
quelle