Imagem post: Tudo que você gostaria de saber sobre plugins jQuery e ninguém teve paciência de explicar
JQuery

Tudo que você gostaria de saber sobre plugins jQuery e ninguém teve paciência de explicar

Pra você que cansou de ser um mero manipulador de plugins alheios

Por
38

Então quer dizer que você anda brincando com jQuery. Volta e meia utiliza uns plugins que mais parecem mágica e se duvidar até se aventurou em criar o seu próprio, acertei?

Acontece que, caso você já saiba desenvolver os seus, talvez possam existir melhores formas de escrevê-lo. Será que você está seguindo as melhores práticas? Será que realmente entende o que está acontecendo por trás de cada linha?

Hoje vou tentar responder as dúvidas mais frequentes, explorando as melhores práticas para se construir um plugin. E no fim lhe mostrar um padrão interessante que você pode seguir agora que já entendeu os conceitos.

A ideia aqui não é simplesmente mostrar como criar um plugin, mas sim como criar direito, explorando tudo o que o jQuery tem de melhor para nos oferecer.

Por que eu deveria construir um plugin?

Encapsulamento e reaproveitamento de código, essas são as palavras-chave. Se você está codificando algo que talvez sirva para futuros projetos, pode ser uma boa encapsular tudo isso em um plugin.

Entendi, quero criar um! Como faz?

Existem diversas formas, mas vamos começar com essa:

$.fn.meuPlugin = function() {
    // aqui vem a lógica
};

Esse é o mínimo que você precisa para iniciar o desenvolvimento de um plugin, basta adicionar uma propriedade ao $.fn.

Por mais trivial que isso possa parecer, muita gente não entende o que está acontecendo por trás disso exatamente. Portanto, antes de evoluirmos esse padrão, vamos recorrer ao código fonte da biblioteca, na sua versão mais recente, para entender de verdade esse pequeno trecho de código.

O que significa o cifrão ($) ?

O famoso $ nada mais é do que um “apelido” para o objeto jQuery. Próximo ao fim do código fonte da biblioteca encontramos a seguinte definição:

window.jQuery = window.$ = jQuery;

Isso significa que o mesmo objeto em memória pode ser referenciado de diversas formas: window.jQuery, window.$, jQuery ou simplesmente $.

Qual a diferença entre $.meuPlugin e $.fn.meuPlugin?

Possivelmente você já se deparou com plugins que não utilizavam a propriedade .fn. Mas afinal, por que eu deveria utilizar o .fn? Por que não apenas $.meuPlugin ao invés de $.fn.meuPlugin?

Novamente, ao nos aventurarmos no código fonte percebemos, logo nas primeiras linhas, como o objeto jQuery é definido.

var jQuery = function( selector, context ) {
    return new jQuery.fn.init( selector, context, rootjQuery );
}

Note que jQuery é uma função e no Javascript uma função é também um objeto do tipo Function. Por isso jQuery.meuPlugin (ou $.meuPlugin) irá atribuir meuPlugin para o objeto jQuery do tipo Function.

Dito isso, voltamos ao código fonte e veremos que jQuery.fn é a mesma coisa que dizer jQuery.prototype.

jQuery.fn = jQuery.prototype;

Portanto, a cada vez que você atribuir uma função (ou propriedade) para jQuery.fn, como em $.fn.meuPlugin, a função estará disponível para todas as instâncias desse objeto.

