jQuery 插件回调无法正常工作
jQuery Plugin callback doesn't work properly
我在 jsfiddle 的简单插件中复制了这个问题:https://jsfiddle.net/5atn3010/1/
想法是:
- 我有 2 个 select 或年份范围(从 2005 年到 2020 年)
- 当我 select 第一个 selector 中的选项时,selected 值(例如 2010)在第二个 selector 中设置为最小值。
- 最后,第二个 selector 被重新绘制并且只显示新值(从 2010 到 2020)
这行得通,但有一个大错误。不仅更改第二个 select 值,而且第一个 selector 的最小值也更改。
为什么会这样?我该如何解决?
;(function ( $, window, document, undefined ) {
"use strict";
var pluginName = "testing";
function Plugin( element, options ) {
this.element = element;
this.$element = $(element);
this.name = pluginName;
this.opts = $.extend({}, $.fn[pluginName].defaults, options);
this.$elements = {
year:null,
}
this.init(element,options);
}
Plugin.prototype = {
init: function () {
var me=this;
me.$elements.year=$("<select />").attr("name","year");
if (me.opts.css!=null) {
me.$elements.year.addClass(me.opts.css);
}
me.$elements.year.on("change",function() {
me.opts.onChange.call(me,me.$elements.year.val());
me._draw.call(me); //redraw me only for show error
});
me.$element.append(me.$elements.year);
me._draw();
},
_draw: function() {
var me=this;
var date_start=me.opts.date.start;
var date_end=me.opts.date.end;
me.$elements.year.find("option").remove();
for (var i=date_start;i<=date_end;i++) {
var option=$("<option/>").attr("value",i).text(i);
me.$elements.year.append(option);
}
},
setMin: function(min) {
this.opts.date.start=min;
this._draw();
}
}
$.fn[pluginName] = function(options) {
var param=arguments[1];
return this.each(function() {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
else if ($.isFunction(Plugin.prototype[options])) {
$.data(this, 'plugin_' + pluginName)[options](param);
} else {
$.error('Method ' + options + ' is not available');
}
});
};
$.fn[pluginName].defaults = {
date: {
start:2005,
end:2020
},
onSelect:function() {}
};
})( jQuery, window, document );
$().ready(function(){
$("#span1").testing({
onChange:function(min) {
console.log(min);
$("#span2").testing("setMin",min);
}
});
$("#span2").testing();
});
您的代码有两个问题。首先 - 你没有递归地扩展你的选项对象。简而言之 - 您有两个不同的 opts
对象,它们持有对同一个 date
对象的引用。我添加了一些日志记录,以便您可以理解我在说什么。您需要深复制您的选项对象。
请仔细阅读jQuery.extends页http://api.jquery.com/jquery.extend/
其次,您将 this.opts.date.start
分配给 <option>
值。目前它工作正常,但如果您尝试将最短日期设置为 selected date + N
,它将无法按预期工作。它将 N 作为字符串连接而不是添加。我也为这个案例添加了一些日志。
我在 jsfiddle 的简单插件中复制了这个问题:https://jsfiddle.net/5atn3010/1/
想法是:
- 我有 2 个 select 或年份范围(从 2005 年到 2020 年)
- 当我 select 第一个 selector 中的选项时,selected 值(例如 2010)在第二个 selector 中设置为最小值。
- 最后,第二个 selector 被重新绘制并且只显示新值(从 2010 到 2020)
这行得通,但有一个大错误。不仅更改第二个 select 值,而且第一个 selector 的最小值也更改。
为什么会这样?我该如何解决?
;(function ( $, window, document, undefined ) {
"use strict";
var pluginName = "testing";
function Plugin( element, options ) {
this.element = element;
this.$element = $(element);
this.name = pluginName;
this.opts = $.extend({}, $.fn[pluginName].defaults, options);
this.$elements = {
year:null,
}
this.init(element,options);
}
Plugin.prototype = {
init: function () {
var me=this;
me.$elements.year=$("<select />").attr("name","year");
if (me.opts.css!=null) {
me.$elements.year.addClass(me.opts.css);
}
me.$elements.year.on("change",function() {
me.opts.onChange.call(me,me.$elements.year.val());
me._draw.call(me); //redraw me only for show error
});
me.$element.append(me.$elements.year);
me._draw();
},
_draw: function() {
var me=this;
var date_start=me.opts.date.start;
var date_end=me.opts.date.end;
me.$elements.year.find("option").remove();
for (var i=date_start;i<=date_end;i++) {
var option=$("<option/>").attr("value",i).text(i);
me.$elements.year.append(option);
}
},
setMin: function(min) {
this.opts.date.start=min;
this._draw();
}
}
$.fn[pluginName] = function(options) {
var param=arguments[1];
return this.each(function() {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
else if ($.isFunction(Plugin.prototype[options])) {
$.data(this, 'plugin_' + pluginName)[options](param);
} else {
$.error('Method ' + options + ' is not available');
}
});
};
$.fn[pluginName].defaults = {
date: {
start:2005,
end:2020
},
onSelect:function() {}
};
})( jQuery, window, document );
$().ready(function(){
$("#span1").testing({
onChange:function(min) {
console.log(min);
$("#span2").testing("setMin",min);
}
});
$("#span2").testing();
});
您的代码有两个问题。首先 - 你没有递归地扩展你的选项对象。简而言之 - 您有两个不同的 opts
对象,它们持有对同一个 date
对象的引用。我添加了一些日志记录,以便您可以理解我在说什么。您需要深复制您的选项对象。
请仔细阅读jQuery.extends页http://api.jquery.com/jquery.extend/
其次,您将 this.opts.date.start
分配给 <option>
值。目前它工作正常,但如果您尝试将最短日期设置为 selected date + N
,它将无法按预期工作。它将 N 作为字符串连接而不是添加。我也为这个案例添加了一些日志。