Bagaimana mencegah agar fungsi yang dilampirkan dari perilaku tidak terpasang dua kali?

11

Saya memiliki perilaku yang menambah onbeberapa kotak centang.

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

Ini bekerja dengan sangat baik, tetapi kotak centang berada di bagian yang dimuat AJAX. Jika saya memuat ulang bagian formulir itu, mengkliknya membuat popup konfirmasi dua kali. Sekarang, saya tahu saya bisa menguji fungsi dalam jika ini pertama kali berturut-turut dipanggil, tapi saya lebih suka memastikan itu ditambahkan ke elemen saya hanya sekali, dan dengan demikian disebut hanya sekali. Bagaimana saya bisa melakukan itu?

Mołot
sumber

Jawaban:

20

The once()fungsi akan membantu dengan itu, misalnya

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

Salah satu dari sekian banyak referensi

Clive
sumber
2
Terima kasih. Bekerja seperti pesona. Saya kira itu adalah salah satu dari momen-momen ini ketika saya gagal bertanya kepada Google dengan benar. Saya bertanya tentang mencegah dua kali dan mencegah banyak . Andai saja saya bertanya tentang melakukannya sekali ...
Mołot
1
@ Mołot Tetapi berkat komentar Anda yang diindeks, saya menemukannya ketika saya mencari mencegah beberapa :-D
frazras
7

Anda perlu menggunakan fungsi once () untuk mencapai ini. Dari halaman ini

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

String "myModule" yang diteruskan ke fungsi ditetapkan sebagai penanda pada elemen yang cocok dengan pemilihan jQuery, jadi kali berikutnya disebut itu mengabaikannya. Jangan gunakan string yang sama jika Anda memanggil fungsi yang dulu beberapa kali untuk tujuan yang berbeda, jika tidak, Anda bisa mengalahkan tujuannya.

Alfred Armstrong
sumber
Terima kasih atas penjelasan Anda :) Terima jawaban Clive karena kode-nya bekerja untuk saya secara langsung dan Anda tidak, tapi saya lebih suka deskripsi Anda.
Mołot
1

Berikut adalah contoh yang memperluas jawaban 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
sumber
Solusi ini berhasil untuk saya. Saya tidak perlu menghubungkan beberapa elemen dengan aksi. Saya harus menjalankan fungsi saja. Drupal.behaviors.checkOnce = { attach: function (context, settings) { if (context === document) { check(); } function check() { //code } } };Dalam hal ini check()fungsi akan berjalan hanya sekali, ketika konteksnya akan menjadidocument
Vadim Sudarikov
0

Anda juga dapat melakukan ini:

(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
sumber