Isso é importante, pois quando você invoca a função $(), como em $(“#algumID”), uma nova instância é criada nessa linha:

return new jQuery.fn.init( selector, context );

E essa instância terá todos os métodos que atribuirmos ao prototype, mas não todos os métodos que foram atribuídos direto ao objeto Function.

Logo, vá de .fn.

Evite conflitos

Sabia que existem outras bibliotecas Javascript que também utilizam o símbolo cifrão para referenciar seus objetos? Pois é, isso pode lhe causar uma baita dor de cabeça se utilizar apenas aquele primeiro padrão proposto.

Logo, uma boa prática seria encapsular a lógica do plugin em uma função anônima. Assim, garantimos que não irá haver conflito entre o $ do jQuery com o $ de outras bibliotecas.

(function( $ ){
    $.fn.meuPlugin = function() {
        // aqui vem a lógica
    }; 
})( jQuery );

Dessa forma mapeamos o $ para que não seja afetado por nada fora desse escopo.

Não quebre a corrente

Então, você já entendeu como funcionam algumas coisas, vamos criar nosso primeiro plugin! Começaremos com o clássico exemplo de um Tooltip (aquelas caixinhas que aparecem no mouseover).

Criamos então a chamada para o plugin a partir de determinado seletor:

$(function() {
    $(".BlaBlaBla").tooltip();
});

E código do nosso plugin ficará definido assim:

(function( $ ){
    $.fn.tooltip = function() {
        this.css({ background: 'yellow' });
    }; 
})( jQuery );

Aparentemente tudo certo, já que o plugin funciona direitinho, certo?

Na verdade não, pois dessa forma estamos ferindo um dos princípios importantes que diferem os plugins bons dos ruins, e esse princípio se chama encadeamento.

No jQuery é muito comum vermos declarações do tipo:

$('div').show().addClass('BlaBlaBla').fadeIn();

Isso, porque é possível encadear diversas chamadas, a um mesmo seletor. E uma excelente prática por sinal, já que não criamos diversas instâncias como em:

$('div').show();
$('div').addClass('BlaBlaBla');
$('div').fadeIn();

Para permitirmos comportamento similar com nosso plugin basta retornar o this.

(function( $ ){
    $.fn.tooltip = function() {
        return this.each (function() {
            $(this).css({ background: 'yellow' });
        });
    }; 
})( jQuery );

Assim, além de garantirmos o encadeamento, também manipulamos a coleção passada para o plugin através do método each, muito similar a um loop com for por exemplo.

Como passar parâmetros e lidar com eles depois?

E que tal se evoluíssemos nosso plugin e resolvessemos passar como parâmetro a cor de fundo do nosso elemento.

$(function() {
    $(".BlaBlaBla").tooltip({
      'corDeFundo' : 'blue'
    });
}); 

Agora preparamos nosso plugin para receber os parâmetros através da variável options e aplicamos a propriedade corDeFundo no background.

(function( $ ){
    $.fn.tooltip = function(options) {
        return this.each (function() {
            $(this).css({ background: options.corDeFundo });
        });
    }; 
})( jQuery );

Maravilha, funcionou! Mas o que acontece se você resolve mais tarde não passar como parâmetro a cor de fundo? Nosso plugin quebra.

Portanto, não podemos nos esquecer de que precisamos nos preparar para receber esse conjunto de opções e assegurar que, caso não seja passado nenhum valor como parâmetro, nós possamos lidar com valores padrão.

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

        var defaults = {
          'corDeFundo' : 'yellow'
        };

        var settings = $.extend( {}, defaults, options );

        return this.each(function() {
            $(this).css({ background: settings.corDeFundo });
        });

    }; 
})( jQuery );

Para isso recorremos a função $.extend que irá buscar os valores passados pela variável options e mesclar com os valores definidos na variável defaults, armazenando em outra variável chamada settings.

A procura da batida perfeita

Esse é só o começo para você que deseja se aprofundar um pouquinho mais nessa arte de criar plugins, para entender mais visite o guia oficial.

Mesmo que a ideia de se formar um padrão único para criar plugins seja utópico, sugiro fortemente que dê uma olhadinha no jQuery Boilerplate, lá você vai encontrar um padrão bem sólido para iniciar seus projetos, sem contar que a versão traduzida para português foi lançada hoje!

Mas se o buraco for mais em baixo e você for lidar com plugins stateful que controlam o estado dos objetos, confira o jQuery UI Widget Factory.

Lembre-se que o jQuery não é apenas uma caixa preta que faz mágicas pra você. Aventure-se no código fonte e verá que não é nada muito diferente do que você já faz com JavaScript puro.

E é isso, espero que depois desse artigo, você tenha evoluido de um simples “manipulador de plugins” para um criador de fato. Até a próxima!

38

Por Zeno Rocha

Front-end Engineer na empresa norte-americana Liferay, Inc. Já foi desenvolvedor de software na Petrobras e no Globoesporte.com. Curitibano, mora há 5 anos no Rio de Janeiro. Tem 22 anos e é estudante de Sistemas de Informação na Universidade Federal do Estado do Rio de Janeiro.

http://twitter.com/zenorocha

Mais posts do autor

  • Anderlan

    Muito da hora esse seu post, nunca imaginava o que se passava nas entrelinhas do jQuery. Vlw ae fera , sucesso!

  • André Luz

    Mto bom o article ^^ parabens

  • http://twitter.com/ivans_jr Ivan Júnior

    hehe Boa Mano, ótimo artigo.

  • cironunes

    Ótimo artigo Zeno, parabéns!

  • http://leobetosouza.com/ Leonardo Alberto Souza

    Grande, Zeno! Muito bom te ver escrevendo aqui!

    Muito bom passar pra galera a importância de ler o código fonte daquilo que a gente coloca nas nossas aplicações. Seus exemplos foram muito bem colocados! Parabéns!

    Só senti falta de uma parada: avisar que o this dentro do plugin é um jQuery Object e que o desenvolvedor não precisa usar $(this)… mas acho que nem é tão necessário nesse artigo. :D

  • Bruno Pereira

    Legal, obrigado por compartilhar.

  • http://twitter.com/cezar_luiz Cezar Luiz

    Artigo de leitura fácil, simples e muito últil! Parabéns!

  • http://twitter.com/davidsonFellipe davidson fellipe ☭

    Qualidade, Zeno!

  • Jaydson Gomes

    Muito bom o artigo Zeno. Parabéns.

  • http://twitter.com/felipe_leao Felipe Leão

    Ok, e eu achando que ja tava sabendo fazer as coisas minimamente com jQuery. Muito bom lek!

  • zenorocha

    hehehe vivendo e aprendendo. um dia ainda fico fera em python como tu =]

  • http://twitter.com/luiztiago Luiz Tiago Oliveira

    Show de bola, Zeno. Parabéns pelo post e pela estréia! :)

  • Bernardo Fontes

    Fala Zeno! Ficou muito bom o seu texto! Tirou várias dúvidas minhas sobre jQuery e, principalmente, sobre o funcionamento mágico do “fn”!

  • zenorocha

    Excelente adendo, para mais dicas de boas práticas, ver: http://remysharp.com/2010/06/03/signs-of-a-poorly-written-jquery-plugin/

  • VitorGGA

    Mto bom, vou começar a criar uns plugins aqui. Vlw

  • Rodrigo Cesar Nascimento

    parabéns, cara. o artigo está excelente.

  • Deivid Marques

    É realmente muito bom esse artigo cara, Parabéns eu tinha algumas dúvidas que foram bem esclarecidas aqui. Vlw mesmo.

  • Derp

    muito bom o post.
    Era essas coisinhas que eu queria saber.
    Esse site é o melhor

  • Renato de luna

    Tu é o cara Zeno, muito boa matéria e didática nem se fala, ajudou muito, valeu!

  • Frank Gilber

    Muito bm o artigo Zeno!

  • Pedro Rezende

    Muito bom, cara! Ótimo artigo :)

  • BruceEmmanuelSueira

    Bacana Zeno, fazer é fácil, fazer a forma correta é que é o diferencial.

  • João Rodrigues

    Posso repetir o que todo mundo já disse?

    Excelente artigo, parabéns!!! 

  • http://twitter.com/jardel_xavier Jardel Xavier

    Ótmio artigo, parabéns! Obrigado por compartilhar.

  • Pingback: Conheça o jQuery Boilerplate: Entrevista com Zeno Rocha | Plugins | jQuery Brasil

  • http://twitter.com/degenozes Diego Armando

    magavilha

  • Hugo Dias

    Show de bola Zeno !

  • Trambulhao

     Ótimo artigo, parabéns!

  • http://twitter.com/caarlos0 Carlos Alexandro Becker

    Muito bom o artigo,
    Aparentemente a prática de retornar o this, é com o objetivo de fazer um Builder Pattern, ou é impressão minha?

    Parabéns pelo artigo, abraço

  • Alexandre Magno Teles Zimerer

    Muito bom Zeno, há um tempo eu escrevi um post traduzido do Mike Alsup sobre um pattern de desenvolvimento de plugins, ele tem umas dicas boas para complementar o post: http://blog.alexandremagno.net/2008/01/um-padrao-de-desenvolvimento-para-plugins-do-jquery/

  • Penetra

    PERFEITO! :D
    Agora vou desenvolver diversos plugins, graças ao Tableless.
    Muito obrigado. O post é excelente.

  • Fabbiojoe8
  • http://www.facebook.com/mrcodex Marcelo Rocha

    Estou estudando sobre criação de plugins, e este artigo esta sendo de grande ajuda.

  • http://www.facebook.com/nininho.tkd Nininho Tkd

    muito bom cara!!

  • Helam Moreira

    Valew Zeno, artigo mto bom!!

  • http://www.facebook.com/gabriel.magalhaes.santos Gabriel Magalhães Dos Santos

    Aprendi e fiz o meu em 10 minutos hehehehehe, muito bom, util e pratico. Ótimo post!

  • http://www.facebook.com/martin.silva.315213 Martin Silva

    Cara, obrigado por compartilhar estas preciosoas informações.

  • Rodrigo Zem

    muito bom artigo… confesso que dentre os artigos que li, aprendi mais com o seu!!! valew .. acho que foi a linguagem rsrs

Mais artigos