我正在编写一个简单的jQuery插件,但是我无法在页面上使用多个实例。
例如,这是一个示例插件来说明我的观点:
(function($) {
$.fn.samplePlugin = function(options) {
if (typeof foo != 'undefined')
{
alert('Already defined!');
} else {
var foo = 'bar';
}
};
})(jQuery);
然后如果我这样做:
$(document).ready(function(){
$('#myDiv').samplePlugin({}); // does nothing
$('#myDiv2').samplePlugion({}); // alerts "Already defined!"
});
这显然是一个过于简化的例子来说明问题。 所以我的问题是,我如何拥有两个单独的插件实例?我希望能够在同一页面上的多个实例中使用它。
我猜测问题的一部分可能是在全局范围内定义变量。那么如何定义它们对插件实例的唯一性呢?
感谢您的指导!
答案 0 :(得分:17)
我有同样的问题,但我找到一个非常方便的解决方案,我会发布给可能有这个问题的人
当您在插件中定义变量时,您可以使用.data()来存储您定义的所有变量
像这样(function($) {
$.fn.samplePlugin = function(options) {
var base = this;
this.foo // define foo
// do stuff with foo and other variables
// Add a reverse reference to the DOM object
this.data("pluginname", base);
};})(jQuery);
当你想使用相同的foo变量时,你应该用这个来反复引用:
base = this.data("pluginname");
base.foo
希望有所帮助
洛根
答案 1 :(得分:2)
我不确定拥有多个插件实例的含义。插件可用于任何元素。
这条评论对我来说并不太清楚:
所以说这是一个插件 一个“颜色”参数并转向 把对象变成那种颜色。嗯,在那 例如,你需要多个实例 你正在处理多个页面 元素转动多种颜色。
在这种情况下,您可以根据需要传递不同颜色的参数:
$('div#foo').makeColor('red');
$('div#bar').makeColor('blue');
每次调用插件时,它都会使用您提供的任何参数。该插件不是需要实例的类。
答案 2 :(得分:2)
把我的解决方案放在这里:
(function ($){
$.fn.plugin = function (options){
var settings = $.extend({}, $.fn.plugin.defaults, options);
settings.that = $(this);
$.fn.plugin.init (settings);
};
$.fn.plugin.defaults = { objval: 'default' };
$.fn.plugin.init = function (settings){
settings.that.val (settings.objval);
};
}( jQuery ));
$('#target1').plugin ({objval: 'not default'});
$('#target2').plugin ();
每次初始化对象时,都会隔离设置变量。
答案 3 :(得分:2)
HTML:
<code class="resize1">resize1</code>
<code class="resize2">resize2</code>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('.resize1').ratiofix({message:'resize1'});
$('.resize2').ratiofix({message:'resize2'});
});
</script>
我找到了2个解决方案 - 第一个是jquery小部件工厂 http://jqueryui.com/widget/ js代码:
$.widget("custom.ratiofix",{
options:{
message:"nothing"
},
_create:function (){
var self=this;
this.setListeners();
},
setListeners:function (){
var self=this;
$(window).on('resize',$.proxy(self.printMsg,self));
},
printMsg:function (){
console.log(this.options.message);
}
});
第二个(没有小部件工厂):
(function ($){
var Ratiofix = {
init: function(options, elem) {
this.options = $.extend({},this.options,options);
this.elem = elem;
this.$elem = $(elem);
this.setListeners();
return this;
},
options: {
message: "No message"
},
printMsg: function(){
console.log(this.options.message);
},
setListeners:function (){
var self=this;
this.$elem.on('click',function (){
console.log(self.options.message);
});
$(window).on('resize',$.proxy(self.printMsg, self));
}
};
$.fn.ratiofix=function (options){
this.init= function(options, elem) {
this.options = $.extend({},this.options,options);
this.elem = elem;
this.$elem = $(elem);
return this;
};
if ( this.length ) {
return this.each(function(){
var ratiofix = Object.create(Ratiofix);
ratiofix.init(options, this);
$.data(this, 'ratiofix', ratiofix);
});
}
};
})(jQuery);
在这两种情况下,插件都可以单独工作并拥有自己的设置。在我的情况下 - 2个小部件监听窗口调整大小并打印到控制台自己的options.message
答案 4 :(得分:1)
要直接回答您的问题,您可以使用jQuery.noconflict()来避免命名空间冲突,从而可能在页面上有多个实例化。
var $j = jQuery.noConflict();
// Use jQuery via $j(...)
$j(document).ready(function() {
// etc
检查here
但我质疑你的设计。你为什么要编写一个似乎不能在jQuery包装集上运行的插件?应该编写插件,假设它们在'this'中保存的jQuery数组上运行。在这种情况下,任何状态都可以存储在每个被采取行动的项目中......但也许你正在构建不同的东西?
请查看this page
答案 5 :(得分:1)
而不是写这个
$("#divid1").samplePlugin();
$("#divid2").samplePlugin();
你可以这样做
$.plugin('samplePlugin1', samplePlugin);
$("#divid1").samplePlugin1();
$.plugin('samplePlugin2', samplePlugin);
$("#divid2").samplePlugin2();
你可以从这里获得很多细节 http://alexsexton.com/?p=51
答案 6 :(得分:1)
您需要使用this.foo
而不是var foo
,以便变量仅与当前对象相关。
答案 7 :(得分:-1)
这对我有用!我有一些特定的参数,用于我想要运行插件的页面/地点,并且能够通过使用简单的if语句获得成功。希望这有助于某人!
<!-- Begin JQuery Plugin Foo -->
<script src="js/foo_fun.js"></script>
<?php
if(substr_count(strtolower($currentUrl),"member")>0)
{
?>
<script>
$(document).ready(function(){
$('#vscroller').vscroller({newsfeed:'news_employee.xml', speed:1000,stay:2000,cache:false});
});
</script>
<?php
}
else
{
?>
<script>
$(document).ready(function(){
$('#vscroller').vscroller({newsfeed:'news_company.xml', speed:1000,stay:2000,cache:false});
});
</script>
<?php
}
?>
<!-- End JQuery Foo-->
答案 8 :(得分:-4)
我遇到了同样的问题:如何在一个表单上使用多个插件实例? 通常的方法失败,因为实际上,实例不是插件的实例:它是jQuery的一个实例。 因此,如果定义了多个元素由插件管理,则每个定义都会覆盖以前的参数。
有必要从另一方面看问题。
插件通常用于对特定元素的特定事件做出反应。例如,单击按钮,或当鼠标悬停在元素上时。 在我的情况下,我必须为城市字段使用自动完成插件,但我的表单有5个选项卡,总共4个字段用于城市,用于收集信息的4个不同部分。 对于每个字段,参数都是细节。
顺便说一句,我已经意识到我不需要每次都让插件处于活动状态:只需在场上的相应事件就足够了。
所以我有了一个想法:每个元素的事件管理器。当事件追加时,我定义了插件动作。 有些代码可以更有效地解释:想象你有3个div块,你的插件必须改变颜色,但具体的颜色取决于哪个div受影响。
$(document).ready(function(){
// Wich elements are affected by the plugin
var ids = ['myDiv1','myDiv2','myDiv3'];
// foe each one :
for (v in ids)
{
//define from an event :
$('#'+ ids[v]).focus(function()
{
// depending which id is active :
var aParams, idDiv = $(this).attr('id');
// Choosing the right params
switch(idDiv)
{
case 'myDiv1':
aParams = {'color': '#660000', 'background-color': '#0000ff'};
break;
case 'myDiv2':
aParams = {'color': '#006600', 'background-color': '#ff00ff'};
break;
case 'myDiv3':
aParams = {'color': '#000066', 'background-color': '#ff0000'};
break;
default:
aParams = {'color': '#000000', 'background-color': '#ffffff'};
};
// Defining the plugin on the right element with the right params
$(this).myPlugin(
{
colors: aParams
});
});
}
});
这很好用。
对不起,如果我的英语不完美 - 我希望你能理解。