จะป้องกันฟังก์ชั่นที่แนบมากับพฤติกรรมได้อย่างไร


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 อย่างถูกต้อง ผมถามเกี่ยวกับการป้องกันครั้งที่สองและการป้องกันหลาย ถ้าเพียง แต่ฉันได้ถามเกี่ยวกับการทำครั้งเดียว ...
MOLOT

1
@ Mołot แต่ขอบคุณที่ความคิดเห็นของคุณได้รับการจัดทำดัชนีฉันพบว่าเมื่อฉันค้นหาเพื่อป้องกันหลาย ๆ :-D
frazras

7

คุณต้องใช้ฟังก์ชั่นหนึ่งครั้ง () เพื่อให้ได้สิ่งนี้ จากหน้านี้

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

สตริง "myModule" ที่ส่งผ่านไปยังฟังก์ชันถูกตั้งค่าเป็นเครื่องหมายบนองค์ประกอบที่ตรงกับการเลือก jQuery ดังนั้นครั้งต่อไปที่ครั้งหนึ่งถูกเรียกว่าจะไม่สนใจสิ่งเหล่านั้น อย่าใช้สายอักขระเดียวกันถ้าคุณเรียกใช้ฟังก์ชันหนึ่งครั้งหลายครั้งเพื่อจุดประสงค์ที่แตกต่างกันมิฉะนั้นคุณอาจเอาชนะวัตถุประสงค์ของมัน


ขอบคุณสำหรับคำอธิบายของคุณ :) ยอมรับคำตอบของไคลฟ์เนื่องจากรหัสของเขาใช้ได้กับฉันโดยตรงและคุณก็ไม่ได้ แต่ฉันชอบคำอธิบายของคุณดีกว่า
Mołot

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

วิธีนี้ใช้ได้ผลสำหรับฉัน ฉันไม่ต้องการเชื่อมโยงองค์ประกอบกับการกระทำ ฉันต้องเรียกใช้ฟังก์ชั่น Drupal.behaviors.checkOnce = { attach: function (context, settings) { if (context === document) { check(); } function check() { //code } } };ในกรณีนี้check()ฟังก์ชั่นจะทำงานเพียงครั้งเดียวเมื่อบริบทจะเป็นdocument
Vadim Sudarikov

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

สิ่งนี้ดีสำหรับฉัน
Mahtab Alam

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.