Как предотвратить привязку поведенческих функций дважды?

11

У меня есть поведение, которое добавляет onк некоторым флажкам.

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

Это работает очень хорошо, но флажки находятся в AJAX-загруженной части. Если я перезагружу эту часть формы, щелкнув по ней, вы получите всплывающее окно подтверждения дважды. Теперь я знаю, что могу проверить внутреннюю функцию, если она вызывается впервые, но я бы предпочел, чтобы она добавлялась в мой элемент только один раз и, следовательно, вызывалась только один раз. Как я могу это сделать?

МОЛОТ
источник

Ответы:

20

once()Функция поможет с этим, например ,

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

Одна из многих ссылок

Клайв
источник
2
Спасибо. Работал как шарм. Я думаю, это один из тех моментов, когда я просто не могу правильно спросить Google. Я спросил о предотвращении дважды и предотвращении множественного . Если бы я только попросил сделать это один раз ...
Mołot
1
@ Mołot Но благодаря тому, что ваш комментарий был проиндексирован, я нашел его, когда искал предотвращение множественного числа :-D
frazras
7

Вам нужно использовать функцию Once () для достижения этой цели. С этой страницы

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

Строка «myModule», переданная функции, устанавливается в качестве маркера на элементах, соответствующих выбору jQuery, поэтому при следующем вызове она игнорируется. Не используйте одну и ту же строку, если вы вызываете функцию один раз несколько раз для разных целей, иначе вы можете победить ее назначение.

Альфред Армстронг
источник
Спасибо за ваше объяснение :) Принял ответ Клайва, так как его код работал на меня напрямую, а ваш - нет, но мне больше нравится ваше описание.
Молот
2

Вот пример, который расширяет ответ 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.
    }
  }
};
maskedjellybean
источник
Это решение сработало для меня. Мне не нужно связывать какой-то элемент с действием. Я должен запустить только функцию. Drupal.behaviors.checkOnce = { attach: function (context, settings) { if (context === document) { check(); } function check() { //code } } };В этом случае check()функция будет запускаться только один раз, когда контекст будетdocument
Вадим Судариков
1

Вы также можете сделать это тоже:

(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);
taggartJ
источник
Отлично, это работает для меня
Махтаб Алам
0

вот еще один способ иметь функцию, которая запускается один раз:

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

Источник: https://www.drupal.org/forum/support/module-development-and-code-questions/2018-06-15/run-js-funtion-once-not-attach-once#comment-12654121

frazras
источник