0

我正在构建一个名为 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 引导“选项卡”中的元素上调用我的插件时,我正在经历这种痛苦,它本身嵌套在一个引导模式中: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')

因此,您使用它来发出信号的方法还不错。

但是,您还有另外两个选择:

1) 拉出事件处理程序,使处理程序成为单个实例。在你的方法之上, dovar fnOnSubmit = function() { ... } 然后你可以简单地通过在重新绑定之前调用来确保正确绑定,$('a.submit', form).unbind('click', fnOnSubmit)就像你已经在做的那样。

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

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

我希望这有帮助。

于 2013-01-10T14:52:21.377 回答