Как иметь несколько экземпляров плагина jQuery на одной странице?
Я пишу простой плагин 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!"
});
Это, очевидно, чрезмерно упрощенный пример, чтобы пересечь точку. Итак, мой вопрос в том, как у меня есть два отдельных экземпляра плагина? Я бы хотел использовать его в нескольких экземплярах на одной странице.
Я предполагаю, что часть проблемы может заключаться в определении переменных в глобальной области. Как я могу определить их уникальные для этого экземпляра плагина, то?
Благодарим вас за руководство!
Ответы
Ответ 1
У меня такая же проблема, но я нахожу очень удобное решение, я опубликую его для тех, у кого может быть эта проблема.
когда вы определяете свои переменные insinde плагина, вы можете использовать .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
Надеюсь, что это поможет
Логан
Ответ 2
Я не уверен, что вы имеете в виду, имея более одного экземпляра плагина. Плагин будет доступен для использования на любом элементе.
Этот комментарий для меня не уточняет:
Так скажите, что это был плагин, который взял параметр "цвет" и повернул объект в этот цвет. Ну, в этом вам понадобится несколько экземпляров, так как вы имеете дело с несколькими страницами элемент, переворачивающий более одного цвета.
В этом случае вы должны передавать разные цвета, если необходимо:
$('div#foo').makeColor('red');
$('div#bar').makeColor('blue');
Каждый раз, когда вы вызываете плагин, он будет использовать любые аргументы, которые вы ему даете. Плагин не является классом, который нуждается в экземплярах.
Ответ 3
Просто бросьте мое решение здесь:
(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 ();
DEMO
Параметр настроек изолируется каждый раз, когда вы инициализируете объект.
Ответ 4
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 factory
http://jqueryui.com/widget/
js code:
$.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);
}
});
И второй (без виджета factory):
(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
Ответ 5
Чтобы ответить на ваш вопрос напрямую, вы можете использовать jQuery.noconflict(), чтобы избежать конфликтов пространства имен и, следовательно, потенциально иметь несколько экземпляров на странице.
var $j = jQuery.noConflict();
// Use jQuery via $j(...)
$j(document).ready(function() {
// etc
проверить здесь
Но я сомневаюсь в твоем дизайне. Почему вы пишете плагин, который, похоже, не работает с обернутым jQuery набором? Плагины должны быть написаны, чтобы предположить, что они работают с массивом jQuery, хранящимся в 'this'. В этом случае любое состояние может храниться в каждом из элементов, на которые воздействует... Но, может быть, вы строите что-то другое?
Просмотрите эту страницу
Ответ 6
вместо написания этого
$("#divid1").samplePlugin();
$("#divid2").samplePlugin();
вы можете сделать это
$.plugin('samplePlugin1', samplePlugin);
$("#divid1").samplePlugin1();
$.plugin('samplePlugin2', samplePlugin);
$("#divid2").samplePlugin2();
У вас может быть много деталей отсюда
http://alexsexton.com/?p=51
Ответ 7
Вам нужно использовать this.foo
вместо var foo
, так что переменная связана только с текущим объектом.
Ответ 8
Это сработало для меня! У меня были определенные параметры, для которых страницы/места я хотел запустить плагин и смог добиться успеха, используя простой оператор 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-->
Ответ 9
У меня была та же проблема: как использовать многие экземпляры плагина только для одной формы?
Обычный способ не выполняется, потому что на самом деле экземпляр не является экземпляром плагина: это экземпляр jQuery.
Таким образом, если определено, что более чем один элемент управляется плагином, каждое определение переопределяет предыдущие параметры.
Нужно было посмотреть на проблему с другой стороны.
Плагин обычно обрабатывается для конкретного события для определенного элемента. например, onclick на кнопке, или когда мышь над элементом.
В моем случае мне пришлось использовать плагин автозаполнения для поля города, но моя форма имеет 5 вкладок и всего 4 поля для городов для 4 различных частей собираемой информации.
Для каждого поля параметры являются специфическими.
Кстати, я понял, что iI не нужно, чтобы плагин активен каждый раз: достаточно только соответствующего события в поле.
Итак, у меня появилась идея: менеджер событий для каждого элемента. Когда событие добавляется, поэтому я определяю действие плагина.
Некоторый код будет более эффективным для объяснения: представьте, что у вас есть 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
});
});
}
});
И это прекрасно работает.
Извините, если мой английский не идеален - надеюсь, вы хорошо понимаете.