jQuery回调累积

时间:2013-01-10 14:45:20

标签: javascript jquery

我正在构建一个名为magicForm的简单jQuery插件(这有多荒谬?)。现在面对一个我认为我没有正确搞清楚的问题。

我的插件应该应用于容器元素,当用户填充它们时,它将逐个显示每个输入。这不是我问题的确切目的。 每次初始化容器时,我都会声明一个事件点击回调。让我举个例子。

(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 bootstrap“tab”中的元素上调用我的插件时,我正在经历这种痛苦,它嵌套在一个bootstrap模式中: 每次触发我的引导模态的“显示”事件时,我都在调用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);
}

我对此并不确定。

感谢您的时间!

2 个答案:

答案 0 :(得分:1)

您可以先明确删除点击处理程序:

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

但是,我建议您使用事件命名空间来阻止所有点击处理程序(甚至那些可能由您自己的代码设置的处理程序)被删除:

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

答案 1 :(得分:1)

许多jquery插件使用data来了解他们的插件是否已初始化。大多数情况下,他们使用自己的插件名称作为数据的一部分(或整体)。例如:

$(this).data('magicForm')

所以你使用它发出信号的方法并不是坏事。

但是,您还有两个选择:

1)拉出事件处理程序,使处理程序是单个实例。在您的方法之上,执行var fnOnSubmit = function() { ... }然后您可以通过调用$('a.submit', form).unbind('click', fnOnSubmit)来确保正确绑定,然后再按照您已经执行的方式重新绑定它。

2)另一种选择是使用事件命名空间。

$('a.submit', form).unbind('click.magicForm');然后用.on('click.magicForm')重新绑定它。这种命名空间方法确保当你解除绑定时它只在你的命名空间magicForm的上下文中取消绑定,从而使所有其他点击事件(例如来自其他插件)完好无损。

我希望这会有所帮助。