Паттерн плагина jQuery
Здравствуйте. Разъясните пожалуйста часть конструкции для плагина.
Почти все разобрал что за что отвечает но не понятно концовка. Не могли бы вы объяснить работу строк отмеченных условными комментариями. ;(function($) { var defaults = { }; function Nupoll(element, options) { var widget = this; widget.config = $.extend({}, defaults, options); widget.element = element; this.init(); } Nupoll.prototype.init = function() { }; $.fn.pluginNew = function(options) { new Nupoll(this.first(), options); // ?????????? return this.first(); // ?????????? }; } (jQuery) ); |
new Nupoll(this.first(), options);
Создается экземпляр Nupoll (вызывается конструктор Nupoll). this.first() - первый элемент из коллекции. return this.first() - возвращаем первый элемент, чтобы можно было продолжить цепочку вызовов: $(el).pluginNew().continueChain() Если плагин должен обработать каждый элемент из коллекции, то обычно делают так: $.fn.pluginNew = function(options) { return this.each(function(){ // do stuff }); } |
То есть получается если у меня плагин должен подключатся не к одному к нескольким элементам я использую такой вариант паттерна:
;(function($) { var defaults = { }; function Nupoll(element, options) { var widget = this; widget.config = $.extend({}, defaults, options); widget.element = element; this.init(); } Nupoll.prototype.init = function() { // код плагина }; $.fn.pluginNew = function(options) { return this.each(function(){ // do stuff }); }; } (jQuery) ); |
prison47, изучите сначала основы JavaScript, потом уже учитесь делать плагины для jQuery.
<script src="//code.jquery.com/jquery-latest.min.js"></script> <script> (function($) { $.fn.pluginNew = function(options) { return this.each(function(){ $(this).css('color', 'red'); }); }; } (jQuery) ); </script> <div>Bla bla</div> <div>Тест</div> <script> $('div').pluginNew(); </script> |
Основы я как раз таки изучаю и вот такие конструкции не могу понять, в первом случае код плагина мы пишем в Nupoll.prototype.init = function() {
где уже есть доступ к дом элементу. Во втором случае приведенном вами почему-то все отсекается, тот же конструктор. Если у вас есть ссылки где можно подробнее почитать на доходчивом языке, буду признателен :) |
Если вы не заметили, в моем "плагине" не используются какие-то собственные методы, опции и прочее.
this.each(fn) проходит по всем элементам коллекции и вызывает для каждого элемента функцию fn, устанавливая в качестве контекста этот элемент. Делайте с этим элементом что хотите. Я например просто изменил css свойство. Вы можете создавать какие-то объекты к примеру. Цитата:
Цитата:
|
Спасибо
|
Подскажите пожалуйста. В плагине вешаю обработчики клика через on() на ново появляющиеся элементы. Подключаю плагин к нужному элементу. Все работает. Но если нужно подключить плагин на еще один элемент например для срабатывания с другими параметрами, то обработчики клика начинают дублироваться. Если подключить на три элемента, то утраиваются. Что я неправильно делаю? Или многократное подключение плагина вообще не должно быть? Тогда как сделать срабатывание на нескольких элементах с разными параметрами?
|
prison47,
обычно метку ставят если элемент обработан плагином то второй раз его ненадо -- если нужно по новой метку убирают навешивают по новой обработчики и ставят метку |
А подробней если можно? Не совсем понимаю
|
prison47,
$.fn.pluginNew = function(options) { return this.each(function(){ if ($(this).data('on')) return; $(this).data('on', true) // do stuff }); } |
Странно но почему то не работает. Если я правильно понял нужно так?:
$.fn.pluginNew = function(options) { return this.each(function(){ if ($(this).data('on')) return; $(this).data('on', true) foo.on(....); }); } |
Странно, тот же код, но почему то работает...
<script src="//code.jquery.com/jquery-latest.min.js"></script> <script> (function($) { $.fn.pluginNew = function(options) { return this.each(function(){ if ($(this).data('on')) return; $(this).data('on', true) /*foo.on(....);*/alert('Че-нибудь делаем'); }); } } (jQuery) ); </script> <button onclick="$(this).pluginNew()">Нажми меня полностью</button> |
Точнее я неправильно выразился :) Работать то работает но все равно дублирует
|
prison47,
код дубляжа можно? |
prison47, но ведь алерт вылетает только при первом нажатии. Значит все ок :)
|
$body.on('click.noteOverlay', '#general_overlay', function(){ var genThis = $(this).siblings('[data-case]'); removeOverCase(genThis); }); |
prison47,
лучше небольшое демо чем часть кода |
prison47, это решение всех твоих проблем. Изучи как следует:
options = options || {}; index = options.index || 0; if (!selector || options.live === false) { that.unbind('click.fb-start').bind('click.fb-start', run); } else { D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); } this.filter('[data-fancybox-start=1]').trigger('click'); return this; |
Понял, спасибо буду разбираться что к чему!
|
Вот как-то так.
<script src="//code.jquery.com/jquery-latest.min.js"></script> <script> ;(function($) { $.fn.pluginName = function( settings ) { var settings = $.extend( { }, settings); return this.each(function() { var element = $(this); $('.foo').click(function(){ alert($(this)); }); }); }; }) (jQuery) ; </script> <style> .foo{ width:100px; height:100px; background: #000; } </style> <button onclick="$(this).pluginName()">Нажми </button> <button onclick="$(this).pluginName()">Нажми 2</button> <div class='foo'></div> |
Цитата:
|
prison47,
<!DOCTYPE HTML> <html> <head> <title></title> <meta charset="utf-8" /> <style type="text/css"> #general_overlay{ background-color: #FF0099; width: 300px; height: 50px; } </style> </head> <body> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> (function($) { $.fn.pluginName = function( settings ) { var settings = $.extend( { }, settings); return this.each(function() { var element = $(this); if($('#general_overlay').length) {alert('No pasarán'); return} ; if(!$('#general_overlay').length){ $("<div id='general_overlay'></div>").appendTo($('body')); }; var genOverlay = $('#general_overlay'); element.click( function(){ genOverlay.show(); }); $('body').on('click.overPop', '#general_overlay', function(){ $(this).hide(); // console.log($(this)); }); }); }; }) (jQuery) ; </script> <button onclick="$(this).pluginName()">Нажми </button> <button onclick="$(this).pluginName()">Нажми 2</button> </body> </html> |
Спасибо за оформление, вот получается если произвожу клик на диве overlay он удаляется а в консоле this проходит два раза.
А в этом коде не могу разобраться, я незнаю значение переменных , например D options = options || {}; index = options.index || 0; if (!selector || options.live === false) { that.unbind('click.fb-start').bind('click.fb-start', run); } else { D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); } this.filter('[data-fancybox-start=1]').trigger('click'); return this; |
Цитата:
|
prison47,
лучше скажите как вы хотите чтоб это работало |
Понимаете у меня "плагин" он вешается например на кнопку. При клике на кнопку в конец бади добавляется див оверлей с display:none. Потом добавляется еще один див с определенной информацией он позиционирован в угол браузера. Кликаем на этот див с информацией он позиционируется в центр экрана а див оверелей появляется dispaly:block и затемняет экран. По принципе как в лайт боксах. Потом кликаем один раз на див оверлей он скрывается а второй див удаляется. Так вот клик на скрытие оверлея я вешаю через on(). Если вешать плагин на один элемент на странице (кнопку) то все ок, если на два то обработчик on() срабатывает 2 раза!
Точнее в конец бади оверлей добавляется сразу. А див с информацией при нажатии |
prison47, извините но пока из ваших попыток в который раз обьяснить что вы хотите , я в который раз ничего непонял, может вам не плагин нужен?
|
Цитата:
Цитата:
|
prison47,
или сделали так if(!$('#general_overlay').length){ $("<div id='general_overlay'></div>").appendTo($('body')); $('body').on('click.overPop', '#general_overlay', function(){ $(this).hide(); console.log($(this)); }); }; |
Вот отбросил все что отвлекает.
;(function($) { $.fn.homerTwice = function( settings ) { var settings = $.extend( { }, settings); return this.each(function() { var element = $(this); if(!$('#general_overlay').length){ // проверяем если данного дива нет на странице то добавляем его, в стилях дисплей none $("<div id='general_overlay'></div>").appendTo($('body')); }; var genOverlay = $('#general_overlay'); element.click( function(){ genOverlay.show(); // кликаем по кнопке, наш див #general_overlay появляется }); $('body').on('click.overPop', '#general_overlay', function(){ // кликаем на диве #general_overlay он исчезает $(this).hide(); console.log($(this)); // если плагин вешается например на две кнопки ( $('#btn_1').homerTwice(); $('#btn_2').homerTwice(); ), то происходит двойное срабатывание нажатия }); }); // this each close }; }) (jQuery) ; |
prison47,
$('body').on тогда надо ставить в конец 15 строки |
Да действительность оказалось настолько очевидным :-?
СПАСИБО ПРЕОГРОМНОЕ!!! |
А как быть если мы вешаем обработчик на изменения окна браузера?
$(window).off('resize.noteResize').on('resize.noteResize', function(){ console.log($(this)); }); В консоль this записывается два раза (при условие что плагин подключен дважды). Если использовать без .off('resize.noteResize') тогда this записывается 4 раза. Пробовал через .data() решить проблему. Тоесть повесить проверку если .data() у windows не существует то повесить обработчик и записать для windows .data(). Но все равно дублирует. В чем я сделал ошибку? if(! $.hasData(window) ){ $(window).data('foo'); $(window).on('resize.noteResize', function(){ console.log($(this)); }); }; А вот если подключить плагин 3 раза или 1 раз, this записывается все равно 2 раза. Я так понял это все таки не двойное навешивание обработчика. |
Цитата:
resize => 1.обнулили таймер 2. поставили таймер 3. таймер сработал сделал всё что нужно. resize это серия event -- надо/желательно дождаться последнего. |
Часовой пояс GMT +3, время: 15:32. |