0

magicForm という単純な jQuery プラグインを作成しています (これはばかげていますか?)。今、私が正しく理解していないと思う問題に直面しています。

私のプラグインはコンテナ要素に適用されることになっています。これは、ユーザーが入力すると、各入力が 1 つずつ表示されます。それは私の問題の正確な目的ではありません。コンテナーを初期化するたびに、イベント クリック コールバックを宣言します。例を示しましょう。

(function($){
  var methods = {
    init: function(options){
      return this.each(function(){
        var form, inputs;

        var settings = {
          debug: false
        };
        settings = $.extend(settings, options);
        form = $(this);

        $('a.submit', form).on('click', function(event){
          if (settings.submitCallback) {
            settings.submitCallback.call(form, inputs);
          }
          return false;
        });
      });
    },
    reset: function() {

    }
  }

  $.fn.magicForm = function(method) {
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist.' );
    }
  };
})($);

私はこのコードの特定の部分に焦点を当てています:

$('a.submit', form).on('click', function(event){
    if (settings.submitCallback) {
        settings.submitCallback.call(form, inputs);
    }
    return false;
});

initメソッドが呼び出されるたびに、その貧弱なコールバックが登録されるためです。

Twitterのブートストラップ「タブ」にネストされた要素でプラグインを呼び出し、ブートストラップモーダルにネストされたとき、これを痛々しく経験していました。ブートストラップモーダルinitの「表示」イベントがトリガーされるたびに呼び出していました。

だから、これは私が私の方法でそれを修正したinit方法です:

// Prevent callback cumulation
if (!$(this).data('form_initialized')) {
    $('a.submit', form).on('click', function(event){
        if (settings.submitCallback) {
            settings.submitCallback.call(form, inputs);
        }
        return false;
    });
    $(this).data('form_initialized', true);
}

そして、私はこれについて確信が持てません。

お時間をいただきありがとうございます。

4

2 に答える 2

1

まず、クリック ハンドラを明示的に削除できます。

$('a.submit', form).off('click').on('click', function(event){ ... })

ただし、イベントの名前空間を使用して、すべてのクリック ハンドラー (独自のコードで設定されていないものも含む) が削除されないようにすることをお勧めします。

$('a.submit', form).off('click.magicForm').on('click.magicForm', function(event){ ... })
于 2013-01-10T14:51:48.613 に答える
1

多くの jquery プラグインdataは、プラグインが初期化されているかどうかを知るために使用します。ほとんどの場合、独自のプラグインの名前を一部 (または全体) としてデータとして使用します。例えば:

$(this).data('magicForm')

したがって、それを使用してシグナルを送るというあなたのアプローチは悪いものではありません。

ただし、他に 2 つのオプションがあります。

1) イベント ハンドラーを引き出して、ハンドラーが単一のインスタンスになるようにします。メソッドの上で、 do次に、既に実行している方法で再バインドする前にvar fnOnSubmit = function() { ... } 呼び出すことにより、適切なバインドを確実に行うことができます。$('a.submit', form).unbind('click', fnOnSubmit)

2) もう 1 つのオプションは、イベント名前空間を使用することです。

$('a.submit', form).unbind('click.magicForm');次に、.on('click.magicForm') この名前空間アプローチで再バインドすると、バインドを解除すると、名前空間 magicForm のコンテキストでのみバインドが解除されるため、他のすべてのクリック イベント (他のプラグインなど) はそのまま残ります。

これが役立つことを願っています。

于 2013-01-10T14:52:21.377 に答える