jQuery.fn


//jQuery effin

Davidson Fellipe / @davidsonfellipe / email@fellipe.com



Nov 18, 2011 / já apresentado no riojs, globo.com, sampajs
http://fellipe.com/slides/jqueryfn/demo/

Dúvidas?

O que é um plugin?

um plugin nada mais é que um método do jQuery personalizado para extender as funcionalidades do jQuery Object.

exemplo

Por que criar um plugin?

Por que jQuery?

Apenas a ponta de um iceberg...

Iceberg

http://xstudo.files.wordpress.com/2010/10/iceberg_2.jpg

Repositorio de plugins do jquery

jQuery.fn


html
<p class="element">globoesporte</p>
bgred.js
(function( $ ){
    $.fn.bgRed = function(){
        return this.css({background: 'red'});
    }
})( jQuery );
instância
<script type="text/javascript">
    //seu codigo ira executar assim que o documento estiver pronto, 
    //nao ira esperar todo restante carregar
    $(document).ready(function() {
        $(".element").bgRed();
    });    
</script>

Escrevendo seu primeiro jQuery.fn


  jQuery.fn.myPlugin = function() {
    //seu código
  };
Evitar o uso de $ nesse caso, para não haja conflito com outras bibliotecas

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

Contexto no jQuery.fn


(function( $ ){
  $.fn.myPlugin = function() {
    //seu código
    console.log(this);
  };
})( jQuery );
       
Usar $(this) seria a mesma coisa que fazer $($(this)), pois o this já é um jQuery Object

jQuery.fn plugin interagindo com um conjunto de seletores


(function( $ ){

  $.fn.maiorAltura = function() {

    var max = 0;

    this.each(function() {
      max = Math.max( max, $(this).height() );
    });
    return max;
  };
})( jQuery );
     
$("div").maiorAltura();
http://jsfiddle.net/fellipe/cf6yj/8/ | http://jsfiddle.net/fellipe/D7BWu/8/

jQuery.fn : Enviando parametros


(function( $ ){
    $.fn.bgChange = function( options ) {  

        var settings = {
          'bg' : '#fff'
        };

        if (options) $.extend(settings, options);
        
        $(this).css("background-color", settings.bg);
    };
})( jQuery );
$("body").bgChange({bg: "#f00"}); //vermelho
$("body").bgChange({bg: "#0f0"}); //verde
$("body").bgChange({bg: "#00f"}); //azul
http://jsfiddle.net/fellipe/QnbQR/2/

jQuery.fn : Plugin methods =(


(function( $ ){
    $.fn.tooltip = function( options ) { /* THIS */ };
    $.fn.tooltipShow = function( ) { /* IS */  };
    $.fn.tooltipHide = function( ) { /* BAD */ };
    $.fn.tooltipUpdate = function( content ) { /* !!! */  };
})( jQuery );
                

jQuery.fn : Plugin methods =)


(function( $ ){
    $.fn.tooltip = function() {
      if( $(this).length > 0 ){

       $.extend(this, this.tooltip.methods);

        this.init(options);
      }else{
        $.error('selector not found on tooltip');
      }
    };
    $.fn.tooltip.methods = {
      init : function(  ) {
      }
    };
})( jQuery );

jQuery.fn : Plugin defaults


(function( $ ){
    $.fn.tooltip = function() {
      if( $(this).length > 0 ){

       $.extend(this, this.tooltip.methods);

        this.init(options);
      }else{
        $.error('selector not found on tooltip');
      }
    };

    $.fn.tooltip.defaults = {
      posicaoSeta: "left"
    };

    $.fn.tooltip.methods = {
      init : function(options) {
      }
    };
})( jQuery );

plugin de paginação com jquery.fn | DEMO



(function($) {

    $.fn.Paginacao = function(options) {

      if( $(this).length > 0 ){

        $.extend(this, this.Paginacao.methods);

        this.__init__(options);

        return this;

      }else{
        $.error('selector not found on Paginacao');
        return;
      }
    };

    var _self = this;

    $.fn.Paginacao.defaults = {
      textButton: "mais",
      paginaAtual: 1,
      total: 0,
      urlJSON: "",
      itensPorPagina: 1
    };

    $.fn.Paginacao.methods= {
      __init__: function(options) {},
      __cacheDom__: function() {},
      __configBotaoPaginacao__: function() {},
      __showLoading__: function() {},
      __hideLoading__: function() {},
      __montarNoticia__: function(noticia) {},
      __controleBotoesPaginacao__: function() {},
      __carrega_noticias__: function(){},
      __mostra_mensagem_sem_noticias__: function(){},
      __esconde_mensagem_sem_noticias__: function(){},
      __bindEvents__: function() {}
    };
}(jQuery));
                        

