Escrevendo Plugins jQuery
Por Marcelo Fraga
@marcelofraga




                    #zigottolabs
Por que jQuery?
 Compatibilidade

 Manipulação de eventos

 Manipulação DOM

 Animações

 Interações Ajax




                          #zigottolabs
JavaScript
        var addEvent = function(type, el, func) {
          if (el.addEventListener) {
            el.addEventListener(type, func, false);
          } else {
            el.attachEvent('on' + type, func);
          }
        };

        var link = document.getElementById('link');

        addEvent('click', link, function() {
          // código
        });

                                                      #zigottolabs
jQuery


         $('#link').click(function() {
           // código
         });




                                         #zigottolabs
Por que criar um plugin jQuery?
 Evita colisões usando namespaces

 Fácil de criar

 Organiza códigos complexos

 Reutilização




                                    #zigottolabs
Como criar um plugin jQuery

          jQuery.fn.pluginName = function() {
            // código
          };

          $(‘div’).pluginName();




                                                #zigottolabs
Proteja o jQuery
 Auto-invocando função anônima

 Passando jQuery para o $, evitando colisões com outras bibliotecas




                            (function($) {
                              $.fn.pluginName = function() {
                                // código
                              };
                            })(jQuery);




                                                                      #zigottolabs
Iterando
 Não há necessidade de usar o $(this) porque “this” já é um objeto jQuery

                (function($) {
                  $.fn.maxHeight = function() {
                     var max = 0;

                     this.each(function() {
                        max = Math.max(max, $(this).height());
                     };

                     return max;
                  };
                })(jQuery);

                $(‘div’).maxHeight();
                // ==> retorna a altura da div mais alta da página


                                                                            #zigottolabs
Mantenha o encadeamento
Retorna o “this”, mantendo o encadeamento para poder continuar a ser manipulado por métodos
jQuery, tais como .css().

                     (function($) {
                       $.fn.lockDimensions = function(type) {
                          return this.each(function() {
                            var $this = $(this);

                            if (!type || type == ‘width’) {
                              $this.width($this.width());
                            }

                            if (!type || type == ‘height’) {
                              $this.height($this.height());
                            }
                          });
                       };
                     })(jQuery);

                     $(‘div’).lockDimensions(‘width’).css(‘color’, ‘#f00’);
                                                                              #zigottolabs
Extendendo as opcões
Extend é similar ao método merge do Ruby, entre outras linguagens

                              (function($) {
                                $.fn.tooltip = function(options) {
                                   var settings = $.extend({
                                     location: ‘top’,
                                     background: ‘#ccc’
                                   }, options);

                                   return this.each(function() {
                                      // código
                                   };
                                };
                              })(jQuery);

                              $(‘div’).tooltip({
                                location: ‘left’
                              });
                                                                     #zigottolabs
Plugin Métodos
Um único plugin não deve ter mais de um namespace no objeto jQuery.fn

                          (function($) {
                            $.fn.tooltip = function(options) {
                               // código
                            };

                             $.fn.tooltipShow = function() {
                                // código
                             };

                             $.fn.tooltipHide = function() {
                                // código
                             };

                            $.fn.tooltipUpdate = function(content) {
                               // código
                            };
                          })(jQuery);
                                                                        #zigottolabs
Errado!
E qual o jeito certo?
Plugin Métodos
Encapsulando os métodos em um objeto literal , sendo chamado pelo nome do método e em seguida
quaisquer parâmetros adicionais
 (function($) {
   var methods = {
      init: function(options) { // código },
      show: function() { // código },
      hide: function() { // código },
      update: function(content) { // código }
   };

   $.fn.tooltip = function(method) {
      if (methods[method]) {
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
      } else if (typeof method === ‘object’ || !method) {
        return methods.init.apply(this, arguments);
      } else {
        $.error(‘Method ‘ + method + ‘ does not exists on jQuery.tooltip’);
      }
   };
 })(jQuery);
                                                                             #zigottolabs
Dados
Ajuda a manter o controle de variáveis e estado entre chamadas de métodos a partir do seu plugin

Usando em um objeto literal, torna o acesso mais fácil a todas as propriedades
                  (...)

                  init: function(options) {
                    return this.each(function() {
                       var $this   = $(this),
                           data    = $this.data(‘tooltip’),
                           tooltip = $(‘<div/>’, { text: $this.attr(‘title’) });

                         if (!data) {
                           $this.data(‘tooltip’, {
                              target: $this,
                              tooltip: tooltip
                           });
                         }
                       });
                  };

                  (...)                                                          #zigottolabs
Dados
Quando necessário, permite a remoção dos dados


                           (...)

                           destroy: function(options) {
                             return this.each(function() {
                                var $this = $(this),
                                    data = $this.data(‘tooltip’);

                                  data.tooltip.remove();
                                  $this.removeData(‘tooltip’);
                                });
                           };

                           (...)




                                                                    #zigottolabs
Eventos
Uma boa prática é criar um namespace para o evento

Quando precisar desvincular o evento, pode fazê-lo sem interferir com outros eventos que poderiam ter
sido vinculados ao mesmo tipo de evento

                             (...)

                             init: function(options) {
                                return this.each(function() {
                                  $(window).bind(‘resize.tooltip’, function() {
                                     // código
                                  }
                                });
                             };

                             destroy: function(options) {
                                return this.each(function() {
                                  $(window).unbind(‘resize.tooltip’);
                                });
                             };

                             (...)                                                #zigottolabs
#zigottolabs
Fonte
http://docs.jquery.com/Plugins/Authoring

Escrevendo plugins JQuery

  • 1.
    Escrevendo Plugins jQuery PorMarcelo Fraga @marcelofraga #zigottolabs
  • 2.
    Por que jQuery? Compatibilidade Manipulação de eventos Manipulação DOM Animações Interações Ajax #zigottolabs
  • 3.
    JavaScript var addEvent = function(type, el, func) { if (el.addEventListener) { el.addEventListener(type, func, false); } else { el.attachEvent('on' + type, func); } }; var link = document.getElementById('link'); addEvent('click', link, function() { // código }); #zigottolabs
  • 4.
    jQuery $('#link').click(function() { // código }); #zigottolabs
  • 5.
    Por que criarum plugin jQuery? Evita colisões usando namespaces Fácil de criar Organiza códigos complexos Reutilização #zigottolabs
  • 6.
    Como criar umplugin jQuery jQuery.fn.pluginName = function() { // código }; $(‘div’).pluginName(); #zigottolabs
  • 7.
    Proteja o jQuery Auto-invocando função anônima Passando jQuery para o $, evitando colisões com outras bibliotecas (function($) { $.fn.pluginName = function() { // código }; })(jQuery); #zigottolabs
  • 8.
    Iterando Não hánecessidade de usar o $(this) porque “this” já é um objeto jQuery (function($) { $.fn.maxHeight = function() { var max = 0; this.each(function() { max = Math.max(max, $(this).height()); }; return max; }; })(jQuery); $(‘div’).maxHeight(); // ==> retorna a altura da div mais alta da página #zigottolabs
  • 9.
    Mantenha o encadeamento Retornao “this”, mantendo o encadeamento para poder continuar a ser manipulado por métodos jQuery, tais como .css(). (function($) { $.fn.lockDimensions = function(type) { return this.each(function() { var $this = $(this); if (!type || type == ‘width’) { $this.width($this.width()); } if (!type || type == ‘height’) { $this.height($this.height()); } }); }; })(jQuery); $(‘div’).lockDimensions(‘width’).css(‘color’, ‘#f00’); #zigottolabs
  • 10.
    Extendendo as opcões Extendé similar ao método merge do Ruby, entre outras linguagens (function($) { $.fn.tooltip = function(options) { var settings = $.extend({ location: ‘top’, background: ‘#ccc’ }, options); return this.each(function() { // código }; }; })(jQuery); $(‘div’).tooltip({ location: ‘left’ }); #zigottolabs
  • 11.
    Plugin Métodos Um únicoplugin não deve ter mais de um namespace no objeto jQuery.fn (function($) { $.fn.tooltip = function(options) { // código }; $.fn.tooltipShow = function() { // código }; $.fn.tooltipHide = function() { // código }; $.fn.tooltipUpdate = function(content) { // código }; })(jQuery); #zigottolabs
  • 12.
    Errado! E qual ojeito certo?
  • 13.
    Plugin Métodos Encapsulando osmétodos em um objeto literal , sendo chamado pelo nome do método e em seguida quaisquer parâmetros adicionais (function($) { var methods = { init: function(options) { // código }, show: function() { // código }, hide: function() { // código }, update: function(content) { // código } }; $.fn.tooltip = function(method) { if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === ‘object’ || !method) { return methods.init.apply(this, arguments); } else { $.error(‘Method ‘ + method + ‘ does not exists on jQuery.tooltip’); } }; })(jQuery); #zigottolabs
  • 14.
    Dados Ajuda a mantero controle de variáveis e estado entre chamadas de métodos a partir do seu plugin Usando em um objeto literal, torna o acesso mais fácil a todas as propriedades (...) init: function(options) { return this.each(function() { var $this = $(this), data = $this.data(‘tooltip’), tooltip = $(‘<div/>’, { text: $this.attr(‘title’) }); if (!data) { $this.data(‘tooltip’, { target: $this, tooltip: tooltip }); } }); }; (...) #zigottolabs
  • 15.
    Dados Quando necessário, permitea remoção dos dados (...) destroy: function(options) { return this.each(function() { var $this = $(this), data = $this.data(‘tooltip’); data.tooltip.remove(); $this.removeData(‘tooltip’); }); }; (...) #zigottolabs
  • 16.
    Eventos Uma boa práticaé criar um namespace para o evento Quando precisar desvincular o evento, pode fazê-lo sem interferir com outros eventos que poderiam ter sido vinculados ao mesmo tipo de evento (...) init: function(options) { return this.each(function() { $(window).bind(‘resize.tooltip’, function() { // código } }); }; destroy: function(options) { return this.each(function() { $(window).unbind(‘resize.tooltip’); }); }; (...) #zigottolabs
  • 17.
  • 18.