Javascript JQuery插件,多个实例同一页面;应用于元素类和唯一元素ID;使用$.data保护选项;公共访问功能
我这是第一次编写JQuery插件——几乎就在那里——并试图找到最好的“样板文件”来满足以下需求 这是我的问题:Javascript JQuery插件,多个实例同一页面;应用于元素类和唯一元素ID;使用$.data保护选项;公共访问功能,javascript,jquery,jquery-plugins,boilerplate,Javascript,Jquery,Jquery Plugins,Boilerplate,我这是第一次编写JQuery插件——几乎就在那里——并试图找到最好的“样板文件”来满足以下需求 这是我的问题: 我不能让插件通过它们的类名来处理元素 这是有效的: var myPlugin = $('#single').myPlugin(); // Yes - it gets initialised myPlugin.doAFunction(" Some Params "); // Yes - public access func works 此无效: var myPluginFo
我不能让插件通过它们的类名来处理元素
这是有效的:
var myPlugin = $('#single').myPlugin(); // Yes - it gets initialised
myPlugin.doAFunction(" Some Params "); // Yes - public access func works
此无效:var myPluginFooClass = $('.foo').myPlugin(); // Yes, it gets initialised
myPlugin.doAFunction(" Some Params "); // NO - now this falls over
以下是我需要实现的目标:
- 同一页上有多个实例
- 每个实例都有自己的变量,部署时不会被其他实例覆盖(我使用的是$.data)
- 公共访问功能只影响该实例,而不影响其他实例强>
- 实例可以通过其id(#myElement)部署到单个元素上
- 实例可以按类(.foo)部署到元素上-这是不起作用的
(function($){
$.fn.myPlugin = function(options) {
// support multiple elements
if (this.length > 1){
this.each(function() { $(this).myPlugin(options) });
return this;
}
// -- private variables --
var $this = $(this);
// default settings
var defaults = {
initialText: 'I have been initialized'
};
// Merge defaults with setup options
var options = $.extend({}, defaults, options);
// Protect final options, placing inside jQuery element data
$this.data('myPlugSettings', options);
// Shortcut var to access option data
var settings = $this.data('myPlugSettings');
// private methods
var fooPrivate = function() {
// do something private ...
};
// public methods
this.changeText = function(param) {
$this.text(param);
};
// Constructor
this.init = function() {
$this.text( settings.initialText );
// Return this for chainability?
return this;
};
return this.init();
}
})(jQuery);
// globals
_ = {
myPlugin: null,
myPluginTwo: null,
myPluginFoo: null
}
// Button Event handlers
$("#btnLoadPlugs").click(function(e) {
_.myPlugin = $('#single').myPlugin({
initialText: "Custom initial text"
});
_.myPluginTwo = $('#anotherSingle').myPlugin();
_.myPluginFoo = $('.foo').myPlugin();
});
$("#btnGoSingle").click(function(e) {
_.myPlugin.changeText(" Worked on single ID ");
});
$("#btnGoAnotherSingle").click(function(e) {
_.myPluginTwo.changeText(" Worked again here ");
});
$("#btnGoFoo").click(function(e) {
// THIS FALLS OVER ???????????
_.myPluginFoo.changeText(" foos get this ");
});
这里的问题很容易理解。TLDR
\uuu0.mypluginfo
使用changeText
方法释放对jQuery对象的引用
// support multiple elements
if (this.length > 1){
this.each(function() { $(this).myPlugin(options) });
// Send the collection back.
return this;
}
只是为了让它发挥作用
// This will work, but this is not exactly what you have intended.
_.myPluginFoo.each(function(key, value) {
$(value).myPlugin().changeText('Hello');
});
为什么?
这是Sizzle选择器引擎的预期行为,$(“#unique”)
调用将返回带有单个HtmleElement的jQuery集合实例,可由$(“#unique”)[0]
访问
通过在$.fn.myPlugin
中将$('#unique')
修改为this
,您将获得一个带有changeThext
属性的结果对象
this.length>1//true
通过调试以下代码,您将很容易注意到差异:
$("#btnLoadPlugs").click(function(e) {
// ...
console.log(_.myPluginTwo); // Single object.
console.log(_.myPluginFoo); // A collection, without changeText method.
});
$。您正在使用的数据保护不是很有效
更好的方法
如果有意义的话,您还可以实现类似于$('.foo').myPlugin('changeText','newtext')
的东西
看一看,这是jQuery插件最好的地方之一。您返回这个
而没有其他东西运行if(this.length>1){this.each(function(){$(this.myPlugin(options)});返回this;}
Yea!!!所以我们从上面删除并返回此
,它将按预期工作!唯一的障碍是在这种情况下它会破坏链式能力,对吧-但是。。。我猜你不能既有蛋糕又吃!谢谢你,谢谢你。回答得真不错。上面链接的JQuery样板文件也提供了一些很好的解决方案。