Upgrade to Pro — share decks privately, control downloads, hide ads and more …

jQuery — fonctionnalités avancées

jQuery — fonctionnalités avancées

Présentation donnée le 9 mars 2011 à ConFoo 2011 (Montréal).

8c4cee1129bc11fbe9a0b9379dce2cb1?s=128

Rémi Prévost

March 09, 2011
Tweet

Transcript

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

  2. Rémi Prévost @remi + http://remiprevost.com Développeur Web

  3. But de cette présentation

  4. Pas un tutoriel/pitch jQuery But

  5. Survol des fonctionnalités moins connues But

  6. Sa force Courbe d’apprentissage facile But

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

  8. Ensuite? Beaucoup plus de possibilités But

  9. 1.0 → 1.5 45 Ko → 208 Ko 2006 2011

    But
  10. • Utilitaires • Événements • Animations • Manipulations • Parsers

    • Data • Deferreds But
  11. Utilitaires Pour sauver du temps

  12. Implémentations natives Utilitaires

  13. $ Ne touchent pas aux objets natifs Utilitaires

  14. $.map Modifie chaque élément d’un tableau Utilitaires

  15. var noms = ["jack", "kate", "john", "james", "claire"] $.map(noms, function(nom)

    { return nom.toUpperCase(); }); => ["JACK", "KATE", "JOHN", "JAMES", "CLAIRE"]
  16. $(".user-name").map(function() { return $(this).text(); } ); => ["@remi", "@garno", "@jmlacroix",

    "@vincentroyc"]
  17. $.grep Filtre un tableau Utilitaires

  18. 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", … }]
  19. $.inArray Vérifie la présence d’éléments Utilitaires

  20. var numeros = [4, 8, 15, 16, 23, 42]; $.inArray(numeros,

    16); => 3 $.inArray(numeros, 64); => -1
  21. $.merge Fusionne deux tableaux Utilitaires

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

    "charlie", "eko"]; $.merge(tailies, middlies); => ["libby", "bernard", "eko", "jack", "charlie", "eko"]
  23. $.extend Fusionne deux objets Utilitaires

  24. 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."
  25. $.extend($.easing, { customEasing : function(p, n, firstNum, diff) { return

    firstNum - diff / p; } });
  26. Utilitaires • $.map • $.grep • $.inArray • $.merge •

    $.extend
  27. Pas assez? Underscore.js Utilitaires

  28. Utilitaires • _.reduce • _.uniq • _.keys • _.values •

    _.times
  29. Événements Lier et déclencher

  30. Base Événements faciles Événements

  31. $(".element").click(function() {}); $(".element").dblclick(function() {}) $(".element").mouseover(function() {}); $(".element").mouseout(function() {}); $(".element").keyup(function() {});

    $(".element").keydown(function() {}); $(".element").keypress(function() {});
  32. $(".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() {});
  33. $(".element").bind({ click: function() {}, dblclick: function() {}, mouseover: function() {},

    mouseleave: function() {} });
  34. Arbitraires Déclencher n’importe quoi (vraiment) Événements

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

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

  37. Méthodes événementielles Événements

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

    $("#vote-count").trigger("increase"); });
  39. function increase_vote_count() { var elem = $("#vote_count"); elem.text(parseInt(elem.text()) + 1);

    } $("#upvote-button").bind("click", increase_vote_count);
  40. 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(); });
  41. Arguments Encore plus personnalisables Événements

  42. $(".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!" }])
  43. Tout peut être lié à un événement Événements

  44. var Island = { is_magic: true }; $(Island).bind("move", function() {

    alert(this.is_magic); // true }); $(Island).trigger("move");
  45. $.fn.live Pour les éléments inexistants Événements

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

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

    { if ($(event.target).is(".user")) { // Faire quelque chose } })
  48. $.fn.delegate Plus performant que $.fn.live Événements

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

    function(event) { if ($(event.target).is("a.user")) { // Faire quelque chose } })
  50. $.fn.die Le contraire de « live » Événements

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

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

    // ne fonctionnera pas $("#tweets a.user").die("click"); // fonctionne!
  53. $.fn.undelegate Le contraire de « delegate » (duh) Événements

  54. $("#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!
  55. Namespaces Pour éviter la confusion Événements

  56. // 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”
  57. // 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
  58. • $.fn.bind • $.fn.trigger • $.fn.live + $.fn.die • $.fn.delegate

    + $.fn.undelegate • Namespaces Événements
  59. Animations Au-delà de « fadeOut »

  60. Base Animations faciles Animations

  61. $("#menu").slideUp(); $("#menu").slideDown(); $("#menu").slideToggle(); $("#fantome").fadeIn(); $("#fantome").fadeOut(); $("#fantome").fadeToggle();

  62. $.fn.animate Animations pour « power-users » Animations

  63. $("#element").animate({ left: "-=200px", height: "toggle", width: "toggle" },{ duration: 1000,

    easing: "linear", complete: function() {}, step: function() {}, queue: false, specialEasing: { height: "easeIn", width: "easeOut" } });
  64. $.fn.queue Gérer la file d’attente Animations

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

    height: "+=200px" }); $("#element-2") .animate({ fontSize: "14em" }, { queue: false }) .animate({ width: "+=200px" }) .animate({ height: "+=200px" });
  66. $.fn.delay Animer avec un délai Animations

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

    .delay(1000) .animate({ height: "+=200px" });
  68. $.fn.delay Pas seulement pour les animations Animations

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

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

  71. $.fx.off Soyons gentils avec les plus lents Animations

  72. $.fx.off = true;

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

  74. Support Tester la compatibilité du navigateur

  75. $.browser Vous devriez l’éviter Support

  76. 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) }
  77. Implémentation Pas réputation Support

  78. if (typeof window.WebSocket != "undefined") { // Quelque chose de

    cool avec les sockets } else { // Quelque chose de cool en… AJAX? }
  79. $.support Vous devriez le modifier Support

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

  81. $.extend($.support, { webSockets : (function() { return typeof window.WebSocket !=

    "undefined" }).call(), canvas : (function() { var canvas = document.createElement("canvas"); return !!(canvas.getContext && canvas.getContext("2d")); }).call() });
  82. if ($.support.canvas) { // Quelque chose de cool avec <canvas>

    } else { // Quelque chose de cool… des images? }
  83. Pas assez? Modernizr Support

  84. Support • Modernizr.borderradius • Modernizr.geolocation • Modernizr.localstorage • Modernizr.draganddrop •

    Modernizr.addTest
  85. Manipulations Modifier le DOM facilement

  86. Base Manipulations faciles Manipulations

  87. $(".article").append("<div class=\"share-this\"></div>"); $("<strong>!!!</strong>").insertAfter(".important"); $("Attention! Spoiler").insertBefore(".spoiler"); $(".no-javascript-message").remove();

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

  89. 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");
  90. $.fn.clone Cloner des noeuds Manipulations

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

  92. $.fn.detach Supprimer du DOM seulement Manipulations

  93. $("#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!
  94. Parsers Analyseurs intégrés à jQuery

  95. $.parseJSON Analyse de JSON Parsers

  96. var data = '{ "name": "John Locke" }'; var person

    = $.parseJSON(data); person.name => "John Locke"
  97. $.parseXML Parcourir du XML comme du HTML Parsers

  98. 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"]
  99. Data Stocker des données

  100. $.fn.data Des données dans des objets jQuery Data

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

  102. // 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();
  103. Événements de données Data

  104. // 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
  105. $("#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
  106. HTML5 data Stocker de façon sémantique Data

  107. Avant Des données dans les attributs HTML Data

  108. <!-- 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); });
  109. <!-- 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); });
  110. Après Le plugin $.metadata Data

  111. <!-- 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); });
  112. <!-- 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); });
  113. Maintenant Les attributs « data » de HTML5 Data

  114. <!-- 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); });
  115. <!-- 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
  116. • $.fn.data • Événements « getData » + « setData

    » • $.fn.attr • $.metadata • $.fn.data + HTML5 Data
  117. Deferred Gestion facile de callbacks

  118. $.Deferred Résolution, rejet et attente Deferred

  119. var request = $.Deferred(); request.done(function() { alert("succes!"); }); request.fail(function() {

    alert("erreur!"); }); request.resolve(); => "succes!" // OU request.reject(); => "erreur!"
  120. Deferred AJAX Exemple classique Deferred

  121. var request = $.get("/feed") request.done(function(data) { console.log(data.user.name); }); request.fail(function(error) {

    console.log(error.message); });
  122. var request = $.get("/feed") request.done(function(data) { console.log(data.user.name); }); request.fail(function(error) {

    console.log(error.message); });
  123. var request = $.get("/feed") request.done(function(data) { console.log(data.user.name); }); request.fail(function(error) {

    console.log(error.message); });
  124. $.fn.then Déclarer des callbacks Deferred

  125. var request = $.get("/feed"); request.then( function() { alert("done!"); }, function()

    { alert("failed!"); } );
  126. $.fn.when Gérer des deferred multiples Deferred

  127. var request = $.get("/feed") $.when(request) .then( function() { alert("done!") },

    function() { alert("failed!") } );
  128. var request1 = $.get("/feed") var request2 = $.get("/users") $.when(request1, request2)

    .then( function() { alert("everything has succeed!") }, function() { alert("something has failed.") } );
  129. Possibilités Un wrapper d’API Deferred

  130. // 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); });
  131. • $.Deferred • $.fn.resolve • $.fn.reject • $.fn.then • $.fn.when

    Deferred
  132. Bref Fonctionnalités avancées

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

  134. Questions? Commentaires? @remi