我喜欢jQuery插件架构,但是,当我想要保留对插件实例的引用以便稍后在我的代码中访问属性或方法时,我发现它令人沮丧(可能是因为我对此缺乏了解)。
编辑:我想澄清一下,我真正想要做的是保留对插件中使用的方法和属性的引用,以便我以后可以使用它们
让我们以AJAX加载图标为例。在更传统的OOP环境中,我可以这样做:
var myIcon = new AJAXIcon();
myIcon.start();
//some stuff
myIcon.stop();
我的对象的方法和属性存储在变量中供以后使用。现在,如果我想在jQuery插件中拥有相同的功能,我会从我的主代码中调用它,就像这样:
$("#myId").ajaxIcon()
按照惯例,我的插件需要返回传递给我的插件的原始jQuery对象,允许可链接性,但如果我这样做,我就失去了访问插件实例的方法和属性的能力。
现在,我知道您可以在我的插件中声明一个公共函数,有点像
$.fn.ajaxIcon = function(options) {
return this.each(function () {
//do some stuff
}
}
$.fn.ajaxIcon.stop = function() {
//stop stuff
}
但是,如果不违反返回原始jQuery对象的惯例,我就无法保留对我想要引用的插件的特定实例的引用。
我希望能够做到这样的事情:
var myIcon = $("myId").ajaxIcon(); //myIcon = a reference to the ajaxIcon
myIcon.start();
//some stuff
myIcon.stop();
有什么想法吗?
答案 0 :(得分:90)
如果您执行以下操作:
(function($){
$.fn.myPlugin = function(options) {
// support multiple elements
if (this.length > 1){
this.each(function() { $(this).myPlugin(options) });
return this;
}
// private variables
var pOne = '';
var pTwo = '';
// ...
// private methods
var foo = function() {
// do something ...
}
// ...
// public methods
this.initialize = function() {
// do something ...
return this;
};
this.bar = function() {
// do something ...
};
return this.initialize();
}
})(jQuery);
然后您可以访问任何公共方法:
var myPlugin = $('#id').myPlugin();
myPlugin.bar();
这是来自于realevil.com的very helpful article(2009年5月),它本身是来自learningjquery.com的this article(2007年10月)的扩展。
答案 1 :(得分:2)
好的,我想出了如何做到这一点:
插件代码:
$.ajaxIcon.init = function(element, options) {
//your initialization code
this.start = function() {
//start code
}
this.stop = function() {
//stop code
}
}
$.fn.ajaxIcon = function(options) {
this.each(function () {
//This is where the magic happens
jQuery(this).data('ajaxIcon', new jQuery.ajaxIcon.init(this, opts));
});
return this;
}
然后在代码中的其他地方使用它:
var myIcon = $("#myId").ajaxIcon.data('ajaxIcon')
// myIcon: a reference to the 'init' object specific to this plugin instance
myIcon.start();
myIcon.stop();
瞧,回答我自己的问题:)
答案 2 :(得分:0)
我认为你可以用这样的东西来完成你正在寻找的东西:
var myIcon = $("myId").ajaxIcon(); //myIcon = a reference to the ajaxIcon
$.ajaxIcon.start(myIcon);//some stuff
$.ajaxIcon.stop(myIcon);
虽然没有测试过 - 我无法访问我可以执行该操作的环境
答案 3 :(得分:0)
具有所有功能的示例插件:
<script type="text/javascript">
(function( $ ) {
$.fn.PluginX = function( options ) {
// Default variables
// var defaults = {textColor: "#000", backgroundColor: "#fff"}
// var opts = $.extend( {}, defaults, options );
// Or
var settings = $.extend( {}, $.fn.PluginX.defaults, options );
// Private function
var privFunc = function(txt) {
return "Private function " + txt;
};
// Public function
this.pubFunc = function(txt) {
console.log("\r\nPublic function " + txt);
return this;
};
// Public function2
this.pubFunc2 = function(txt) {
console.log("\r\nPublic function " + txt);
// Private from public
privFunc("\r\nPrivate function from public -- " + txt);
return this;
};
// Our plugin implementation code goes here.
return this.each(function() {
// alert(opts.validate);
$(this).on('click',function(){
var elem = $( this );
var markup = elem.text();
console.log("\r\nElement text " + markup);
// Function private
console.log(privFunc(markup));
// External func
console.log($.fn.PluginX.format(markup));
// External function
console.log(external(markup));
});
return this;
});
};
// Variable
$.fn.PluginX.defaults = {
validate: "username"
};
// External Function
$.fn.PluginX.format = function(txt) {
return "<strong>" + txt + "</strong>";
};
// External Function
function external(txt){
return "External " + txt;
}
})(jQuery);
$(document).ready(function() {
var pl = $('.txt').PluginX({validate: "words"}).pubFunc("Hello Public").pubFunc2("Hello Public2");
});
</script>
<p class="txt">Hello Max</p>
<p class="txt">Hello Pax</p>
答案 4 :(得分:-1)
我看到试图完成此操作的大多数jQuery插件将使用匿名范围和闭包来引用该实例独有的函数和变量。例如,使用以下模式:
;(function ($) {
// your code
})(jQuery);
在模块的开头和结尾之间,您可以声明所需的任何功能。您不会污染全局命名空间,并且可以通过闭包保留对局部变量的访问,这可以解决您的许多问题。另外,不要害怕使用$.data
函数。