plugin com jquery.fn | DEMO



  /**
   * Description: widget para controlar a paginacao
   * Autor: Davidson Fellipe
   * Dependencias:
   * 1 - jQuery[1.4.2]
   *
  */
  (function($) {
      "use strict";
      $.fn.Paginacao = function(options) {

        if( $(this).length > 0 ){

          $.extend(this, this.Paginacao.methods);

          this.__init__(options);

          return this;
        }else{

          $.error('selector not found on Paginacao');

          return;
        }
      };

      var _self = this;

      $.fn.Paginacao.defaults = {
        textButton: "mais",
        paginaAtual: 1,
        total: 0,
        urlJSON: "",
        itensPorPagina: 1
      };

      $.fn.Paginacao.methods= {

      __init__: function(options) {

        if(options.urlJSON !== ""){

          _self = this;

            //Merge do conteudo de dois ou mais objetos dentro do primeiro.
          _self.options = $.extend({}, $.fn.Paginacao.defaults, options);

          _self.__cacheDom__();

          _self.__configBotaoPaginacao__();
        }
      },

      //realiza cache de elementos DOM
      __cacheDom__: function() {
          _self.domCache = {
            'buttonPaginacao': $(".paginacao", _self),
            'mensagemNenhumaNoticia': $(".mensagem-nenhuma-noticia", _self),
            'listaNoticias': $("ol", _self)
          };
      },

      //configura binds e maquina de estados do botao
      __configBotaoPaginacao__: function() {  
        _self.__bindEvents__();
        _self.__controleBotoesPaginacao__();
      },

      __showLoading__: function() {
        _self.domCache.buttonPaginacao.html('<img src="img/loading.gif" alt="" />');
      },

      __hideLoading__: function() {
        _self.domCache.buttonPaginacao.html(_self.options.textButton);
      },

      __montarNoticia__: function(noticia) {
            return  '<li class="materia" itemscope itemtype="http://schema.org/NewsArticle">' +
                    ' <div class="materia-chamada">' +
                    '   <span class="materia-data" itemprop="publishDate" content="' + noticia.ultima_atualizacao + '">' + noticia.ultima_atualizacao + '</span>' +
                    '   <h3 class="materia-titulo">' +
                    '     <a href="' + noticia.permalink + '" title="' + noticia.titulo + '" itemprop="name">' + noticia.titulo + '</a>' +
                    '   </h3>' +
                    ' </div>' +
                    '</li>';
        },

        __controleBotoesPaginacao__: function() {

          var totalPaginas = Math.ceil(parseInt(_self.options.total, 10)/_self.options.itensPorPagina);

          if(totalPaginas > _self.options.paginaAtual){

            _self.domCache.buttonPaginacao.removeClass("desabilitar-paginacao");
          
          }else{
          
            _self.domCache.buttonPaginacao.addClass("desabilitar-paginacao");
          
          }
        },

      __carrega_noticias__: function(){

        _self.__showLoading__();

        //prepara url para request do json
        var urlRequest = this.options.urlJSON +  (_self.options.paginaAtual + 1) + ".json";

        $.ajax({
              method: 'get',
              dataType: 'json',
              url: urlRequest,
              success: function(response){

                //esconde o loading
                _self.__hideLoading__();
                
                //atualiza configuracoes da rolagem
                _self.options.total = response.totalItens;

                if (response.materias.length > 0){

                  _self.__esconde_mensagem_sem_noticias__();

                  var listaNoticias = "";

                  for( var i = 0, total = response.materias.length; i < total; i++ ){

                    listaNoticias += _self.__montarNoticia__(response.materias[i]);

                  }

                  _self.domCache.listaNoticias.append(listaNoticias);

                  $("li:hidden", _self.domCache.listaNoticias).slideDown("slow");

                  _self.options.paginaAtual++;

                  _self.__controleBotoesPaginacao__();

                }else{

                  _self.__mostra_mensagem_sem_noticias__();
                  
                }
              }
          });
      },

      __mostra_mensagem_sem_noticias__: function(){
        _self.domCache.buttonPaginacao.hide();
        _self.domCache.mensagemNenhumaNoticia.show();
      },

      __esconde_mensagem_sem_noticias__: function(){
        _self.domCache.buttonPaginacao.show();
        _self.domCache.mensagemNenhumaNoticia.hide();
      },

      __bindEvents__: function() {

        _self.domCache.buttonPaginacao.die("click").live("click", function() {
          if(_self.options.total > (_self.options.paginaAtual * _self.options.itensPorPagina)){
            _self.__carrega_noticias__();
          }
        });

      }

    };
  }(jQuery));

Onde eu posso revisar meu código

Alternativas?

jQuery Widget factory

jQuery Boilerplate

links

Obrigado

Davidson Fellipe / @davidsonfellipe / email@fellipe.com
Nov 18, 2011




http://fellipe.com/slides/jqueryfn/demo/