jQuery插件 - 初始化后更新设置
Posted
技术标签:
【中文标题】jQuery插件 - 初始化后更新设置【英文标题】:jQuery plugin - update settings after initialization 【发布时间】:2015-04-08 08:37:13 【问题描述】:我有一个 jQuery 插件,我希望能够即时更改选项,例如:$('.element').pwstabs('options','effect',scale)
或类似的东西。我尝试添加update: function
,尝试添加Plugin.prototype.update
,但仍然无法弄清楚如何做到这一点:)
这是插件的结构:
;(function ($, window, document, undefined)
var pluginName = "pwstabs",
defaults =
effect: 'scaleout',
defaultTab: 1,
containerWidth: '100%',
tabsPosition: 'horizontal',
horizontalPosition: 'top',
verticalPosition: 'left',
responsive: false,
theme: '',
rtl: false,
controlls: false,
next: '',
prev: '',
first: '',
last: '',
auto: false,
play: '',
pause: ''
;
function Plugin(element, options)
this.element = $(element);
this.$elem = $(this.element);
this.settings = $.extend(, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
Plugin.prototype =
init: function()
// Here's the code for the plugin
;
$.fn[pluginName] = function ( options )
return this.each(function ()
new Plugin( this, options );
);
;
)(jQuery, window, document);
所以现在我使用这样的插件:
$('.element').pwstabs(
effect: 'scalein',
defaultTab: 2
);
当我单击一个按钮时,我想将效果更改为scaleout
。使用如下代码:
$('.button').click(function()
$('.element').pwstabs('options','effect','scalein');
);
那么如何在插件中实现呢?
【问题讨论】:
$('.button').click(function() $('.element').pwstabs("effect":"scaleout"); );
?
@guest271314 理论上可以工作,但它会重新初始化插件,这不是他想要的:)
@guest271314,已经尝试过了,它确实会重新初始化插件
将标志变量添加到init
,如果插件已经启动,接受选项更改,而不再次调用init
?添加 .data("init", true)
到 element ,如果插件已经在 element 启动,接受选项更改而不再次调用 init
?
这可行,我也考虑过这种方法。但是,OP 询问的是特定的调用模式,所以我在回答中实现了它。
【参考方案1】:
目前,该插件中唯一支持的调用模式是发送一个包含设置的对象文字以覆盖默认值。例如:
$('.element').pwstabs(
effect: 'scalein',
defaultTab: 2
);
该调用模式在以下方法中定义:
$.fn[pluginName] = function ( options )
return this.each(function ()
new Plugin( this, options );
);
;
如您所见,选项字典作为唯一参数发送到构造函数 Plugin() 以构建插件并对其进行初始化。
要支持您需要的调用模式,您必须修改此方法以支持 both 调用模式(使用对象字面量进行初始化,但也可以调用具有更多参数的任何方法,例如您的选项设置方法)。
这是一个改进的函数,可以处理两种调用模式。此外,它还将插件的实例存储在元素上,因此您可以在同一元素的后续调用(例如设置更改)时访问现有设置等。
$.fn[pluginName] = function (options)
// get the arguments
var args = $.makeArray(arguments),
after = args.slice(1);
return this.each(function ()
// check if there is an existing instance related to element
var instance = $.data(this, pluginName);
if (instance)
if (instance[options])
instance[options].apply(instance, after);
else
$.error('Method ' + options + ' does not exist on Plugin');
else
// create the plugin
var plugin = new Plugin(this, options);
// Store the plugin instance on the element
$.data(this, pluginName, plugin);
return plugin;
);
这将允许您根据请求调用插件:
$('.element').pwstabs('options','effect','slidedown');
但是,这意味着您在插件原型中有一个“选项”方法,因此请务必添加一个:
Plugin.prototype =
options: function (option, val)
this.settings[option] = val;
,
// Constructing Tabs Plugin
init: function ()
// omitted code for brevity
如您所见,选项设置只是在现有实例上设置新选项。非常简单高效。新设置将被点击方法处理程序拾取,瞧!
这是一个带有示例代码的 jsFiddle,以防您无法实现我到目前为止所描述的内容:
http://jsfiddle.net/7whs3u1n/6/
更新:我已经大大改进了我的答案,以摆脱不需要的东西,包括更多细节和完整的实现(检查上面的小提琴);)我希望这能回答你的问题!
为您的插件添加状态并不难,但当您有空闲时间时,还可以检查一下编写有状态 jQuery 有状态插件的替代机制,称为 jQuery 小部件工厂:
http://learn.jquery.com/plugins/stateful-plugins-with-widget-factory/
将来您可以考虑重写您的插件以使用小部件工厂。它肯定会让你的代码更简单;)
【讨论】:
这太好了,谢谢你的解释和帮助! :) 顺便说一句,我如何在这个“选项”方法中处理这个事情? ^^ @TheZenCoder 发布了一个替代方法模板,特定于应用字符串或对象参数的调用模式;虽然没有解决内部init
函数。您的作品可能是 OP 正在寻找的;拥有更多的细节和地址init
函数。干杯:)
@guest271314 您的实现同样有效。我改进了我的答案以支持任何数量的论点等,就像你的答案一样;)
@AlexChizhov 请查看更新。你应该很高兴;)如果你愿意,请接受答案!
@TheZenCoder 这太棒了!非常感谢;)在您的帮助下,下一个版本的插件将更加实用:)【参考方案2】:
试试这个模式
(function ($)
var defaults =
"text": "abcdefg",
, options = $.extend(, defaults, options);
$.fn.plugin = function (options)
var options = (function (opts, def)
var _opts = ;
if (typeof opts[0] !== "object")
_opts[opts[0]] = opts[1];
;
return opts.length === 0
? def
: typeof opts[0] === "object"
? opts[0] : _opts
([].slice.call(arguments), defaults));
return $(this).text(options.text)
(jQuery));
$(".results:eq(0)").plugin(); // return `defaults`
$(".results:eq(1)").plugin("text":"gfedcba"); // return `options`
$(".results:eq(2)").plugin("text", 123); // return `arguments` as `options`
(function ($)
var defaults =
"text": "abcdefg",
, options = $.extend(, defaults, options);
$.fn.plugin = function (options)
var options = (function (opts, def)
var _opts = ;
if (typeof opts[0] !== "object")
_opts[opts[0]] = opts[1];
;
return opts.length === 0
? def
: typeof opts[0] === "object"
? opts[0] : _opts
([].slice.call(arguments), defaults));
return $(this).text(options.text)
(jQuery));
$(".results:eq(0)").plugin(); // return `defaults`
$(".results:eq(1)").plugin("text":"gfedcba"); // return `options`
$(".results:eq(2)").plugin("text", 123); // return `arguments` as `options`
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="results"></div><br />
<div class="results"></div><br />
<div class="results"></div>
【讨论】:
以上是关于jQuery插件 - 初始化后更新设置的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Datatables Jquery 插件销毁表并使用新的更新数据重新初始化同一个表