web-dev-qa-db-ja.com

jsクリック関数が複数回実行されるのはなぜですか?

twigテンプレートとカスタムJavaScriptファイルを組み合わせて使用​​して、フィールドと段落のアコーディオン機能をいくつか作成しています。

すべてが期待どおりに印刷され、基本的なアコーディオン機能が機能します。ただし、クリック関数スクリプトが複数回実行されているため、「展開、折りたたみ、展開、折りたたみ...」の動作が発生します。画像を見る:

browser and console view that shows logging of each function iteration on click

スクリプトファイルは次のとおりです。

(function($, Drupal) {

/* Add span to wysiwyg button classes for alignment
------------------------------------ */
Drupal.behaviors.accordionFaqFunction = {
  attach: function (context, settings) {
        $('.toggle').click(function(e) {

                e.preventDefault();
                var $this = $(this);

                if ($this.next().hasClass('show')) {
                        $this.next().removeClass('show');
                        $this.next().slideUp(350);
                        console.log("hiding");
                } else {
                        $this.parent().parent().find('li .inner').removeClass('show');
                        $this.parent().parent().find('li .inner').slideUp(350);
                        console.log("showing");
                        $this.next().toggleClass('show');
                        $this.next().slideToggle(350);
                }
        });


  }
};

})(jQuery, Drupal);

スクリプトが複数回実行されるのはなぜですか?

4
lane

最も重要なことは、JQueryセレクタcontextを使用する必要があることです。そうでない場合は、Drupalビヘイビアーがcontextのみを処理に渡したときに、いつでもjsコードを通じてDOM全体を実行します。

それでも関数が複数回実行される場合は、一意の識別子を指定してonce()を追加します。

$('input.myCustom', context).once('mySecondBehavior').each(function () {

ライブラリを追加することを忘れないでくださいcore/jquery.onceをmytheme.libraries.ymlに追加してください https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview を参照

10
4k4

プロジェクトで何かを作業しているときに、この投稿を見つけました。 $( 'body'、context)にバインドされた複数のイベントがあります。プラットフォームの柔軟性により、ウィジェットなどを本体内のほぼどこにでも配置できるためです。

$('body', context).on('click', '.modal-trigger', function (e) {});を使用すると、クリックイベントが本体2xにバインドされていました。

単に$('body', context).once().on('click', '.modal-trigger', function (e) {});を使用すると、最後にアタッチ/ロードされたスクリプトのみが本体にバインドされ、他のスクリプトイベントはアタッチされませんでした。

各スクリプトに一意の識別子を付けて.once()を追加すると、この問題は見事に解決されました。

例最初のモーダルスクリプト

  Drupal.behaviors.SigmaModal = {

    attach: function (context, settings) {

      // Trigger sigma dialog on click.
      $('body', context).once('SigmaModal').on('click', '.sigma-modal-trigger', function (e) {

2番目のモーダルスクリプト

  Drupal.behaviors.DisplayModal = {

    attach: function (context, settings) {

      // Trigger generic dialogs on click.
      $('body', context).once('DisplayModal').on('click', '.modal-trigger', function (e) {
4
ZhuRenTongKu

これは、Drupal 8で試すことができます。

Drupal.behaviors.custom = {
    attach: function(context, settings) {
        if(!Drupal.behaviors.custom.click_set){
            //Your code.
            Drupal.behaviors.custom.click_set = true;
        }
    }
};
1
lucasvm1980