我正在构建一个名为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);
}
我对此并不确定。
感谢您的时间!
答案 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的上下文中取消绑定,从而使所有其他点击事件(例如来自其他插件)完好无损。
我希望这会有所帮助。