SlideShare una empresa de Scribd logo
1 de 57
Descargar para leer sin conexión
Indo além com jQuery
#jQuery.fn / #jQuery.factory




Marcos Sousa
falecomigo@marcossousa.com
@marcos_sousa
www.marcossousa.com
Desenvolvimento de aplicações WEB
Desde 2004
Java, .NET, Ruby, Javascript, HTML, CSS e SQL
Introdução ao jQuery
 Motivação/ Histórico/ Características básicas/ Boas práticas
Porque usar jQuery?
Acessível através da variável global

jQuery.myFunctionGoesHere();


ou através do alias

$.myFunctionGoesHere();
Seletores jQuery

$(“#my-element-id”) // busca pelo ID
$(“.my-element-class”) // seleciona pela classe CSS
$(“div:has(input:checked)”) // combinando funções
$(“li:even”).css(“background-color:#333”) //li ímpar
$(“ul#my-list li:first”) // primeiro li
$(“ul#my-list li:last”) // último li
Criando custom selectors

$.expr[“:”].withRel = function(obj){
    var $this = $(obj);
    return ($this.attr("rel") != "")
});
// usage
$(“a:withRel”).css(“background-color:#999”)
Criando elementos

$("<p alt=‘Dynamic content’>My text </p>") 
  .click(function(){  // some click logic }) 
  .attr("id", "test") 
  .addClass("clickable");
Definindo eventos ao elemento


$(“my-cool-div”).bind(“click”, awesomeClick)
$(“ul”).one(“mouseover”, notifyUser)
$(“ul”).delegate(“li”, “click”, makeItWork)
Namespace em eventos


$("div").bind("click.widget", clickFunction); 
$("div").bind("mouseout.widget", mouseFuncion); 
$("div").unbind(".widget");
Eventos personalizados



$("div").bind("drop.widget", dropFn); 
$("div").trigger("drop");
Evitando comportamentos padrão


event.preventDefault(); 
Interrompendo propagação de eventos


event.stopPropagation(); 
Carregando diretamente conteúdo

$("div").load("/users/list #online",
               "‘group’: ‘all’",
               function(){  
    // some work to do after load
});
Nível mais baixo - $.ajax
$.ajax({
    type: "POST",
    url: "/user/create",
    data: "{‘username’: ‘foo’, ‘pwd’: ‘test’}",
   beforeSend: function( xhr ) {
      xhr.overrideMimeType( "application/json" );
    }
}).done(function(){  
    // some work to do after load
});
Filtrando requests

var currentRequests = {};
$.ajaxPrefilter(function(opts, originalOpts,jqXHR){
    if (currentRequests[ opts.url ]) {
       jqXHR.abort();
    }
    currentRequests[ opts.url ] = jqXHR;
});
Criando plugins
 Motivação/ Principais/ $.fn.extend vs $.extend/ Demo
O que são?


São funções customizadas adicionadas
dinamicamente ao objeto jQuery para manipular
elementos DOM
Motivação


 Reutilização de código
 Encapsulamento
 Fácil de criar e usar
Exemplos plugins
 jQuery Validation (http://jquery.bassistance.de/validate)
 Autocomplete (http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete)
 Tip tip (http://code.drewwilson.com/entry/tiptip-jquery-plugin)
 Uniform (http://uniformjs.com)
 Masked Input (http://digitalbush.com/projects/masked-input-plugin)
 Price Format (http://jquerypriceformat.com)
 Custom File Upload (https://github.com/filamentgroup/jQuery-Custom-File-Input)
Criando o plugin com $.fn.method

(function($) {
    $.fn.capitalize = function(options) {
        // implementation goes here
	   };
})(jQuery);
ou através do $.fn.extend

(function($) {
    $.fn.extend({
      capitalize : function(options) {
        // implementation goes here
	     };
    }
})(jQuery);
Importante saber...
  this no contexto do plugin já é um objeto jQuery
  usar each ao manipular ou extrair informações objeto this
   Seletor pode retornar mais de 1 objeto
  retornar este objeto jQuery para não perder a fluência
  usar namespace para métodos, dados e bind de eventos
Importante saber...
     this no contexto do plugin já é um objeto jQuery
     usar each ao manipular ou extrair informações objeto this
      Seletor pode retornar mais de 1 objeto
     retornar este objeto jQuery para não perder a fluência
     usar namespace para métodos, dados e bind de eventos

return this.each(function(){  
    $(this) // this here isn’t jQuery Object
});
WTF jQuery.extend?

$.extend({
    saySomething : function() {
      console.log(“I have to say #ASGATAPIRA!”);
	   }
});
Na prática....

$(“label”).capitalize();
$.capitalize();
$.saySomething();
$(“label”).saySomething();
Capitalize Plugin demo
https://github.com/marcossousa/bhjs-examples/tree/demo1
Trabalhando com parâmetros

var defaults = {  
   forceLowerCase : false
};
var options = $.extend(defaults, options);
Mantendo compatibidade

(function($) {
  ...
})(jQuery);
Ops... 2 plugins?

jQuery.fn.extend({
    capitalize : function(options) {
        // implementation goes here
    },
    uncapitalize : function(options) {
        // implementation goes here
    }
});
Crie namespace e encapsule a chamada

var methods = {
    init : function(options) {
        // implementation goes here
    },
    restore : function() {
        // implementation goes here
    }
}
Delegar a chamada para os métodos
$.fn.capitalize = function(method) {
    if(methods[method]) {
        options = Array.prototype.slice.call(arguments, 1);
        return methods[method].apply(this, options);
    } else if ( typeof method == “object”) {
        return methods.init.apply(this, arguments);
    } else {
        $.error(“The method ” + method + “ doens’t exist”);
    }
};
$(“#my-div”).capitalize(“restore”);
Capitalize with namespace demo
    https://github.com/marcossousa/bhjs-examples/tree/demo2
Widgets UI
Motivação/ $.widget/ Características/ Templates
Gerenciar plugins é difícil

  Reverter ao estado inicial
  Permitir os usuários interagir com eventos gerados
  Alterar configurações após ser chamado
  Evitar múltiplas instâncias para um mesmo elemento
  Encapsular tarefas comuns
Widget Factory

Factories são usadas para criar
diferentes objetos por meio de uma
interface genérica
                                     Que tal usar uma fábrica?
Widget Factory

JQuery UI Widget Factory cria,
baseado em um nome e objeto, um
plugin jQuery e uma “Classe” para
                                    Que tal usar uma fábrica?
encapsular as funcionalidades
Algumas conveniências do $.widget
 Cria um namespace (jQuery.gcom)
 Encapsula a classe (jQuery.gcom.foo.prototype)
 Extende o plugin jQuery (jQuery.fn.foo)
 Estrutura para setup, teardown e alterar opções
 Fácil de chamar callbacks: .trigger(“evento”)
 Métodos acessíveis via: .foo(“metodo”) ou .metodo()
 Permite métodos “privados”
Na prática....
;(function ( $, window, document, undefined) {
    $.widget( “gcom.foo” , {
        options: {
            someValue: null
        },
        _create : function() {
        },
        _destroy: function() {
        },
        foo: function( event ) {
        },
        _setOption: function( key, value ) {
        }
    });
})( jQuery, window, document );
Capitalize demo
https://github.com/marcossousa/bhjs-examples/tree/demo3
Métodos “privados”

 Métodos precedidos com underscore (_foo : function(){})
 Não são acessíveis pela API
  $(“#results”).table(“_hover”); // não funciona
 Para quase tudo na vida dá-se um jeitinho
  $(“#results”).data(“table”)._hover(); //OK
  $.gcom.table.prototype._hover();
Fica fácil trabalhar com eventos

  Permite gerar eventos para o usuário do plugin
   callbackname - Nome do evento que deseja lançar
   eventObject - mock do evento original
   userObject - objeto contendo propriedades úteis
Fica fácil trabalhar com eventos

     Permite gerar eventos para o usuário do plugin
      callbackname - Nome do evento que deseja lançar
      eventObject - mock do evento original
      userObject - objeto contendo propriedades úteis

this.trigger(“hover”, e, { hovered: myObject} );
$(“#my-div”).foo( {hover: function() {} } );
Customizando widgets existentes

$.widget(“ui.dialog”, .ui.dialog, {
    close : function() {
      if(confirm(“Do you really want to?”) {
        this.super(“close”);
        console.log(“OH GOD IF I CATCH U”);
      }
    }
});
usando templates em plugins
<script id="layout" type="text/x-jquery-tmpl">
    <ul id="related-profiles">
      {{template $child}}
    </ul>
</script>
 
<script id="layout" type="text/x-jquery-tmpl">
Paul Benigeri pegou todas, menos a ${username} porque está
no Canadá!
</script>
 
render( "layout", { $child: "content", username: "Luiza" } );
Importante saber...



 O namespace “ui” é reservado para os plugins
 oficiais Jquery UI.
O que fará do seu plugin um sucesso?
Qualidade
                Código bem escrito:
http://docs.jquery.com/JQuery_Core_Style_Guidelines
Compatilidade
“é compatível com versões mais novas?”
Confiança
Bem testado, com suite confíavel, CI (QUnit, Jasmine, etc)
Perfomance
Consumir o mínimo de recurso (http://jsperf.com/)
Tamanho do código
Não passar de alguns KBs minificado e comprimido
Documentação
Facilite a vida de quem for usar sucinta e concisa
Manutenção
responda dúvidas, corrija bugs e aprimore-o
Mais sobre o assunto


http://docs.jquery.com/Plugins/Authoring
https://github.com/addyosmani/jquery-plugin-patterns/
http://docs.jquery.com/JQuery_Core_Style_Guidelines
http://markdalgleish.com/2011/05/creating-highly-configurable-jquery-
plugins/

Más contenido relacionado

Destacado

It Takes Two to Tango: an Exploration of Domain Pairs for Cross-Domain Collab...
It Takes Two to Tango: an Exploration of Domain Pairs for Cross-Domain Collab...It Takes Two to Tango: an Exploration of Domain Pairs for Cross-Domain Collab...
It Takes Two to Tango: an Exploration of Domain Pairs for Cross-Domain Collab...Shaghayegh (Sherry) Sahebi
 
Say YES - Your Energy Secrets
Say YES - Your Energy SecretsSay YES - Your Energy Secrets
Say YES - Your Energy SecretsSree Nidhi S K
 
資訊新聞心得報告
資訊新聞心得報告資訊新聞心得報告
資訊新聞心得報告guestc8a309
 
MAPP - Managing Attitudes & Performance Potential
MAPP - Managing Attitudes & Performance PotentialMAPP - Managing Attitudes & Performance Potential
MAPP - Managing Attitudes & Performance PotentialSree Nidhi S K
 
維基經濟學 第一章
維基經濟學 第一章維基經濟學 第一章
維基經濟學 第一章guestc8a309
 
Dando os primeiros passos com rails
Dando os primeiros passos com railsDando os primeiros passos com rails
Dando os primeiros passos com railsMarcos Sousa
 
RECORRIDO CIENTÍFICO POR MADRID
RECORRIDO CIENTÍFICO POR MADRIDRECORRIDO CIENTÍFICO POR MADRID
RECORRIDO CIENTÍFICO POR MADRIDJUAN MIGUEL NIETO
 
Retail Growth Strategies
Retail Growth StrategiesRetail Growth Strategies
Retail Growth Strategiestarshant009
 
Predicting Student Performance in Solving Parameterized Exercises
Predicting Student Performance in Solving Parameterized ExercisesPredicting Student Performance in Solving Parameterized Exercises
Predicting Student Performance in Solving Parameterized ExercisesShaghayegh (Sherry) Sahebi
 
10 Myth Pres Espanol
10 Myth Pres   Espanol10 Myth Pres   Espanol
10 Myth Pres Espanollarryc77
 

Destacado (11)

It Takes Two to Tango: an Exploration of Domain Pairs for Cross-Domain Collab...
It Takes Two to Tango: an Exploration of Domain Pairs for Cross-Domain Collab...It Takes Two to Tango: an Exploration of Domain Pairs for Cross-Domain Collab...
It Takes Two to Tango: an Exploration of Domain Pairs for Cross-Domain Collab...
 
Say YES - Your Energy Secrets
Say YES - Your Energy SecretsSay YES - Your Energy Secrets
Say YES - Your Energy Secrets
 
資訊新聞心得報告
資訊新聞心得報告資訊新聞心得報告
資訊新聞心得報告
 
MAPP - Managing Attitudes & Performance Potential
MAPP - Managing Attitudes & Performance PotentialMAPP - Managing Attitudes & Performance Potential
MAPP - Managing Attitudes & Performance Potential
 
維基經濟學 第一章
維基經濟學 第一章維基經濟學 第一章
維基經濟學 第一章
 
Design Equals Limits
Design Equals LimitsDesign Equals Limits
Design Equals Limits
 
Dando os primeiros passos com rails
Dando os primeiros passos com railsDando os primeiros passos com rails
Dando os primeiros passos com rails
 
RECORRIDO CIENTÍFICO POR MADRID
RECORRIDO CIENTÍFICO POR MADRIDRECORRIDO CIENTÍFICO POR MADRID
RECORRIDO CIENTÍFICO POR MADRID
 
Retail Growth Strategies
Retail Growth StrategiesRetail Growth Strategies
Retail Growth Strategies
 
Predicting Student Performance in Solving Parameterized Exercises
Predicting Student Performance in Solving Parameterized ExercisesPredicting Student Performance in Solving Parameterized Exercises
Predicting Student Performance in Solving Parameterized Exercises
 
10 Myth Pres Espanol
10 Myth Pres   Espanol10 Myth Pres   Espanol
10 Myth Pres Espanol
 

Indo alem jquery3