带有方法和全局回调的 jQuery 插件
Posted
技术标签:
【中文标题】带有方法和全局回调的 jQuery 插件【英文标题】:jQuery plugin with methods & global callbacks 【发布时间】:2012-11-09 16:07:39 【问题描述】:我想创建一个同时具有方法和回调的 jQuery 插件,方法可以工作,但我无法让回调工作,回调的范围让我感到困惑,
(function($)
var methods =
create: function(options)
var defaults =
width: 320,
height: 240,
background: '#000',
onstop: function()
;
var options = $.extend(defaults, options);
return $(this).each(function(i)
console.log('create');
);
,
stop: function(options)
var defaults =
onstop: function()
;
var options = $.extend(defaults, options);
return $(this).each(function(i)
console.log('stop');
options.onstop.call();
);
;
$.fn.myplugin = function(option)
if (methods[option])
return methods[option].apply( this, Array.prototype.slice.call(arguments, 1));
else if (typeof option === 'object' || ! option)
return methods.create.apply(this, arguments);
else
$.error('Method ' + option + ' does not exist in jQuery.plugin');
;
)(jQuery);
所以在<script>
:
$(document).ready(function()
$('#start').click( function()
$('#myvideo').myplugin('create', onstop: function() console.log('on stop'); );
);
$('#stop').click( function()
$('#myvideo').myplugin('stop');
);
);
基本上,我似乎想让 onstop: function() 对插件全局化
/* ======== 更新代码(见 cmets) ======== */
(function($)
var callbacks =
onready: $.Callbacks("once memory unique").add(function()
//console.log('onready');
),
ondeny: $.Callbacks("unique").add(function()
//console.log('ondeny');
),
onerror: $.Callbacks("unique").add(function()
//console.log('onerror');
),
onstop: $.Callbacks("unique").add(function()
//console.log('onstop');
)
;
var methods =
construct: function()
,
create: function(options)
var defaults =
width: 320,
height: 240,
background: '#000',
onready: function(),
onstop: function()
;
var options = $.extend(defaults, options);
return this.each(function(i, elements)
for (var prop in options)
if (prop in callbacks)
callbacks[prop].add(options.prop);
callbacks.onready.fire();
);
,
stop: function()
return this.each(function(i, elements)
callbacks.onstop.fire();
);
;
$.fn.myplugin = function(option)
if (methods[option])
return methods[option].apply( this, Array.prototype.slice.call(arguments, 1));
else if (typeof option === 'object' || ! option)
return methods.construct.apply(this, arguments);
else
$.error('Method ' + option + ' does not exist in jQuery.plugin');
;
)(jQuery);
【问题讨论】:
回调应该由插件的用户设置,不是吗? 我想让它们作为选项访问 【参考方案1】:我建议使用一些成熟的 jQuery.Callbacks
对象:
var callbacks =
onready: $.Callbacks("once memory unique").add(function()
console.log('ready');
),
ondeny: $.Callbacks("unique").add(function()
console.log('deny');
),
onerror: $.Callbacks("unique").add(function()
console.log('error');
),
onstop: $.Callbacks("unique").add(function()
console.log('stop');
)
;
现在,当您获得一些新选项时,您可以这样做
for (var prop in options)
if (prop in callbacks)
callbacks[prop].add(options[prop]);
然后调用它们就行了
callbacks.onstop.fire(/*args*/);
或者,如果您关心回调的上下文,请使用fireWith
。
【讨论】:
起初这似乎有效,但我忘记了我还有另一个 console.log(),我很好奇“曾经的记忆独特”和“独特”等是做什么的?我添加了回调,例如 onready: $.Callbacks("onready").add(function() console.log('onready'); ),我还在 'create' 方法中将它们添加为选项,但它们目前似乎没有开火。还在纠结... 好吧,我发现了“独特”之类的。将代码更新为我现在拥有的代码,仍然没有触发回调。$('#start').click( function() $('#myvideo').myplugin('create', onready: function() console.log('!on ready!'); , onstop: function() console.log('!on stop!'); ); );
这不记录
糟糕,修复了循环中向回调添加函数的小问题。顺便说一句,我不确定您是否要分离应用插件的每个元素的回调,因为那时您不能使用静态 callbacks
对象。在.each
-loop 中添加回调也没什么用,因为它们只会在没有unique
标志的情况下再次添加。【参考方案2】:
我使用 globalOptions 变量将插件初始化选项存储为全局,
这是用于测试和用作模板的两个文件。
jquery.plugin.js (函数($)
var pluginName = 'myPlugin';
var globalOptions = '';
var methods =
create: function(options)
var defaults =
backgroundColor: '#000',
color: '#fff',
oncreate: function(),
onchangecolor: function(),
onloadpage: function(page)
;
globalOptions = $.extend(defaults, options);
return $(this).each(function(i, elements)
$(elements).data('globalOptions', globalOptions);
globalOptions.oncreate();
);
,
changeColor: function()
return $(this).each(function(i, elements)
globalOptions = $(elements).data('globalOptions');
if (!globalOptions) $.error('Error: ' + pluginName + ' has not been initialized yet'); return false;
$(this).css('background-color', globalOptions.backgroundColor);
$(this).css('color', globalOptions.color);
globalOptions.onchangecolor();
);
,
loadPage: function(options)
return $(this).each(function(i, elements)
globalOptions = $(elements).data('globalOptions');
if (!globalOptions) $.error('Error: ' + pluginName + ' has not been initialized yet'); return false;
globalOptions.onloadpage(options.page);
location.href = options.page;
);
;
$.fn.myPlugin = function(option)
if (methods[option])
return methods[option].apply(this, Array.prototype.slice.call(arguments, 1));
else if (typeof option === 'object' || ! option)
return methods.create.apply(this, arguments);
else
$.error('Error: Method "' + option + '" does not exist in ' + pluginName);
return false;
;
)(jQuery);
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Example</title>
<script src="jquery.min.js"></script>
<script src="jquery.plugin.js"></script>
<script>
$(document).ready(function()
var myElement = $('.container').myPlugin(
color: '#555',
backgroundColor: '#ddd',
oncreate: function()
console.log('Callback: create');
,
onchangecolor: function()
console.log('Callback: onchangecolor');
,
onloadpage: function(page)
console.log('Callback: onloadpage = '+page);
);
$('.color').click(function(event)
myElement.myPlugin('changeColor');
);
$('.page').click(function(event)
myElement.myPlugin('loadPage', page: '#test' );
);
);
</script>
</head>
<body>
<div class="container">
<button class="color">changeColor</button> <button class="page">loadPage</button>
</div>
</body>
</html>
如果有人有更好的方法和添加“私有”方法的方法,请分享。 :)
【讨论】:
以上是关于带有方法和全局回调的 jQuery 插件的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript之jQuery-9 jQuery 开发插件(添加新全局函数添加jQuery对象方法添加新简写方法方法参数)