jquery — fonctionnalités avancées
Post on 21-Jun-2015
5.366 Views
Preview:
TRANSCRIPT
Rémi Prévost — ConFoo 2011
jQueryfonctionnalités avancées
Rémi Prévost
@remi + http://remiprevost.com
Développeur Web
Butde cette présentation
Pasun tutoriel/pitch jQuery
But
Survoldes fonctionnalités moins connues
But
Sa forceCourbe d’apprentissage facile
But
$(".surprise").click(function() { $(this).fadeOut("slow");});
Ensuite?Beaucoup plus de possibilités
But
1.0 → 1.545 Ko → 208 Ko
2006 2011
But
• Utilitaires• Événements• Animations• Manipulations• Parsers• Data• Deferreds
But
UtilitairesPour sauver du temps
Implémentationsnatives
Utilitaires
$Ne touchent pas aux objets natifs
Utilitaires
$.mapModifie chaque élément d’un tableau
Utilitaires
var noms = ["jack", "kate", "john", "james", "claire"]
$.map(noms, function(nom) { return nom.toUpperCase(); });=> ["JACK", "KATE", "JOHN", "JAMES", "CLAIRE"]
$(".user-name").map(function() { return $(this).text(); } );=> ["@remi", "@garno", "@jmlacroix", "@vincentroyc"]
$.grepFiltre un tableau
Utilitaires
var personnes = [ { nom: "Jack Sheppard", evil: false }, { nom: "Benjamin Linus", evil: true }, { nom: "Kate Austen", evil: false }];
$.grep(personnes, function(p) { return p.evil });=> [{ nom: "Benjamin Linus", evil: true }]
$.grep(personnes, function(p) { return p.evil }, false);=> [{ nom: "Jack Sheppard", … }, { nom: "Kate Austen", … }]
$.inArrayVérifie la présence d’éléments
Utilitaires
var numeros = [4, 8, 15, 16, 23, 42];
$.inArray(numeros, 16);=> 3
$.inArray(numeros, 64);=> -1
$.mergeFusionne deux tableaux
Utilitaires
var tailies = ["libby", "bernard", "eko"];var middlies = ["jack", "charlie", "eko"];
$.merge(tailies, middlies);=> ["libby", "bernard", "eko", "jack", "charlie", "eko"]
$.extendFusionne deux objets
Utilitaires
function push_button(options) { options = $.extend({ delay: 108, input: [4, 8, 15, 16, 23, 42] }, options); return "Wait for "+options.delay+" minutes.";}
push_button({ delay: 64 });=> "Wait for 64 minutes."
$.extend($.easing, { customEasing : function(p, n, firstNum, diff) { return firstNum - diff / p; }});
Utilitaires
• $.map• $.grep• $.inArray• $.merge• $.extend
Pas assez?Underscore.js
Utilitaires
Utilitaires
• _.reduce• _.uniq• _.keys• _.values• _.times
ÉvénementsLier et déclencher
BaseÉvénements faciles
Événements
$(".element").click(function() {});$(".element").dblclick(function() {})
$(".element").mouseover(function() {});$(".element").mouseout(function() {});
$(".element").keyup(function() {});$(".element").keydown(function() {});$(".element").keypress(function() {});
$(".element").bind("click", function() {});$(".element").bind("dblclick", function() {})
$(".element").bind("mouseover", function() {});$(".element").bind("mouseout", function() {});
$(".element").bind("keyup", function() {});$(".element").bind("keydown", function() {});$(".element").bind("keypress", function() {});
$(".element").bind({ click: function() {}, dblclick: function() {}, mouseover: function() {}, mouseleave: function() {}});
ArbitrairesDéclencher n’importe quoi (vraiment)
Événements
$.fn.bind("anything", function() { // this});
$.fn.trigger("anything");
$("#element").bind("anything", function() { // this});
$("#element").trigger("anything");
Méthodesévénementielles
Événements
$("#vote-count").bind("increase", function() { $(this).text(parseInt($(this).text) + 1);});
$("#upvote-button").bind("click", function() { $("#vote-count").trigger("increase");});
function increase_vote_count() { var elem = $("#vote_count"); elem.text(parseInt(elem.text()) + 1);}
$("#upvote-button").bind("click", increase_vote_count);
function VoteCount(selecteur) { this.element = $(selecteur); this.increase = function() { this.element.text(parseInt(this.element.text()) + 1); }}
vote_count = new VoteCount("#vote-count");
$("#upvote-button").bind("click", function() { vote_count.increase();});
ArgumentsEncore plus personnalisables
Événements
$(".tweets").bind("add-tweet", function(event, tweet) { $(this).append("<li>"+tweet.text+" — @"+tweet.user+"</li>");})
$(".tweets").trigger("add-tweet", [{ user: "garno", text: "Tweeting live from @remi’s presentation at #confoo!"}])
Toutpeut être lié à un événement
Événements
var Island = { is_magic: true };
$(Island).bind("move", function() { alert(this.is_magic); // true});
$(Island).trigger("move");
$.fn.livePour les éléments inexistants
Événements
$("#tweets a.user").live("click", function() { // Faire quelque chose});
$(document).bind("click", function(event) { if ($(event.target).is("#tweets a.user")) { // Faire quelque chose }})
$(".user").live("click", function() { // Faire quelque chose});
$(document).bind("click", function(event) { if ($(event.target).is(".user")) { // Faire quelque chose }})
$.fn.delegatePlus performant que $.fn.live
Événements
$("#tweets").delegate("a.user", "click", function() { // Faire quelque chose});
$("#tweets").bind("click", function(event) { if ($(event.target).is("a.user")) { // Faire quelque chose }})
$.fn.dieLe contraire de « live »
Événements
$("#tweets a.user").bind("click", function() { // Quelque chose});
$("#tweets *").unbind("click");
$("#tweets a.user").live("click", function() { // Faire quelque chose});
$("a.user").die("click"); // ne fonctionnera pas$("#tweets a.user").die("click"); // fonctionne!
$.fn.undelegateLe contraire de « delegate » (duh)
Événements
$("#tweets").delegate("a.user", "click", function() { // Faire quelque chose});
$("#tweets").undelegate("a", "click"); // ne fonctionne pas!$("body").undelegate("#tweets a.user", "click"); // non plus!
$("#tweets").undelegate("a.user", "click"); // fonctionne!
NamespacesPour éviter la confusion
Événements
// contenu de application.js$("#contenu a.user").bind("click", function() { // Faire quelque chose avec un utilisateur…});
// contenu de janalytics.js$("a").bind("click", function() { // Enregistrer ce “click”});
$("a").unbind("click"); // retire *tous* les “click”
// contenu de janalytics.js$("a").bind("click.jAnalytics", function() { // Enregistrer ce “click”});
$("a").unbind("click.jAnalytics"); // tous les “click”
$("a").unbind(".jAnalytics"); // tous les événements
• $.fn.bind• $.fn.trigger• $.fn.live + $.fn.die• $.fn.delegate + $.fn.undelegate• Namespaces
Événements
AnimationsAu-delà de « fadeOut »
BaseAnimations faciles
Animations
$("#menu").slideUp();$("#menu").slideDown();$("#menu").slideToggle();
$("#fantome").fadeIn();$("#fantome").fadeOut();$("#fantome").fadeToggle();
$.fn.animateAnimations pour « power-users »
Animations
$("#element").animate({ left: "-=200px", height: "toggle", width: "toggle"},{ duration: 1000, easing: "linear", complete: function() {}, step: function() {}, queue: false, specialEasing: { height: "easeIn", width: "easeOut" }});
$.fn.queueGérer la file d’attente
Animations
$("#element-1").animate({ fontSize: "14em" }).animate({ width: "+=200px" }).animate({ height: "+=200px" });
$("#element-2").animate({ fontSize: "14em" }, { queue: false }).animate({ width: "+=200px" }).animate({ height: "+=200px" });
$.fn.delayAnimer avec un délai
Animations
$("#element").animate({ fontSize: "14em" }).delay(1000).animate({ width: "+=200px" }).delay(1000).animate({ height: "+=200px" });
$.fn.delayPas seulement pour les animations
Animations
$("#ajax-mais-tantot").delay(2000).queue(function() { $(this).load("/ajax_content.html")});
$("#element").bind("click", function() { $(this).delay(2000).queue(function() { $(this).css("background", "yellow"); });});
$.fx.offSoyons gentils avec les plus lents
Animations
$.fx.off = true;
• $.fn.animate• $.fn.queue• $.fn.delay• $.fx.off
Animations
SupportTester la compatibilité du navigateur
$.browserVous devriez l’éviter
Support
if ($.browser.webkit) { // Chose que seulement Webkit supporte (pour l’instant)} else if ($.browser.mozilla) { // Chose que seulement Gecko supporte (pour l’instant)} else if ($.browser.msie) { // Chose que seulement IE supporte (pour l’instant)}
ImplémentationPas réputation
Support
if (typeof window.WebSocket != "undefined") { // Quelque chose de cool avec les sockets} else { // Quelque chose de cool en… AJAX?}
$.supportVous devriez le modifier
Support
$.support.ajax$.support.boxModel$.support.hrefNormalized$.support.opacity
$.extend($.support, {
webSockets : (function() { return typeof window.WebSocket != "undefined" }).call(),
canvas : (function() { var canvas = document.createElement("canvas"); return !!(canvas.getContext && canvas.getContext("2d")); }).call()
});
if ($.support.canvas) { // Quelque chose de cool avec <canvas>} else { // Quelque chose de cool… des images?}
Pas assez?Modernizr
Support
Support
• Modernizr.borderradius• Modernizr.geolocation• Modernizr.localstorage• Modernizr.draganddrop• Modernizr.addTest
ManipulationsModifier le DOM facilement
BaseManipulations faciles
Manipulations
$(".article").append("<div class=\"share-this\"></div>");
$("<strong>!!!</strong>").insertAfter(".important");
$("Attention! Spoiler").insertBefore(".spoiler");
$(".no-javascript-message").remove();
$("<foo />")Création de noeuds DOM jQuery
Manipulations
var ennemi = $("<div />", { "class": "ennemi", text: "|---0-0---|", data: { name: "Blinky" }, click: function() { alert($(this).data("name")+ " a été cliqué!"); }});
ennemi.appendTo(".planche-de-jeu")ennemi.css("background", "cyan");
$.fn.cloneCloner des noeuds
Manipulations
$(".dolly").clone().appendTo("#ferme");
$(".dolly").clone(true).appendTo("#ferme");
$(".dolly").clone(true, false).appendTo("#ferme");
$.fn.detachSupprimer du DOM seulement
Manipulations
$("#lacet").bind("boucler", function() { alert("yay!") });
var lacet = $("#lacet").detach(); // #lacet n’est plus dans le DOM
lacet.appendTo("#souliers");// #lacet est de retour dans le DOM
lacet.trigger("boucler"); // yay!
ParsersAnalyseurs intégrés à jQuery
$.parseJSONAnalyse de JSON
Parsers
var data = '{ "name": "John Locke" }';var person = $.parseJSON(data);
person.name=> "John Locke"
$.parseXMLParcourir du XML comme du HTML
Parsers
var data = "<personne><nom>John Locke</nom></personne>"; data += "<personne><nom>James Ford</nom></personne>";
var personnages = $($.parseXML(data));
personnages.find("personne").map(function() {return $(this).find("nom").text().split(" ")[0];
});=> ["John", "James"]
DataStocker des données
$.fn.dataDes données dans des objets jQuery
Data
$(".unstoppable-button").data("count", 0);
$(".unstoppable-button').bind("click", function() { $(this).data("count", $(this).data("count") + 1);});
// Afficher le “count” du bouton$(".report-button").bind("click", function() { var count = $(".unstoppable-button").data("count"); alert("The other button has been clicked "+count+" times");});
// Remettre le "count" à zéro$(".reset-button").bind("click", function() { $(".unstoppable-button").data("count", 0);});
// Supression de toutes les méta-données du bouton$(".unstoppable-button").removeData();
Événementsde données
Data
// Modification du "get"$(".unstoppable-button").bind("getData", function(event, key) { if (key == "count") { return jQuery.data(this, key) * 2; }});
$(".unstoppable-button").data("count", 10);$(".unstoppable-button").data("count");=> 20
$("#slideshow").data("position", 0).bind({ "forward" : function() { $(this).data("position", $(this).data("position") + 1); }, "backward" : function() { $(this).data("position", $(this).data("position") - 1); }, "changeData", function(event, key, value) { if (key != "position") { return true; } if (value >= $(this).children().length) { jQuery.data(this, "position", 0); } else if (value == -1) { jQuery.data(this, "position", $(this).children().length - 1); } }});
$("#slideshow").trigger("forward"); // position=1$("#slideshow").trigger("forward"); // position=2$("#slideshow").trigger("forward"); // position=0$("#slideshow").trigger("backward"); // position=2
HTML5 dataStocker de façon sémantique
Data
AvantDes données dans les attributs HTML
Data
<!-- HTML --><li rel="5" class="story"><a href="#">Show</a></li>
// Javascript$("li.story a").click(function() { var id = $(this).parent().attr("rel"); $("#content").load("/stories/"+id);});
<!-- HTML --><li rel="5|remi" class="story"><a href="#">Show</a></li>
// Javascript$("li.story a").click(function() { var data = $(this).parent().attr("rel").split("|"); var id = data[0]; var user = data[1]; $("#content").load("/"+user+"/stories/"+id);});
AprèsLe plugin $.metadata
Data
<!-- HTML --><li class="story {id:5}"><a href="#">Show</a></li>
// Javascript$("li.story a").click(function() { var data = $(this).parent().metadata(); $("#content").load("/stories/"+data.id);});
<!-- HTML --><li class="story {id:5,user:'remi',category:6}"><a href="#">Show</a></li>
// Javascript$("li.story a").click(function() { var data = $(this).parent().metadata(); $("#content").load("/"+data.user+"/stories/"+data.id);});
MaintenantLes attributs « data » de HTML5
Data
<!-- HTML --><li data-id="5" class="story"><a href="#">Show</a></li>
// Javascript$("li.story a").click(function() { var id = $(this).parent().data("id"); $("#content").load("/stories/"+id);});
<!-- HTML --><div data-remote="foo" class="block-1"></div><div data-remote="true" class="block-2"></div>
// Javascript$("div.block-1").data("remote");=> "foo"
$("div.block-2").data("remote");=> true
• $.fn.data• Événements « getData » + « setData »• $.fn.attr• $.metadata• $.fn.data + HTML5
Data
DeferredGestion facile de callbacks
$.DeferredRésolution, rejet et attente
Deferred
var request = $.Deferred();
request.done(function() { alert("succes!"); });request.fail(function() { alert("erreur!"); });
request.resolve();=> "succes!"
// OU
request.reject();=> "erreur!"
Deferred AJAXExemple classique
Deferred
var request = $.get("/feed")
request.done(function(data) { console.log(data.user.name);});
request.fail(function(error) { console.log(error.message);});
var request = $.get("/feed")
request.done(function(data) { console.log(data.user.name);});
request.fail(function(error) { console.log(error.message);});
var request = $.get("/feed")
request.done(function(data) { console.log(data.user.name);});
request.fail(function(error) { console.log(error.message);});
$.fn.thenDéclarer des callbacks
Deferred
var request = $.get("/feed");
request.then( function() { alert("done!"); }, function() { alert("failed!"); });
$.fn.whenGérer des deferred multiples
Deferred
var request = $.get("/feed")
$.when(request).then( function() { alert("done!") }, function() { alert("failed!") });
var request1 = $.get("/feed")var request2 = $.get("/users")
$.when(request1, request2).then( function() { alert("everything has succeed!") }, function() { alert("something has failed.") });
PossibilitésUn wrapper d’API
Deferred
// Exemple par Michael Bleigh (intridea.com)Twitter = { search: function(query) { var dfr = $.Deferred(); $.ajax({ url: "http://search.twitter.com/search.json", data: { q: query }, dataType: "jsonp", success: dfr.resolve }); return dfr.promise(); }}
Twitter.search("#confoo").done(function(data) { alert(data.results[0].text);});
• $.Deferred• $.fn.resolve• $.fn.reject• $.fn.then• $.fn.when
Deferred
BrefFonctionnalités avancées
• api.jquery.com• james.padolsey.com• jaubourg.net• ejohn.org/apps/workshop/adv-talk
Ressources
Questions?Commentaires?
@remi
top related