7 pratiques Javascript qui changent la vie

Ajax, javascript et le DOM avaient l'allure de gadgets peu fiables

A l’époque où le mot Ajax évoquait encore un produit d’entretien, où le DOM était un territoire d’outre Web, et où l’idée de faire des applications dynamiques sur le Web paraissait extrèmement utopique, Javascript avait l’allure d’un gadget peu fiable. Il ne me serait jamais venu à l’esprit que ce langage soit évolué, stable et puissant. Et que son apprentissage soit aussi semé d’embuches… Après des mois de pratique intensive et d’arrachage de cheveux, voici quelques-uns des trucs que j’ai appris.

  1. La fonction $()
  2. L’objet littéral
  3. JSON
  4. Yahoo UI (ou autre framework)
  5. La capture d’évenements
  6. Le Javascript gzippé
  7. Les outils de débuggage


Ajax, javascript et le DOM avaient l'allure de gadgets peu fiables

A l’époque où le mot Ajax évoquait encore un produit d’entretien, où le DOM était un territoire d’outre Web, et où l’idée de faire des applications dynamiques sur le Web paraissait extrèmement utopique, Javascript avait l’allure d’un gadget peu fiable. Il ne me serait jamais venu à l’esprit que ce langage soit évolué, stable et puissant. Et que son apprentissage soit aussi semé d’embuches… Après des mois de pratique intensive et d’arrachage de cheveux, voici quelques-uns des trucs que j’ai appris.

  1. La fonction $()

    vs document.getElementById()

    Dès qu’on manipule les éléments d’une page (le DOM) en Javascript, on multiplie les appels à document.getElementById('element_id'), ce qui est long et source d’erreurs. Je ne suis sans doute pas le seul à avoir perdu du temps à cause d’une majuscule oubliée. Saviez-vous qu’il était possible d’appeler votre élément par la simple fonction $('element_id') ? Il suffit de déclarer la fonction $() qui remplacera élégamment la longue séquence habituelle :

    function $(element_id) {     return document.getElementById(element_id); }

    C’est bête comme tout, mais très pratique à écrire et à repérer, surtout pour les habitués de la syntaxe $variable de PHP.

    MAJ Juin 2008 : attention, la fonction que je propose est excessivement limitée. Si vous souhaitez passer à JQuery plus tard, vos appels $(‘id’) ne seront pas compatibles. J’en ai fait l’expérience, j’aurais dû lui donner un nom personnalisé comme my$(). Moralité : installez JQuery et passez à la syntaxe $(‘#id’).
  2. L’objet littéral

    vs les fonctions

    L’écriture objet dans javascript est complètement différente, disons, de celle de PHP (je ne connais pas Java ou C#) puisqu’elle ne repose pas sur la dualité classe/instance : tout objet est instancié dans JS. Elle présente cependant les mêmes avantages : regrouper des fonctions et mieux séparer le code dans le but d’en faciliter la maintenance. La notation objet est également très compacte et lisible. L’accès aux méthodes et propriétés d’un objet est extrèmement facile, puisqu’il suffit de séparer par un point l’objet et sa méthode : objet.methode(). Prenons l’exemple de deux fonctions destinées à afficher et masquer un menu, afficher_menu() et masquer_menu(). En notation objet, on créera un objet monMenu qui aura ces deux méthodes :

    var monMenu = {     afficher: function() {         $('mon_menu').style.display = 'block';     },     masquer: function() {         $('mon_menu').style.display = 'none';     } }; // J'appelle la méthode masquer monMenu.masquer(); 

    A terme, on pourra ranger l’ensemble des déclarations de l’objet monMenu dans un fichier monMenu.js, ce qui facilitera la mise à jour du site. La notation objet permet en outre de définir un « espace de nommage » (par ex. un objet potlatch dont découlent potlatch.menu, potlatch.formulaire, etc.) qui évite que plusieurs variables ou fonctions portent le même nom. On évite ainsi l’événement < body onload="init()">init() ne sait plus quel script initialiser… Il y a bien d’autres subtilités à la notation objet, une fois que vous serez lancés.

  3. Yahoo UI (ou autre framework)

    vs réinventer la roue

    Je ne vais pas m’étendre dessus, mais les frameworks (bibliothèques de développement) sont du pain béni pour le développeur : ils lui évitent de se retaper les incompatibilités de navigateurs et autres fonctions de base. Yahoo, avec la Yahoo User Interface Library, fournit des briques de base très bien conçues : événements, DOM, animation, divers widgets (dont le tableau de données, le calendrier, les fenêtres, les onglets…). L’ensemble est très bien documenté (en anglais). On regrette juste que la logique soit parfois un peu difficile à acquérir et que certains exemples manquent de commentaires, mais la puissance et la flexibilité sont au rendez-vous. A noter, pour les plus avares en bande passante, que Yahoo héberge ses fichiers JS, compressés et toujours disponibles, ce qui allègera d’autant votre serveur et devrait faire gagner du temps aux visiteurs qui ont déjà ces librairies dans leur cache de navigateur. Bien entendu, il y a d’autres frameworks (Dojo, prototype…) tout aussi gratuits et open source : à vous de choisir vos armes pour ne pas partir nu à l’assaut du javascript.

    MAJ Juin 2008 : J’ai succombé à JQuery depuis quelques temps. Il permet de faire des trucs de dingue en très peu de lignes. Je le recommande désormais face à Yahoo UI
  4. La capture d’évenements

    vs onClick

    L’un des changements de mentalité les plus traumatisants que m’a imposée la YUI library concerne la gestion des événements. Avant, on bardait les sites d’onclick, onmouseover et autres événements intégrés à même la balise HTML. Aujourd’hui, on considère que ce comportement est honteux, sale et immoral. Il faut extraire le comportement du code sémantique, et donc, indiquer au script qu’il doit « écouter » les événements pour les intercepter et en faire quelque chose, au moyen de la méthode addListener(). Ci-joint un exemple basé sur YUI, puisque j’ai l’habitude de l’employer. Pour remplacer le code <a onclick="monMenu.afficher()">fermer</a>, on emploiera le code suivant :

    // Dans le fichier JS YAHOO.util.Event.addListener('fermer', 'click', monMenu.fermer); // Dans le HTML <a id="fermer">fermer</a>

    Les implications et possibilités de ce mode de fonctionnement sont énormes. Sachez par exemple que la fonction appelée en 3e argument de la méthode addListener() aura pour premier argument un objet Event. Et si je veux passer des variables à cette fonction, je dois les inclure dans objet qui devient le quatrième argument :

     YAHOO.util.Event.addListener(element,evenement,fonction.de.retour,{arg1 : "pot", arg2 : "latch"}) // Fonction retour (callback) fonction.de.retour(e,o) {     alert(o.arg1); // => pot }

    Un des plus gros avantages, c’est que cela permet une séparation totale entre le source HTML et le comportement. On peut ainsi créer une version « accessible » de ses contenus en simple HTML, qui sera enrichie pour ceux qui disposent du Javascript. On peut également bénéficier de la délégation d’événements, qui consiste à placer un seul addListener() sur un élément du DOM qui capturera les événements de chacun de ses éléments enfants. Il suffira alors d’identifier quel <li> a été cliqué parmi les quinze du menu pour déclencher l’action adaptée. Le gain de performances est remarquable pour les longues collections d’éléments.

  5. JSON (Javascript object notation)

    vs XML

    Mes premiers pas avec Ajax ont aussi été un contact rugueux avec XML. XML a des qualités, mais la beauté n’en fait pas partie. Et son intégration avec javascript, passant le contenu dans un grand tableau multi-dimensionnel à parcourir avec des getAttribute() à foison me faisait mal aux oreilles. C’est par hasard que je suis tombé sur JSON, qui fait la même chose que XML (renvoyer des données hiérarchisées), mais son élégance m’a émerveillé, tant dans la lisibilité du contenu retourné que dans l’évidence de l’utilisation des objets résultants avec Javascript. Elle consiste à créer un objet littéral qui sera parcouru par le script et utilisable comme un objet créé par le script. Illustration :

     // Réponse XML <actus>     <actu>         <titre>Pourquoi passer à la POO ?</titre>         <auteur>Le Caphar</auteur>     </actu>     <actu>         <titre>Planète Bosphore</titre>         <auteur>Le Caphar</auteur>     </actu> </actus> // Fonction de sélection (attention code reproduit de mémoire, pas forcément valide !) function retourXml(reponse) {     var actus = reponse.responseXML.getElementsByTagName('actu');     for (var i=0 ; i<actus.length ; i++)     {         var titre = getNodeValue(actus[i],'titre');     } } // Retour JSON {"actus":     [         {"actu": 		{ 		"titre":"Pourquoi passer à la POO ?", 		"auteur":"Le Caphar", 		} 	}, 	{"actu": 		{ 		"titre":"Planète Bosphore", 		"auteur":"Le Caphar", 		} 	}     ] } // Fonction JSON function retourJson(reponse) {     var data = eval('(' + reponse.responseText+ ')');     for (var i=0 ; i<data.actus.length ; i++)     {         var titre = data.actus[i].actu.titre;     } } 

    C’est peut-être subtil, mais la clarté du schéma de données dans le second exemple me paraît évidente. Après, c’est une question de goût et je ne vais pas entrer dans la bataille qui fait rage chez les développeur JS anglo-saxons.

  6. Le Javascript gzippé

    vs 700ko de librairies à charger

    A force d’enrichir ses scripts, on finit par accroître le poids des données à télécharger. Heureusement pour nous, la technique de compression gzip est disponible dans la plupart des navigateurs. Il vous suffit de servir des fichiers JS gzippés pour diviser leur poids par deux, voire davantage. C’est la technique qu’utilise Yahoo pour servir sa librairie YUI. Et si vous utilisez PHP, rien de plus simple : indiquez comme source de votre balise <script> votre fichier js.php, qui contiendra le code suivant :

    <?php ob_start ("ob_gzhandler"); header("Content-type: text/javascript; charset: UTF-8"); header("Cache-Control: must-revalidate"); $offset = 60 * 60 ; // Durée en secondes avant expiration du cache $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT"; header($ExpStr); // liste de vos fichiers JS à compresser   include('fiche.js');   include('filtres.js');   include('historique.js');   include('liste.js');   include('recherche.js');   include('categories.js');   ?> 

    La même méthode s’applique au CSS, avec des taux de compression impressionnants. L’essayer, c’est l’adopter !

  7. Les outils de déboguage

    vs tourner en rond

    Javascript manque singulièrement d’outils de déboguage, ce qui rend difficile le développement avancé. Il y a pourtant une série d’outils qui me sont extrèmement utiles, tournant tous sur Firefox :

    • afficher le code source de la sélection : si vous affichez le source de votre page, les éléments créés dynamiquement par javascript seront invisibles. Par contre, si vous sélectionnez une portion de texte, le menu contextuel vous permet d’afficher le DOM tel qu’il a été généré par le script.
    • la Web Developer Toolbar, et notamment la combinaison de touches Ctrl+Maj+F pour repérer par survol un élément du DOM, connaître ses dimensions, sa position dans le DOM, sa classe et son Id
    • l’indispensable Firebug qui se place en bas de l’écran et affiche énormément d’informations, notamment les erreurs et les appels RPC (Ajax) avec l’adresse des pages demandées, le temps de chargement et le contenu renvoyé… un bijou !
    • le Dom Inspector et son extension l’Event Spy : après avoir identifié un élément du DOM, je peux ouvrir l’event spy par un clic droit et surveiller tout ce qui va arriver à ce pauvre élément.

J’espère apprendre encore bien d’autres techniques à mesure que je me familiarise avec cet étrange langage. N’hésitez pas à partager vers vos meilleures astuces dans les commentaires.

Outil de référencement professionnel - essai gratuit Ce contenu a été publié dans Webdesign, avec comme mot(s)-clé(s) , , , , , , , , , . Vous pouvez le mettre en favoris avec ce permalien.

7 réponses à 7 pratiques Javascript qui changent la vie

  1. nicolasN dit :

    Merci pour cet article ! Des très bonnes idées, ajouté dans mes favoris !

  2. k-ny dit :

    Et hop, je me garde tout ça sous le coude !

    Et en passant ton blog dans mon google reader :)

  3. telnes dit :

    tres tres interressant , voir meme demanderais des tutos complets pour chaque point aborder ^^

    notament la partie class methode js et la compression gzip

    ++

  4. eMeRiKa dit :

    J’avais déja entendu de ne plus mettre de onclick sans vraiment comprendre comment faire. je vais me pencher sur prototype voir comment il le gère!!

    Merci pour ses conseils

  5. Diagg dit :

    Super post, bravo ! Je signal pour les personnes qui devellope sous IE ou opera qu’il existe une version de firebug pour ces navigateur nommé Firebug Light : link to getfirebug.com.

  6. crazykangourou dit :

    Bonjour, merci pour cet article, il tombe a point nommé, car je suis en phase d’optimisation de mon site (oracle 9i + php4).
    J’utilise la compression ob_start ("ob_gzhandler") pour l’intégralité des pages que j’envoie, c’est pas mieux?

    Ensuite une autre question, c’est un site dynamique, par conséquent j’utilise le no-cache.
    Mais les feuilles de style et le javascript sont identiques et sont très lourd et je viens de voir la méthode pour les cacher.

    Donc ma question est la suivante :
    – Mon site est implémenté suivant la structure mvc2 (controleur principale)
    – Sachant que mon site est dynamique avec une entete no-cache

    Est t il quand meme possible d’inclure 2 fichiers php avec des entete différents ? Comme dans le point 6 Le Javascript gzippé.

    Autrement dit :

    <?php
    ob_start ("ob_gzhandler");
    header(cache-control : no-cache);

    require_once ("javascript_cache.php");
    require_once("css_cache.php");

    require_once ("header.php");

    // code controleur

    requitre_once ("footer.php");

    ?php>

  7. Damien Ravé - Le Caphar dit :

    @kangourou : désolé pour le délai, j’étais en plein déménagement et j’ai laissé le blog au second plan.

    Pour tes questions :

    1/ Oui, en théorie c’est mieux de tout compresser plutôt que rien du tout. Cela dit, il y a des navigateurs (je sais plus lesquels, Netscape truc, IE 4 et autres vieilleries je crois, à vérifier sur le site de Yahoo avec les « grade A browsers ») qui ne sont pas compatibles avec le GZip. Pour ces visiteurs, si tu ne zippes que ton Javascript, ils perdent une partie de l’interactivité (théoriquement, si tu as développé selon les principes de l’enrichissement progressif, ton site reste consultable). Par contre si tu zippes l’ensemble de tes pages, ils ne peuvent carrément plus consulter tes pages. A toi de voir si tu es prêt à prendre ce risque).

    2/ Le code que tu indiques ne te fera pas bénéficier de la mise en cache du JS et du CSS dans le navigateur, car le source passé via include/require est produit directement dans le code HTML. Pour le navigateur, tu ne produis qu’un gros fichier qui change à chaque rechargement, même si certaines de ses lignes sont identiques.
    En fait si tu veux éviter le cache sur ton HTML mais le conserver sur tes fichiers JS et CSS, tu dois les appeler comme des fichiers externes dans ton code HTML, via les balises <SCRIPT src= »javascript_cache.php » /> et <LINK REL= »stylesheet » HREF= »css_cache.php »>. Il faudra repréciser les paramètres de cache dans l’en-tête de chacun de ces fichiers.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *