Desenvolvimento

30 jul, 2012

Desvendando o Plugin jQuery Boilerplate

Publicidade

Construir plugins jQuery pode ser muito divertido e essa é uma atividade feita por muitas pessoas hoje em dia. A equipe do jQuery tornou muito fácil começar a trabalhar na criação de plugins jQuery, tanto que, muitos desenvolvedores de JavaScript que realmente não sabem o que estão fazendo entraram nessa também. Isto leva tanto de código horrível que está por toda a internet. Felizmente, algumas pessoas muito inteligentes vieram com boilerplates do plugins jQuery. Hoje eu vou guiá-lo por um e mostrar como eles tornam a codificação do plugin jQuery mais simples e organizada.

O que é um boilerplate?

Boilerplate é um código concebido como uma base de partida para o seu código. O jQuery boilerplate é o código JavaScript que cria todo o código que normalmente é usado em plugins jQuery. Ele também pode resolver alguns problemas antecipadamente e que você não saberia que existia até tentar fazer um plugin.

Você verá abaixo um exemplo de um boilerplate, que está disponível a partir do jQuery Boilerplate (nome muito original). Você pode encontrar boilerplates diferentes por toda a Internet, incluindo a Websanova. Além disso, Addy Osmani reuniu um monte de jQuery boilerplate em toda a web para que você possa escolher um que você goste.

    // the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, undefined ) {

// undefined is used here as the undefined global variable in ECMAScript 3 is
// mutable (ie. it can be changed by someone else). undefined isn't really being
// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
// can no longer be modified.

// window and document are passed through as local variables rather than globals
// as this (slightly) quickens the resolution process and can be more efficiently
// minified (especially when both are regularly referenced in your plugin).

// Create the defaults once
var pluginName = 'defaultPluginName',
document = window.document,
defaults = {
propertyName: "value"
};

// The actual plugin constructor
function Plugin( element, options ) {
this.element = element;

// jQuery has an extend method which merges the contents of two or
// more objects, storing the result in the first object. The first object
// is generally empty as we don't want to alter the default options for
// future instances of the plugin
this.options = $.extend( {}, defaults, options) ;

this._defaults = defaults;
this._name = pluginName;

this.init();
}

Plugin.prototype.init = function () {
// Place initialization logic here
// You already have access to the DOM element and the options via the instance,
// e.g., this.element and this.options
};

// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function ( options ) {
return this.each(function () {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
}
});
}

}(jQuery, window));

Passo-a-passo

Vamos caminhar passo-a-passo através desse código para que eu possa ajudar explicando o que é, o que faz, e porque é útil. Primeiro, vamos dar uma olhada nas linhas 3 e 53. Aqui temos uma expressão de função de chamada imediata (também conhecida como IIFE ou, se preferir, auto-invocando função anônima). Isto envolve o código do plugin de forma que seja seguro de fora da alteração. Permite-nos, também, enviar jQuery e encurtá-la para o $ sem nos preocuparmos com alguém acionando o noConflict. window e o undefined também foi usado como parâmetro para que pudéssemos usá-los sem medo de alteração (especialmente no caso do undefined, porque nas versões mais antigas do JavaScript, ele era mutável) e porque nos permite encurtar essas referências quando o código é minify, mas é claro que você já sabia disso, porque os comentários nas linhas 5-12 te disseram. Se notou o ponto e vírgula antes do parêntese de abertura na linha 3 e você não sabe ao certo o que é isso, leia os comentários nas linhas 1 e 2.

Agora vamos dar uma olhada nas linhas 15-19. A primeira coisa que você deve observar é que essas variáveis são definidas fora de qualquer função – o IIFE não conta. Isso limita o número de instâncias para a linha 1 (como oposto do 1 para cada vez que o plugin for chamado ou um objeto plugin for instanciado) e os tornam disponíveis para tudo no IIFE. A primeira variável é a pluginName, que deve ser o nome da função que você está estendendo com jQuery. Está referenciado nas linhas 32, 45, 47 e 48. Isso permite que você altere o nome do seu plugin em um só lugar e não em todos os quatro (e mais lugares caso precise fazer referência a ele dentro do código).

A próxima variável é a document, que é apenas uma referência para o documento – frequentemente usado em plugins jQuery -, o que lhe permite ser reduzido por minifiers novamente. A última variável é default. A maioria dos plugins fornece aos usuários opções que eles podem enviar para o plugin e esta variável contém os valores padrão para cada uma das opções que oferece.

Vamos passar para linhas 22-35. Este é o construtor para o objeto que vai fazer todo o trabalho pesado no plugin. O construtor é mínimo; na maioria das vezes apenas cria propriedades de instância e, em seguida, deixa o resto para o init. Indo adiante, this.element mantém o elemento DOM que este plugin deve manipular, this.options contém um objeto com todas as opções que o usuário enviou e quaisquer defeitos que não foram substituídos pelo usuário. O resto é bastante auto-explicativo.

Agora nós estamos olhando para linhas 37-41. Esta é a função init, onde toda a lógica associada a inicialização deste plugin deve ser colocada. Pessoalmente, gostaria de ter escrito esta parte assim:

    Plugin.prototype = {
init: function() {

}
}

Isso faz com que você esteja configurando para iniciar a adição de métodos adicionais para o plugin, se os tiver.

Finalmente, veremos as linhas 45-51. É aqui que iremos realmente estender a jQuery com o nosso plugin. Tal como acontece com praticamente qualquer método jQuery, ele retorna this (na verdade this.each, que ainda retorna this). Isso permite que as pessoas coloquem os métodos jQuery em cadeia. Dentro de each, estamos verificando para ver se temos atribuído um plugin para os dados do objeto DOM. Se tivermos, então não temos nada a fazer por isso, porque o plugin já está instalado e funcionando lá. Se não, crie um objeto plugin novo e adicione-o aos dados do elemento DOM.

Um momento inesquecível

Isso resume este jQuery boilerplate. Aqui você já vê muito do básico sendo feito da forma certa e dá a você um pouco de um framework para começar a construir seu código. Isto, obviamente, não é a única abordagem para jQuery boilerplate.

Como indicado na jqueryboilerplate.com, “embora a ideia de um único boilerplate seja ótima na teoria, a realidade é que no desenvolvimento de plugins, nós raramente os escrevemos de uma forma muito fixa, usando um único padrão o tempo todo”. Isso significa que esta não é uma solução que se encaixa absolutamente em todos os casos e há muitas alternativas por aí. Espero que você tenha aprendido um pouco e esteja animado para fazer seus próprios plugins jQuery boilerplate.

***

Artigo original disponível em: http://www.joezimjs.com/javascript/walking-jquery-plugin-boilerplate/