jquery — fonctionnalités avancées

134
Rémi Prévost — ConFoo 2011 jQuery fonctionnalités avancées

Upload: remi-prevost

Post on 21-Jun-2015

5.368 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: jQuery — fonctionnalités avancées

Rémi Prévost — ConFoo 2011

jQueryfonctionnalités avancées

Page 2: jQuery — fonctionnalités avancées

Rémi Prévost

@remi + http://remiprevost.com

Développeur Web

Page 3: jQuery — fonctionnalités avancées

Butde cette présentation

Page 4: jQuery — fonctionnalités avancées

Pasun tutoriel/pitch jQuery

But

Page 5: jQuery — fonctionnalités avancées

Survoldes fonctionnalités moins connues

But

Page 6: jQuery — fonctionnalités avancées

Sa forceCourbe d’apprentissage facile

But

Page 7: jQuery — fonctionnalités avancées

$(".surprise").click(function() { $(this).fadeOut("slow");});

Page 8: jQuery — fonctionnalités avancées

Ensuite?Beaucoup plus de possibilités

But

Page 9: jQuery — fonctionnalités avancées

1.0 → 1.545 Ko → 208 Ko

2006 2011

But

Page 10: jQuery — fonctionnalités avancées

• Utilitaires• Événements• Animations• Manipulations• Parsers• Data• Deferreds

But

Page 11: jQuery — fonctionnalités avancées

UtilitairesPour sauver du temps

Page 12: jQuery — fonctionnalités avancées

Implémentationsnatives

Utilitaires

Page 13: jQuery — fonctionnalités avancées

$Ne touchent pas aux objets natifs

Utilitaires

Page 14: jQuery — fonctionnalités avancées

$.mapModifie chaque élément d’un tableau

Utilitaires

Page 15: jQuery — fonctionnalités avancées

var noms = ["jack", "kate", "john", "james", "claire"]

$.map(noms, function(nom) { return nom.toUpperCase(); });=> ["JACK", "KATE", "JOHN", "JAMES", "CLAIRE"]

Page 16: jQuery — fonctionnalités avancées

$(".user-name").map(function() { return $(this).text(); } );=> ["@remi", "@garno", "@jmlacroix", "@vincentroyc"]

Page 17: jQuery — fonctionnalités avancées

$.grepFiltre un tableau

Utilitaires

Page 18: jQuery — fonctionnalités avancées

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", … }]

Page 19: jQuery — fonctionnalités avancées

$.inArrayVérifie la présence d’éléments

Utilitaires

Page 20: jQuery — fonctionnalités avancées

var numeros = [4, 8, 15, 16, 23, 42];

$.inArray(numeros, 16);=> 3

$.inArray(numeros, 64);=> -1

Page 21: jQuery — fonctionnalités avancées

$.mergeFusionne deux tableaux

Utilitaires

Page 22: jQuery — fonctionnalités avancées

var tailies = ["libby", "bernard", "eko"];var middlies = ["jack", "charlie", "eko"];

$.merge(tailies, middlies);=> ["libby", "bernard", "eko", "jack", "charlie", "eko"]

Page 23: jQuery — fonctionnalités avancées

$.extendFusionne deux objets

Utilitaires

Page 24: jQuery — fonctionnalités avancées

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."

Page 25: jQuery — fonctionnalités avancées

$.extend($.easing, { customEasing : function(p, n, firstNum, diff) { return firstNum - diff / p; }});

Page 26: jQuery — fonctionnalités avancées

Utilitaires

• $.map• $.grep• $.inArray• $.merge• $.extend

Page 27: jQuery — fonctionnalités avancées

Pas assez?Underscore.js

Utilitaires

Page 28: jQuery — fonctionnalités avancées

Utilitaires

• _.reduce• _.uniq• _.keys• _.values• _.times

Page 29: jQuery — fonctionnalités avancées

ÉvénementsLier et déclencher

Page 30: jQuery — fonctionnalités avancées

BaseÉvénements faciles

Événements

Page 31: jQuery — fonctionnalités avancées

$(".element").click(function() {});$(".element").dblclick(function() {})

$(".element").mouseover(function() {});$(".element").mouseout(function() {});

$(".element").keyup(function() {});$(".element").keydown(function() {});$(".element").keypress(function() {});

Page 32: jQuery — fonctionnalités avancées

$(".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() {});

Page 33: jQuery — fonctionnalités avancées

$(".element").bind({ click: function() {}, dblclick: function() {}, mouseover: function() {}, mouseleave: function() {}});

Page 34: jQuery — fonctionnalités avancées

ArbitrairesDéclencher n’importe quoi (vraiment)

Événements

Page 35: jQuery — fonctionnalités avancées

$.fn.bind("anything", function() { // this});

$.fn.trigger("anything");

Page 36: jQuery — fonctionnalités avancées

$("#element").bind("anything", function() { // this});

$("#element").trigger("anything");

Page 37: jQuery — fonctionnalités avancées

Méthodesévénementielles

Événements

Page 38: jQuery — fonctionnalités avancées

$("#vote-count").bind("increase", function() { $(this).text(parseInt($(this).text) + 1);});

$("#upvote-button").bind("click", function() { $("#vote-count").trigger("increase");});

Page 39: jQuery — fonctionnalités avancées

function increase_vote_count() { var elem = $("#vote_count"); elem.text(parseInt(elem.text()) + 1);}

$("#upvote-button").bind("click", increase_vote_count);

Page 40: jQuery — fonctionnalités avancées

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();});

Page 41: jQuery — fonctionnalités avancées

ArgumentsEncore plus personnalisables

Événements

Page 42: jQuery — fonctionnalités avancées

$(".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!"}])

Page 43: jQuery — fonctionnalités avancées

Toutpeut être lié à un événement

Événements

Page 44: jQuery — fonctionnalités avancées

var Island = { is_magic: true };

$(Island).bind("move", function() { alert(this.is_magic); // true});

$(Island).trigger("move");

Page 45: jQuery — fonctionnalités avancées

$.fn.livePour les éléments inexistants

Événements

Page 46: jQuery — fonctionnalités avancées

$("#tweets a.user").live("click", function() { // Faire quelque chose});

$(document).bind("click", function(event) { if ($(event.target).is("#tweets a.user")) { // Faire quelque chose }})

Page 47: jQuery — fonctionnalités avancées

$(".user").live("click", function() { // Faire quelque chose});

$(document).bind("click", function(event) { if ($(event.target).is(".user")) { // Faire quelque chose }})

Page 48: jQuery — fonctionnalités avancées

$.fn.delegatePlus performant que $.fn.live

Événements

Page 49: jQuery — fonctionnalités avancées

$("#tweets").delegate("a.user", "click", function() { // Faire quelque chose});

$("#tweets").bind("click", function(event) { if ($(event.target).is("a.user")) { // Faire quelque chose }})

Page 50: jQuery — fonctionnalités avancées

$.fn.dieLe contraire de « live »

Événements

Page 51: jQuery — fonctionnalités avancées

$("#tweets a.user").bind("click", function() { // Quelque chose});

$("#tweets *").unbind("click");

Page 52: jQuery — fonctionnalités avancées

$("#tweets a.user").live("click", function() { // Faire quelque chose});

$("a.user").die("click"); // ne fonctionnera pas$("#tweets a.user").die("click"); // fonctionne!

Page 53: jQuery — fonctionnalités avancées

$.fn.undelegateLe contraire de « delegate » (duh)

Événements

Page 54: jQuery — fonctionnalités avancées

$("#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!

Page 55: jQuery — fonctionnalités avancées

NamespacesPour éviter la confusion

Événements

Page 56: jQuery — fonctionnalités avancées

// 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”

Page 57: jQuery — fonctionnalités avancées

// 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

Page 58: jQuery — fonctionnalités avancées

• $.fn.bind• $.fn.trigger• $.fn.live + $.fn.die• $.fn.delegate + $.fn.undelegate• Namespaces

Événements

Page 59: jQuery — fonctionnalités avancées

AnimationsAu-delà de « fadeOut »

Page 60: jQuery — fonctionnalités avancées

BaseAnimations faciles

Animations

Page 61: jQuery — fonctionnalités avancées

$("#menu").slideUp();$("#menu").slideDown();$("#menu").slideToggle();

$("#fantome").fadeIn();$("#fantome").fadeOut();$("#fantome").fadeToggle();

Page 62: jQuery — fonctionnalités avancées

$.fn.animateAnimations pour « power-users »

Animations

Page 63: jQuery — fonctionnalités avancées

$("#element").animate({ left: "-=200px", height: "toggle", width: "toggle"},{ duration: 1000, easing: "linear", complete: function() {}, step: function() {}, queue: false, specialEasing: { height: "easeIn", width: "easeOut" }});

Page 64: jQuery — fonctionnalités avancées

$.fn.queueGérer la file d’attente

Animations

Page 65: jQuery — fonctionnalités avancées

$("#element-1").animate({ fontSize: "14em" }).animate({ width: "+=200px" }).animate({ height: "+=200px" });

$("#element-2").animate({ fontSize: "14em" }, { queue: false }).animate({ width: "+=200px" }).animate({ height: "+=200px" });

Page 66: jQuery — fonctionnalités avancées

$.fn.delayAnimer avec un délai

Animations

Page 67: jQuery — fonctionnalités avancées

$("#element").animate({ fontSize: "14em" }).delay(1000).animate({ width: "+=200px" }).delay(1000).animate({ height: "+=200px" });

Page 68: jQuery — fonctionnalités avancées

$.fn.delayPas seulement pour les animations

Animations

Page 69: jQuery — fonctionnalités avancées

$("#ajax-mais-tantot").delay(2000).queue(function() { $(this).load("/ajax_content.html")});

Page 70: jQuery — fonctionnalités avancées

$("#element").bind("click", function() { $(this).delay(2000).queue(function() { $(this).css("background", "yellow"); });});

Page 71: jQuery — fonctionnalités avancées

$.fx.offSoyons gentils avec les plus lents

Animations

Page 72: jQuery — fonctionnalités avancées

$.fx.off = true;

Page 73: jQuery — fonctionnalités avancées

• $.fn.animate• $.fn.queue• $.fn.delay• $.fx.off

Animations

Page 74: jQuery — fonctionnalités avancées

SupportTester la compatibilité du navigateur

Page 75: jQuery — fonctionnalités avancées

$.browserVous devriez l’éviter

Support

Page 76: jQuery — fonctionnalités avancées

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)}

Page 77: jQuery — fonctionnalités avancées

ImplémentationPas réputation

Support

Page 78: jQuery — fonctionnalités avancées

if (typeof window.WebSocket != "undefined") { // Quelque chose de cool avec les sockets} else { // Quelque chose de cool en… AJAX?}

Page 79: jQuery — fonctionnalités avancées

$.supportVous devriez le modifier

Support

Page 80: jQuery — fonctionnalités avancées

$.support.ajax$.support.boxModel$.support.hrefNormalized$.support.opacity

Page 81: jQuery — fonctionnalités avancées

$.extend($.support, {

webSockets : (function() { return typeof window.WebSocket != "undefined" }).call(),

canvas : (function() { var canvas = document.createElement("canvas"); return !!(canvas.getContext && canvas.getContext("2d")); }).call()

});

Page 82: jQuery — fonctionnalités avancées

if ($.support.canvas) { // Quelque chose de cool avec <canvas>} else { // Quelque chose de cool… des images?}

Page 83: jQuery — fonctionnalités avancées

Pas assez?Modernizr

Support

Page 84: jQuery — fonctionnalités avancées

Support

• Modernizr.borderradius• Modernizr.geolocation• Modernizr.localstorage• Modernizr.draganddrop• Modernizr.addTest

Page 85: jQuery — fonctionnalités avancées

ManipulationsModifier le DOM facilement

Page 86: jQuery — fonctionnalités avancées

BaseManipulations faciles

Manipulations

Page 87: jQuery — fonctionnalités avancées

$(".article").append("<div class=\"share-this\"></div>");

$("<strong>!!!</strong>").insertAfter(".important");

$("Attention! Spoiler").insertBefore(".spoiler");

$(".no-javascript-message").remove();

Page 88: jQuery — fonctionnalités avancées

$("<foo />")Création de noeuds DOM jQuery

Manipulations

Page 89: jQuery — fonctionnalités avancées

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");

Page 90: jQuery — fonctionnalités avancées

$.fn.cloneCloner des noeuds

Manipulations

Page 91: jQuery — fonctionnalités avancées

$(".dolly").clone().appendTo("#ferme");

$(".dolly").clone(true).appendTo("#ferme");

$(".dolly").clone(true, false).appendTo("#ferme");

Page 92: jQuery — fonctionnalités avancées

$.fn.detachSupprimer du DOM seulement

Manipulations

Page 93: jQuery — fonctionnalités avancées

$("#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!

Page 94: jQuery — fonctionnalités avancées

ParsersAnalyseurs intégrés à jQuery

Page 95: jQuery — fonctionnalités avancées

$.parseJSONAnalyse de JSON

Parsers

Page 96: jQuery — fonctionnalités avancées

var data = '{ "name": "John Locke" }';var person = $.parseJSON(data);

person.name=> "John Locke"

Page 97: jQuery — fonctionnalités avancées

$.parseXMLParcourir du XML comme du HTML

Parsers

Page 98: jQuery — fonctionnalités avancées

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"]

Page 99: jQuery — fonctionnalités avancées

DataStocker des données

Page 100: jQuery — fonctionnalités avancées

$.fn.dataDes données dans des objets jQuery

Data

Page 101: jQuery — fonctionnalités avancées

$(".unstoppable-button").data("count", 0);

$(".unstoppable-button').bind("click", function() { $(this).data("count", $(this).data("count") + 1);});

Page 102: jQuery — fonctionnalités avancées

// 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();

Page 103: jQuery — fonctionnalités avancées

Événementsde données

Data

Page 104: jQuery — fonctionnalités avancées

// 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

Page 105: jQuery — fonctionnalités avancées

$("#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

Page 106: jQuery — fonctionnalités avancées

HTML5 dataStocker de façon sémantique

Data

Page 107: jQuery — fonctionnalités avancées

AvantDes données dans les attributs HTML

Data

Page 108: jQuery — fonctionnalités avancées

<!-- 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);});

Page 109: jQuery — fonctionnalités avancées

<!-- 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);});

Page 110: jQuery — fonctionnalités avancées

AprèsLe plugin $.metadata

Data

Page 111: jQuery — fonctionnalités avancées

<!-- 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);});

Page 112: jQuery — fonctionnalités avancées

<!-- 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);});

Page 113: jQuery — fonctionnalités avancées

MaintenantLes attributs « data » de HTML5

Data

Page 114: jQuery — fonctionnalités avancées

<!-- 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);});

Page 115: jQuery — fonctionnalités avancées

<!-- 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

Page 116: jQuery — fonctionnalités avancées

• $.fn.data• Événements « getData » + « setData »• $.fn.attr• $.metadata• $.fn.data + HTML5

Data

Page 117: jQuery — fonctionnalités avancées

DeferredGestion facile de callbacks

Page 118: jQuery — fonctionnalités avancées

$.DeferredRésolution, rejet et attente

Deferred

Page 119: jQuery — fonctionnalités avancées

var request = $.Deferred();

request.done(function() { alert("succes!"); });request.fail(function() { alert("erreur!"); });

request.resolve();=> "succes!"

// OU

request.reject();=> "erreur!"

Page 120: jQuery — fonctionnalités avancées

Deferred AJAXExemple classique

Deferred

Page 121: jQuery — fonctionnalités avancées

var request = $.get("/feed")

request.done(function(data) { console.log(data.user.name);});

request.fail(function(error) { console.log(error.message);});

Page 122: jQuery — fonctionnalités avancées

var request = $.get("/feed")

request.done(function(data) { console.log(data.user.name);});

request.fail(function(error) { console.log(error.message);});

Page 123: jQuery — fonctionnalités avancées

var request = $.get("/feed")

request.done(function(data) { console.log(data.user.name);});

request.fail(function(error) { console.log(error.message);});

Page 124: jQuery — fonctionnalités avancées

$.fn.thenDéclarer des callbacks

Deferred

Page 125: jQuery — fonctionnalités avancées

var request = $.get("/feed");

request.then( function() { alert("done!"); }, function() { alert("failed!"); });

Page 126: jQuery — fonctionnalités avancées

$.fn.whenGérer des deferred multiples

Deferred

Page 127: jQuery — fonctionnalités avancées

var request = $.get("/feed")

$.when(request).then( function() { alert("done!") }, function() { alert("failed!") });

Page 128: jQuery — fonctionnalités avancées

var request1 = $.get("/feed")var request2 = $.get("/users")

$.when(request1, request2).then( function() { alert("everything has succeed!") }, function() { alert("something has failed.") });

Page 129: jQuery — fonctionnalités avancées

PossibilitésUn wrapper d’API

Deferred

Page 130: jQuery — fonctionnalités avancées

// 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);});

Page 131: jQuery — fonctionnalités avancées

• $.Deferred• $.fn.resolve• $.fn.reject• $.fn.then• $.fn.when

Deferred

Page 132: jQuery — fonctionnalités avancées

BrefFonctionnalités avancées

Page 133: jQuery — fonctionnalités avancées

• api.jquery.com• james.padolsey.com• jaubourg.net• ejohn.org/apps/workshop/adv-talk

Ressources

Page 134: jQuery — fonctionnalités avancées

Questions?Commentaires?

@remi