<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>La Case de l&#039;Oncle Tom &#187; jquery</title>
	<atom:link href="http://case.oncle-tom.net/tag/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://case.oncle-tom.net</link>
	<description>Développement Web, bonnes pratiques et performances</description>
	<lastBuildDate>Sun, 25 Dec 2011 19:33:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="search"
           href="http://case.oncle-tom.net/opensearch"
           type="application/opensearchdescription+xml"
           title="Content Search" />		<item>
		<title>Menu déroulant en rollover semi-accessible avec jQuery</title>
		<link>http://case.oncle-tom.net/2008/menu-deroulant-accessible-en-rollover-avec-jquery/</link>
		<comments>http://case.oncle-tom.net/2008/menu-deroulant-accessible-en-rollover-avec-jquery/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 05:00:50 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[Standards du Web]]></category>
		<category><![CDATA[bonne pratique]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ergonomie]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[logiciels libres]]></category>
		<category><![CDATA[rollover]]></category>
		<category><![CDATA[xhtml]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/?p=919</guid>
		<description><![CDATA[Joie : je fais maintenant partie de Planète Accessibilité en plus de Planet Libre. C&#8217;est l&#8217;occasion pour ce premier article dédié d&#8217;allier à la fois logiciels libres et accessibilité pour le plus grand bien du Web Le but de cette explication sera de développer la méthode et le raisonnement pour mettre en place un menu [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align:center"><img class="aligncenter size-full wp-image-834" title="Logo jQuery" src="http://case.oncle-tom.net/images/2007/12/jquery-logo.png" alt="Logo jQuery" width="117" height="32" /></p>
<p>Joie : je fais maintenant partie de <a href="http://planete-accessibilite.com/">Planète Accessibilité</a> en plus de <a href="http://www.planet-libre.org/">Planet Libre</a>. C&#8217;est l&#8217;occasion pour ce premier article dédié d&#8217;allier à la fois logiciels libres et accessibilité pour le plus grand bien du Web <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Le but de cette explication sera de <strong>développer la méthode et le raisonnement</strong> pour mettre en place un menu en rollover accessible. La difficulté tient essentiellement au fait que tout élément masqué par le biais des <acronym title="Cascading Style Sheets">CSS</acronym> est masqué pour de nombreux clients Web.</p>
<p>Nous verrons aussi pourquoi il est <strong>important de dissocier la présentation et les artifices graphiques</strong> grâce à une dégradation propre du JavaScript. Nous utiliserons pour cela <a href="http://jquery.com">jQuery</a>, <a href="http://case.oncle-tom.net/tag/jquery/">ma librairie JavaScript favorite</a>.<br />
<span id="more-919"></span></p>
<h3>Buts et objectifs de l&#8217;exercice</h3>
<p>J&#8217;ai eu besoin d&#8217;appliquer cette technique sur le site <a href="http://www.emunova.net">Emu Nova</a>. Je souhaitais plusieurs choses :</p>
<ul>
<li>disposer d&#8217;un menu en rollover en haut de page (facilite la navigation sur toutes les pages)</li>
<li>placer le contenu avant les menus dans le flux <acronym title="HyperText Markup Language">HTML</acronym> de la page (améliore le référencement)</li>
<li>une navigation possible sans JavaScript (pour cause de bug ou autre)</li>
</ul>
<p>Autrement dis, j&#8217;ai besoin d&#8217;un <strong>contenu en fin de flux mais visible avant tout le reste</strong>. J&#8217;ai opté pour la solution JavaScript pour éviter un positionnement absolu pénible à gérer (pour cause de conteneur centré) mais aussi pour respecter le <a href="http://code.google.com/p/blueprintcss/">colonnage de Blueprint</a> (puis toutes façons j&#8217;ai raison <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> )</p>
<p>En une image, cela se résume ainsi :</p>
<p style="text-align:center"><a href="http://case.oncle-tom.net/images/2008/06/emunova-menu-accessible.png"><img class="aligncenter size-medium wp-image-920" title="Tentative de menu accessible" src="http://case.oncle-tom.net/images/2008/06/emunova-menu-accessible-150x300.png" alt="Tentative de menu accessible" width="150" height="300" /></a></p>
<p>Nous allons aborder les 3 phases de ce tracé de flèche :</p>
<ol>
<li>la construction du menu (la zone verte)</li>
<li>le déplacement du contenu (la flèche)</li>
<li>la construction de notre nouveau menu (la zone bleue)</li>
</ol>
<h3>Étape 1 : construire le menu en <acronym title="HyperText Markup Language">HTML</acronym></h3>
<p>C&#8217;est l&#8217;étape essentielle. De sa structure dépend le reste de l&#8217;application. On doit <strong>d&#8217;abord penser à présenter le contenu de manière dégradée</strong>. C&#8217;est ainsi que le verront les utilisateur et c&#8217;est important de penser d&#8217;abord au pire des cas avant de mettre en place les paillettes et les artifices.</p>
<p style="text-align:center"><img class="aligncenter size-full wp-image-921" title="Menu accessible (Étape 1)" src="http://case.oncle-tom.net/images/2008/06/menu-accessible-etape-1.png" alt="Menu accessible (Étape 1)" width="427" height="178" /></p>
<p>Cette structure est représentée ainsi en <acronym title="HyperText Markup Language">HTML</acronym> :</p>
<pre><code class="html">&lt;div id="contenu-secondaire"&gt;
  &lt;ul id="navigation"&gt;
    &lt;li class="first column span-6"&gt;
      &lt;h2&gt;Actualités&lt;/h2&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href="..."&gt;Actualités&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="..."&gt;Newsletter&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="..."&gt;Flux <acronym title="Really Simple Syndication">RSS</acronym>&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="..."&gt;Twitter&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="..."&gt;Réactions à chaud&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li class="column span-6"&gt;
      &lt;h2&gt;Émulation&lt;/h2&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href="..."&gt;Émulation&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="..."&gt;Tutoriaux&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="..."&gt;Foire aux Questions&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;</code></pre>
<p>Cette version est volontairement tronquée pour faciliter sa lecture.<br />
L&#8217;idée générale de tout ça c&#8217;est de transporter directement la liste <code>#navigation</code> en dehors de son conteneur, <code>#extra-content</code>. C&#8217;est en effet plus rapide et plus performant de transporter une partie du <acronym title="Document Object Model">DOM</acronym> dans un autre endroit que de la recréer séquentiellement.</p>
<p>Ça aura également l&#8217;avantage de limiter au maximum le travail à effectuer en JavaScript par derrière. On notera que jusqu&#8217;à présent, on n&#8217;a pas encore touché à jQuery.</p>
<p>Avec cette structure, on peut dores et déjà deviner que les &lt;ul&gt; de second niveau seront masqués et affichés à la demande.</p>
<h3>Étape 2 : préparer le menu <acronym title="HyperText Markup Language">HTML</acronym></h3>
<p>La deuxième reste assez simple : on transporte <code>#navigation</code> dans son nouveau conteneur (déjà existant) : <code>#welcome-bar.</code></p>
<p>Pour éviter tout aléas graphique, l&#8217;idéal est de masquer tout ce qu&#8217;on ne veut pas voir maintenant. Nous rentrons maintenant dans la partie pure JavaScript.</p>
<p style="text-align:center"><img class="aligncenter size-full wp-image-922" title="Menu accessible (Étape 2)" src="http://case.oncle-tom.net/images/2008/06/menu-accessible-etape-2.png" alt="Menu accessible (Étape 2)" width="304" height="72" /></p>
<p>Pour atteindre ce résultat, on pourrait envisager le code suivant :</p>
<pre><code class="javascript">(function($){
  $(function(){
    /*
     * Étape 2 : préparation du menu
     */
    $('#navigation &gt; li &gt; ul').hide();
    $('#navigation').appendTo('#welcome-bar');
  });
})(jQuery);</code></pre>
<p>En soi, ce n&#8217;est pas excessif du tout :</p>
<ol>
<li>on masque tous les sous-menus</li>
<li>on transporte le contenu de #navigation dans #welcome-bar</li>
</ol>
<p>Tout le travail se situait dans la réflexion il faut croire <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h3>Étape 3 : assigner les évènements</h3>
<p>Maintenant le plus dur c&#8217;est de donner vie à tout ça. C&#8217;est bien beau d&#8217;avoir des menus mais encore faut-il les animer. Là encore nous avons plusieurs contraintes à subir :</p>
<ul>
<li>les <strong>titres doivent être cliquables</strong>. Certaines personnes cliqueront en effet avant de réaliser qu&#8217;il y a un menu déroulant. Par principe, on prendre le premier lien de la liste et on l&#8217;assignera au titre correspondant ;</li>
<li>le <strong>menu doit se dérouler lors du survol du titre</strong> &#8230;</li>
<li>mais il ne doit pas se masquer tant qu&#8217;on n&#8217;a pas quitté le titre NI la liste déroulante</li>
</ul>
<p>La difficulté tient à ces 2 dernières contraintes. On pourrait tout d&#8217;abord penser à l&#8217;utilisation des évènements <code>mouseover</code> et <code>mouseout</code> MAIS, parce qu&#8217;il y a bien un mais, <code>mouseout</code> est un peu capricieux.</p>
<p>Si on imagine un <code>mouseover</code> directement sur <code>li.column</code>, le problème c&#8217;est que survoler un élément comme <em>Actualités</em> ou <em>Newsletter</em> activera le <code>mouseover</code> de ces derniers &#8230; et désactivera, un temps minime certes, le survol de <code>li.column</code>. Autrement dit le menu se repliera alors qu&#8217;on tentera de l&#8217;utiliser.</p>
<p>Heureusement pour nous, jQuery a introduit les évènements <code>mouseenter</code> et <code>mouseleave</code> (présents dans Internet Explorer depuis des lustres, c&#8217;est bien le seul avantage de cette atrocité) depuis la <a title="Notes de version de jQuery 1.2.2" href="http://docs.jquery.com/Release:jQuery_1.2">version 1.2.2</a>. Ces évènements correspondent exactement à ce que l&#8217;on souhaite : maintenir une zone survolée malgré le survol de ses enfants.<br />
Tout est histoire de couches <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p style="text-align:center"><img class="aligncenter size-full wp-image-923" title="Menu accessible (Étape 3)" src="http://case.oncle-tom.net/images/2008/06/menu-accessible-etape-3.png" alt="Menu accessible (Étape 3)" width="301" height="180" /></p>
<p>Côté code, ça se complique :</p>
<pre><code class="javascript">(function($){
  $(function(){
    /*
     * Étape 3 : assignation des évènements et transformation
     */
    $('#navigation &gt; li')
      .each(function(){
        var title = $('h2:first', this);
        var href = $('a:first', this).clone();
        href.text(title.text()).wrapInner('&lt;span&gt;&lt;/span&gt;');
        title.html(href);
       })
      .find('h2 &gt; a').bind('mouseenter', function(){
        $(this).parents('li.column').find('&gt; ul').slideDown('fast');
      }).end()
      .bind('mouseleave', function(){
        $('&gt; ul', this).slideUp();
      });
  });
})(jQuery);</code></pre>
<p>Plusieurs remarques sur ce code :</p>
<ul>
<li>j&#8217;utilise les <strong>chaînes de jQuery</strong> pour gagner du temps et reparcourir des tableaux déjà connus (le sélecteur n&#8217;est pas réexécuté)</li>
<li>j&#8217;utilise également la <strong>méthode end()</strong> pour revenir au précédent état du sélecteur. Très pratique pour naviguer dans un jeu d&#8217;éléments et gagner en performances</li>
</ul>
<p>Et pour les explications :</p>
<ol>
<li>Pour chaque élément de liste
<ol>
<li>on met de côté le titre de la liste</li>
<li>on clone le premier élément du sous-menu</li>
<li>on modifie le libellé du lien du clone</li>
<li>on remplace le titre par le code <acronym title="HyperText Markup Language">HTML</acronym> du clone</li>
</ol>
</li>
<li>Pour ces liens hypertextes nouvellement créés (plus faciles à styler sans <acronym title="JavaScript">JS</acronym> au rollover), on leur demande de déplier le sous-menu voisin</li>
<li>Ce sous-menu ne sera replié que lorsqu&#8217;on quittera le li.column</li>
</ol>
<h3>Conclusion</h3>
<p>La <strong>mise en œuvre de ce menu est relativement aisée</strong> et surtout, suffisamment souple pour que vous puissiez l&#8217;adapter à vos besoins.<br />
Dans tous les cas on remarquera que les clés de la réussite sont :</p>
<ul>
<li>un <strong>code <acronym title="HyperText Markup Language">HTML</acronym> propre</strong> (facile les sélections <acronym title="JavaScript">JS</acronym> et le stylage <acronym title="Cascading Style Sheets">CSS</acronym>)</li>
<li>une évolution d&#8217;une <strong>base sans artifices vers une interface améliorée</strong> en JavaScript</li>
<li>un <strong>code simple</strong>, facilement maintenable et adaptable</li>
</ul>
<p>Ceci n&#8217;est qu&#8217;un exemple où le JavaScript peut servir à conserver des interfaces accessibles tout en augmentant leur utilisabilité. Qui a dit que le JavaScript c&#8217;était nul ?</p>
<p>Le seul reproche que l&#8217;on peut faire à ce menu accessible c&#8217;est le <em>manque de navigation au clavier</em>. L&#8217;idéal serait de pouvoir naviguer dans le choix des menus entièrement avec les flèches de son clavier.<br />
Rendez-vous dans un autre billet pour ce point ? <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2008/menu-deroulant-accessible-en-rollover-avec-jquery/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Emu Nova 2.1 : coulisses d&#8217;une refonte ergonomique et visuelle</title>
		<link>http://case.oncle-tom.net/2008/emu-nova-21-coulisses-dune-refonte-ergonomique-et-visuelle/</link>
		<comments>http://case.oncle-tom.net/2008/emu-nova-21-coulisses-dune-refonte-ergonomique-et-visuelle/#comments</comments>
		<pubDate>Tue, 22 Apr 2008 05:00:45 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[Standards du Web]]></category>
		<category><![CDATA[blueprint]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ergonomie]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[logiciels libres]]></category>
		<category><![CDATA[rythme vertical]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[xhtml]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/?p=902</guid>
		<description><![CDATA[Mon premier grand fait d&#8217;armes sur le Web aura été le lancement d&#8217;Emu Nova en octobre 2002. Les grandes lignes du site ont toujours été jeux vidéo rétro, émulation et aide aux utilisateurs. J&#8217;ai ainsi décidé d&#8217;offrir une nouvelle garde-robe à Emu Nova le 1er avril 2008 pour renouveler une interface vieille de 3 ans. [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center"><img class="aligncenter size-full wp-image-903" src="http://case.oncle-tom.net/images/2008/04/emunova.gif" alt="Emu Nova" width="186" height="48" /></p>
<p>Mon premier grand fait d&#8217;armes sur le Web aura été le lancement d&#8217;<a href="http://www.emunova.net/">Emu Nova</a> en octobre 2002. Les grandes lignes du site ont toujours été <strong>jeux vidéo rétro</strong>, <strong>émulation</strong> et <strong>aide aux utilisateurs</strong>.<br />
J&#8217;ai ainsi décidé d&#8217;offrir une nouvelle garde-robe à Emu Nova le 1<sup>er</sup> avril 2008 pour <strong>renouveler une interface</strong> vieille de 3 ans. 3 ans où le contenu s&#8217;est accumulé, les menus se sont désordonnés et la navigation s&#8217;est complexifiée.</p>
<p>Aujourd&#8217;hui je vous dévoile les <strong>tenants et aboutissants d&#8217;un travail de réflexion</strong> mené sur plusieurs mois tant en terme d&#8217;ergonomie, d&#8217;accessibilité et de respect des standards du Web.<br />
Où l&#8217;on parlera de jQuery, Blueprint et d&#8217;interface orientée utilisateur.<br />
<span id="more-902"></span></p>
<h3 style="text-align: center;"><a href="http://case.oncle-tom.net/images/2008/04/emunova-2010.png"><img class="aligncenter size-medium wp-image-905" src="http://case.oncle-tom.net/images/2008/04/emunova-2010-227x300.png" alt="Emu Nova : version 2" width="227" height="300" /></a></h3>
<h3>Objectifs de la refonte</h3>
<p>Comme je le disais, la plus grosse critique se tournait vers l&#8217;agencement du site : les menus étaient séparés en 2 et étaient peu visible.</p>
<p>Pire, il y avait tellement de contenu accumulé qu&#8217;au final l&#8217;utilisateur était obligé de scroller au mois une fois pour atteindre le contenu demandé.<br />
J&#8217;ai donc opté pour un <strong>choix radical</strong> : tout reprendre de la feuille blanche et ne tenter de conserver que l&#8217;identité du site au travers de ses couleurs et de son logo.</p>
<p>Plusieurs objectifs ont émergé en griffonnant au fur et à mesure l&#8217;interface sur une feuille de papier :</p>
<ul>
<li>offrir une page d&#8217;accueil qui ne fasse <strong>pas doublon</strong> avec le reste du site</li>
<li>offrir une page d&#8217;accueil <strong>mettant en avant du contenu</strong> pour inciter à visiter le site en profondeur (textes courts, images)</li>
<li>davantage <strong>lier les forums et le site</strong> pour susciter l&#8217;interaction avec l&#8217;internaute</li>
<li>offrir une <strong>interface lisible</strong> dont les contenus sont aisément identifiables sans effort cognitif</li>
<li>offrir du <strong>contenu annexe en pied de page</strong> : je suis désormais intimement convaincu que le pied de page est le meilleur moyen de fidéliser un vagabond curieux qui n&#8217;a pas tiré satisfaction de la première lecture</li>
<li>proposer un site conforme au <strong>standard <acronym title="eXtensible HyperText Markup Language">XHTML</acronym> 1 Strict</strong> en bannissant les mises en forme en tableau, entre autre</li>
</ul>
<p>On le voit, les objectifs de surface sont résolument tournés vers l&#8217;interface utilisateur. Derrière il y avait également des objectifs de simplification et de mutualisation du code avec l&#8217;interface d&#8217;administration.</p>
<h3>Choix technologiques</h3>
<p>Plutôt que de réinventer la roue, j&#8217;ai souhaité utiliser les applications en qui je crois le plus. Je peux compter dessus tout en gagnant du temps. N&#8217;est-ce pas là l&#8217;essentiel ?</p>
<h4>JavaScript : jQuery</h4>
<p>Je suis un féroce utilisateur de <a href="http://jquery.com/">jQuery</a> que j&#8217;adore pour sa <strong>souplesse d&#8217;utilisation</strong> et sa <strong>syntaxe vraiment plaisante</strong>. Elle dépassera, à mon avis, largement le vieillissant couple Prototype/Scriptaculous d&#8217;ici la fin de l&#8217;année 2008.</p>
<p>jQuery sert de base à tout le code JavaScript :</p>
<ul>
<li>altérer l&#8217;interface pour <strong>construire le menu de navigation principal</strong> : sans JavaScript ça marche, avec c&#8217;est encore mieux !</li>
<li>affichage des <strong>messages d&#8217;alertes pour les formulaires incomplets</strong> : pas de popup mais un message inséré à même la page</li>
<li><strong>ouverture des liens externes</strong> dans une nouvelle fenêtre</li>
<li><strong>diaporama de photos</strong> avec Lightbox ; personnalisé pour l&#8217;occasion afin de bénéficier de légendes plus détaillées</li>
</ul>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-904" src="http://case.oncle-tom.net/images/2008/04/emunova-jquery-form.png" alt="Emu Nova : formulaire avec erreur par jQuery" width="500" height="199" /></p>
<p>Il ne reste donc plus en tout et pour tout que 2 popup/alert/confirm obligeant à un affreux et désobligeant clic.</p>
<h4><acronym title="Cascading Style Sheets">CSS</acronym> : Blueprint</h4>
<p><a href="http://code.google.com/p/blueprintcss/">Blueprint</a> est la librairie <acronym title="Cascading Style Sheets">CSS</acronym> la plus proche du Saint-Graal : facile d&#8217;utilisation et très puissante. Mon seul regret à l&#8217;heure actuelle est qu&#8217;elle ne fonctionne qu&#8217;en largeur fixe. Mais dans cette configuration elle joue parfaitement son rôle :</p>
<ul>
<li>construction de colonnes les doigts dans le nez</li>
<li><a href="http://www.biologeek.com/journal/index.php/l-importance-du-rythme-vertical-en-design-css">rythme vertical</a> respecté pour un confort de lecture accru</li>
<li>construction typographique prémachée</li>
<li>correctifs liés à Internet Explorer déjà intégrés</li>
</ul>
<p>Une bonne présentation c&#8217;est une présentation sans contrainte : pas de couleur primaire, pas de difficulté à lire, pas de texte trop petit.</p>
<p>Le premier lecteur qui plisse les yeux c&#8217;est qu&#8217;il aura oublié d&#8217;allumer son écran <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h4>Transparence d&#8217;images : <acronym title="Graphics Interchange Format">GIF</acronym> ou <acronym title="Portable Network Graphics">PNG</acronym> ?</h4>
<p>Quitte à trancher dans le vif, le <strong><acronym title="Graphics Interchange Format">GIF</acronym> a été abandonné au profit du <acronym title="Portable Network Graphics">PNG</acronym></strong> pour le logo.</p>
<p>Pour rappel, si la transparence est possible avec le <acronym title="Graphics Interchange Format">GIF</acronym>, il lui manque la <strong>couche alpha</strong> qui permet de mélanger transparence et couleur. Avec le <acronym title="Portable Network Graphics">PNG</acronym> on peut frimer avec des contours ombrés et des reflets qui fusionnent parfaitement avec le décors.</p>
<p>Alors où est le problème ? Le sempiternel Internet Explorer 6 qui commence même à chauffer les oreilles à Microsoft. À tel point qu&#8217;il souhaite s&#8217;en débarrasser au plus tôt en poussant Internet Explorer 7, y compris pour les non-possesseurs du Service Pack 2 de Windows XP.<br />
La transparence est affichée comme du gris. Magnifique. Sauf en utilisant <a href="http://jquery.khurshid.com/ifixpng.php">jQuery.ifixpng</a>, entre autre.</p>
<h3>Emu Nova : carte de chaleurs, avant et après</h3>
<p style="text-align: center;"><a href="http://case.oncle-tom.net/images/2008/04/emunova-2000vs2100-heatmap.jpg"><img class="aligncenter size-medium wp-image-907" title="Heatmap d\'Emu Nova" src="http://case.oncle-tom.net/images/2008/04/emunova-2000vs2100-heatmap-294x300.jpg" alt="Heatmap d\'Emu Nova" width="294" height="300" /></a></p>
<p>Voici une comparaison des cartes de chaleur à 6 mois d&#8217;intervalle.</p>
<p>On remarque aisément que sur la précédente version les clics sont concentrés, notamment sur la partie haute de la page. Les quelques listes existantes mettent peu en valeur le contenu et de ce fait ne sont pas cliquées.</p>
<p>Sur la nouvelle version les clics semblent <strong>moins concentrés mais touchent globalement toute la page</strong>, exception faite des vignettes en image. Un problème ? Non pas vraiment puisqu&#8217;elles sont rafraîchies toutes les 3 heures ce qui fausse le calcul (qui s&#8217;étale sur 1 journée).</p>
<p>Notez aussi les clics en bas de page : <strong>le pied de page compte</strong>. Qui n&#8217;a pas eu envie qu&#8217;on lui suggère du contenu à lire une fois sa lecture terminée ?</p>
<h3>Conclusion</h3>
<p style="text-align: center;"><a href="http://case.oncle-tom.net/images/2008/04/emunova-2101-homepage.png"><img class="aligncenter size-medium wp-image-906" title="Emu Nova 2.1 : page d\'accueil" src="http://case.oncle-tom.net/images/2008/04/emunova-2101-homepage-203x300.png" alt="Emu Nova 2.1 : page d\'accueil" width="203" height="300" /></a></p>
<p style="text-align: left;">Il n&#8217;est pas aisé de refondre une interface, surtout quand il y a derrière toute une troupe d&#8217;utilisateurs attachés à ses habitudes (ce qu&#8217;on peut comprendre).</p>
<p style="text-align: left;">Si on temporise les différentes phases, voici ce que cela donne :</p>
<ul>
<li>analyse des besoins, ressenti de la situation : plusieurs mois</li>
<li>dessin de la nouvelle interface sur papier : plusieurs jours</li>
<li>intégration <acronym title="HyperText Markup Language">HTML</acronym> : plusieurs heures</li>
<li>refonte du code : plusieurs jours</li>
<li>corrections de bugs : plusieurs heures</li>
<li>premières critiques : quelques minutes</li>
</ul>
<p>Pas étonnant que ma régularité sur ce blog en aie pris un coup <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2008/emu-nova-21-coulisses-dune-refonte-ergonomique-et-visuelle/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>jQuery : optimiser l&#8217;utilisation des sélecteurs CSS</title>
		<link>http://case.oncle-tom.net/2007/jquery-optimisation-selecteurs-css/</link>
		<comments>http://case.oncle-tom.net/2007/jquery-optimisation-selecteurs-css/#comments</comments>
		<pubDate>Tue, 18 Dec 2007 07:00:02 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[bonnes pratiques]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[css 3]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[performances]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/2007/12/18/jquery-optimisation-selecteurs-css/</guid>
		<description><![CDATA[JQuery est une formidable librairie JavaScript car elle offre une grande souplesse et une utilisation simple. Il est cependant important de bien comprendre son fonctionnement pour éviter les débordements liés à une joie mal maîtrisée. S&#8217;il est très facile d&#8217;utiliser les sélecteurs CSS de jQuery, je constate de ci de là que leur utilisation n&#8217;est [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/12/jquery-logo.png" alt="Logo jQuery" /></p>
<p><a href="http://jquery.com">JQuery</a> est une formidable librairie JavaScript car elle offre une grande souplesse et une utilisation simple. <strong>Il est cependant important de bien comprendre son fonctionnement</strong> pour éviter les débordements liés à une joie mal maîtrisée.<br />
S&#8217;il est très facile d&#8217;utiliser les sélecteurs <acronym title="Cascading Style Sheets">CSS</acronym> de jQuery, je constate de ci de là que leur utilisation n&#8217;est pas toujours optimale &#8230; quand elle l&#8217;est déjà un tant soit peu.</p>
<p>Alors on se retrousse les manches et c&#8217;est parti pour un petit <strong>cas pratique sur les sélecteurs <acronym title="Cascading Style Sheets">CSS</acronym></strong> jQuery, plus une petite récap&#8217; pour grapiller du temps et des lignes de code <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
<span id="more-832"></span></p>
<h3>Le cas pratique</h3>
<p>J&#8217;ai pensé à une chose : plutôt que vous papillonniez en lisant cet article, j&#8217;ai fait en sorte que vous puissiez y prendre part. JQuery est très divertissant &#8211; certainement plus que votre voisine d&#8217;en face &#8211; alors tant qu&#8217;à me lire, autant optimiser la compréhension <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
Pour cela il vous faut 2 choses :</p>
<ol>
<li>un <a title="Sandbox HTML / jQuery" href="http://case.oncle-tom.net/images/2007/12/sandbox-oncletom-20071217.htm">bac à sable <acronym title="HyperText Markup Language">HTML</acronym> / jQuery</a> concocté par mes soins</li>
<li>l&#8217;inévitable <a href="https://addons.mozilla.org/fr/firefox/addon/1843">extension Firebug</a> pour bénéficier d&#8217;une console digne de ce nom (entre autre)</li>
</ol>
<h3>Principe de la sélection <acronym title="Cascading Style Sheets">CSS</acronym> de jQuery</h3>
<p>Que celui qui s&#8217;est lancé corps et âme dans jQuery sans lire la <a title="documentation jQuery" href="http://docs.jquery.com/Selectors">documentation</a> lâche un com&#8217; ! Elle est suffisamment complète pour éviter la plupart des questions du genre <q>comment je fais pour &#8230;</q>.</p>
<p>Maintenant que vous avez le document en main, nous allons jouer avec jQuery pour récupérer ce que nous voulons. Les personnes n&#8217;ayant pas Firebug comprendront la logique du code sans même avoir à le regarder :</p>
<pre><code class="javascript">// Récupération du premier paragraphe
$('body p:first-child');
// Récupération du nœud des continents
$('ul.continents');
// Récupération de la liste des capitales
$('.capitale');
// Récupération du dernier élément du body
$('body :last');
// Compter le nombre de pays
$('.pays &gt; li').length;
</code></pre>
<p>Magique non ?</p>
<h3>Comprendre la sélection <acronym title="Cascading Style Sheets">CSS</acronym> de jQuery</h3>
<p>Les résultats sont propres mais n&#8217;est pas parce que ça marche que c&#8217;est bien. La preuve, tous les exemples ci-dessus ne sont pas du tout optimisés.<br />
Alors <strong>comment savoir si un sélecteur est optimisé</strong> ou pas ? La réponse n&#8217;est pas systématique car elle dépend exclusivement de votre rigueur et du <acronym title="Document Object Model"><acronym title="Document Object Model">DOM</acronym></acronym> à interroger. Plus il sera touffu et plus votre sens aigü de la performance sera sollicité.</p>
<p>Reprenons les exemples ci-dessus pour le transposer en JavaScript <em>old-school</em>. C&#8217;est le meilleur moyen de sentir le piège &#8230; ou pas.</p>
<pre><code class="javascript">// Récupération du premier paragraphe
$('body p:first-child');
// équivaut à
document.getElementsByTagName('body')[0].getElementsByTagName('p')[0];</code></pre>
<p>Il y a 2 erreurs dans cette sélection :</p>
<ol>
<li>sélectionner <code>body</code>. <code>getElementsByTagName()</code> oblige à parcourir tous les nœuds du document (1000 s&#8217;il y en a 1000) alors qu&#8217;on n&#8217;en veut qu&#8217;un &#8230; et qu&#8217;il ne peut y en avoir d&#8217;un ;</li>
<li>on sélectionne ensuite tous les <code>p</code> du body. Autant le faire dès la première fois car là encore c&#8217;est tous les nœuds contenus dans <code>body</code> qui sont parcourus &#8230; y compris l&#8217;énorme liste à puces !</li>
</ol>
<pre><code class="javascript">// Récupération du nœud des continents
$('ul.continents');
// équivaut à
var continents = [];
var el = document.getElementsByTagName('ul');
for (i in el)
{
  if (el[i].className.match(/(^| )continents( |$)/);
  {
     continents.push(el[i]);
  }
}</code></pre>
<p>La sélection est ici trop générique. On voit bien que l&#8217;on est obligé de charger tous les éléments <code>ul</code> du <acronym title="Document Object Model">DOM</acronym> pour les filtrer.</p>
<pre><code class="javascript">// Récupération de la liste des capitales
$('.capitale');
// équivaut à
var capitales = [];
var el = document.getElementsByTagName('*');
for (i in el)
{
  if (el[i].className.match(/(^| )capitale( |$)/);
  {
     capitales.push(el[i]);
  }
}</code></pre>
<p>C&#8217;est probablement la dernière chose à faire. Cassez les genoux de toute personne écrivant un tel sélecteur : il mérite d&#8217;animer le BigDill rien de plus !<br />
Dans ce cas de figure, c&#8217;est TOUT le <acronym title="Document Object Model">DOM</acronym> qui est chargé (75 éléments) pour ensuite boucler sur un filtre. Cette boucle n&#8217;est pas optimisée mais ce n&#8217;est pas ce que l&#8217;on souhaite travailler aujourd&#8217;hui <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<pre><code class="javascript">// Récupération du dernier élément du body
$('body :last');
// équivaut à
var el = document.getElementsByTagName('body')[0].lastChild;</code></pre>
<p>Comme dans le premier cas, le <code>document.getElementsByTagName()</code> charge tout le <acronym title="Document Object Model">DOM</acronym> pour le filtrer, ne récupérer que le premier élément et, seule opération non coûteuse, utiliser son dernier enfant.<br />
Ce n&#8217;est pas la pire des exemples mais là encore on peut optimiser les choses.</p>
<pre><code class="javascript">// Compter le nombre de pays
$('.pays &gt; li').length;
// équivaut à
var pays = 0;
var el = document.getElementsByTagName('*');
for (i in el)
{
  if (el[i].className.match(/(^| )pays( |$)/);
    {
      var continent = el[i];
      for (j in continent.childNodes)
      {
        pays += continent.childNodes[j].nodeName == 'li' ? 1 : 0;
      }
    }
  }
}</code></pre>
<p>Un sélecteur par classe ne devrait être qu&#8217;un cas extrême, quand on ne peut se fier à une balise donnée. Car de manière générale, le <code>getElementsByTagName('*')</code> est à bannir. Charger tout le <acronym title="Document Object Model">DOM</acronym> est une folie furieuse.<br />
La bonne idée ici est l&#8217;utilisation du symbole <code>&gt;</code>. Cela se traduit par <code>.childNodes</code> et nous verrons plus bas pourquoi c&#8217;est mieux.</p>
<h3>Et maintenant, optimisons</h3>
<p>S&#8217;il fallait <strong>résumer l&#8217;optimisation en 3 points</strong>, voici ce que je donnerai :</p>
<ol>
<li>jamais de sélecteur vague</li>
<li>toujours un ID (#&lt;ID&gt;) en tête de sélecteur</li>
<li>utiliser au maximum les objets natifs (<code>firstChild</code>, <code>childNodes</code> etc.) : ils évitent d&#8217;interroger tout le <acronym title="Document Object Model">DOM</acronym></li>
</ol>
<p><strong>L&#8217;ennemi des sélecteurs <acronym title="Cascading Style Sheets">CSS</acronym> ce sont les boucles</strong>. Plus elles ont à brasser d&#8217;éléments, plus elles sont longues. <code>getElementsByTagName()</code> cache une boucle : JavaScript scanne tout le <acronym title="Document Object Model">DOM</acronym> pour trouver un nœud ayant un <code>tagName</code> correspondant.<br />
<strong>S&#8217;il faut l&#8217;utiliser, c&#8217;est en aval d&#8217;un sélecteur ayant déjà trié une bonne partie du document.</strong></p>
<p><strong>Votre meilleur ami est <code>getElementById()</code></strong>. Comme son nom l&#8217;indique il ne retourne qu&#8217;un seul élément et surtout, il est incroyablement rapide. Utilisez-le dans un maximum de cas mais attention tout de même : trop d&#8217;ID nuit à la structure du document le rendant ainsi trop rigide.<br />
Il en est de même du parcours des objets natifs des nœuds du <acronym title="Document Object Model">DOM</acronym>. Cela signifie que dès que vous changer la tête de votre <acronym title="HyperText Markup Language">HTML</acronym>, le JavaScript peut en pâtir.</p>
<p>Des fois <strong>il faudra faire quelques concessions de performances pour éviter de réécrire votre code</strong> au moindre changement &#8230; ou parce que la génération est dynamique et difficilement maîtrisable.</p>
<p>Grâce à ces informations, nous pouvons reprendre nos exemples mais de manière optimisée :</p>
<pre><code class="javascript">// Récupération du premier paragraphe
$('body p:first-child');
// version optimisée
$('#sandbox &gt; p:first');
// Récupération du nœud des continents
$('ul.continents');
// version optimisée
$('#geoliste');
// Récupération de la liste des capitales
$('.capitale');
// version optimisée (mais fortement liée à la structure du document)
$('#geoliste &gt; li &gt; ul ul &gt; li.capitale');
// Récupération du dernier élément du body
$('body :last');
// version optimisée
$('#sandbox :last');
// Compter le nombre de pays
$('.pays &gt; li').length;
// version optimisée (mais liée à la structure du document)
$('#geoliste &gt; li &gt; ul &gt; li').length;
</code></pre>
<h3>Évitons les doublons : chaînons !</h3>
<p>Les <acronym title="Cascading Style Sheets">CSS</acronym> c&#8217;est un peu fatiguant alors terminons sur une autre utilisation de jQuery parfois sous-employée à cause d&#8217;un manque de compréhension : les chaînes. jQuery renvoie des objets et permet de réutiliser/filtrer les résultats avec un seul sélecteur.</p>
<p>Voici un extrait de code largement optimisable :</p>
<pre><code class="javascript">$('#intro').addClass('jevaisdisparaitre');
$('#intro').append(' &lt;strong&gt;Je vais disparaître&lt;/strong&gt;.');
$('#intro code').html('Goodbye World');
$('#intro').css('cursor', 'pointer');
$('#intro').one('click', function(){ alert("Bye bye"); $(this).remove(); });
</code></pre>
<p>Tout est correct sauf qu&#8217;on répète plusieurs fois le même sélecteur au lieu d&#8217;utiliser la chaîne disponible. jQuery optimise la sélection d&#8217;un élément déjà sélectionné au préalable mais n&#8217;empêche, au lieu d&#8217;interroger 5 fois <code>#intro</code>, nous n&#8217;allons plus le faire qu&#8217;une seule fois :</p>
<pre><code class="javascript">$('#intro')
  .addClass('jevaisdisparaitre')
  .append(' &lt;strong&gt;Je vais disparaître&lt;/strong&gt;.')
  .one('click', function(){
    alert("Bye bye");
    $(this).remove();
  })
  .children('code')
  .html('Goodbye World');
</code></pre>
<p>Tout se suit jusqu&#8217;à la fonction <code>children()</code> qui modifie le sélecteur de départ et applique la suite de la chaîne à cette nouvelle sélection.<br />
Une autre optimisation consiste à déplacer la déclaration <acronym title="Cascading Style Sheets">CSS</acronym> <code>cursor</code> dans la classe <code>.jevaisdisparaitre</code> de l&#8217;hypothétique feuille de style. <strong>Essayez de dissocier au mieux fond et forme</strong> : ça évite <em>BEAUCOUP</em> de modifications de code pour des ajustements esthétiques.</p>
<h3>Conclusion</h3>
<p><strong>Optimiser ses sélecteurs n&#8217;est finalement pas si difficile que ça quand on comprend comment fonctionnent les rouages internes</strong>. Il est évident que les gains peuvent être minimes sur de petites pages. Il s&#8217;agit cependant d&#8217;une gymnastique à maîtriser : ce n&#8217;est pas en arrivant sur de gros volumes qu&#8217;il faudra apprendre à sélectionner proprement.</p>
<p>Et comme <q>les petites rivières font les grands fleuves</q>, ces petites économies pourraient vous sauver la vie sur des applications full-<acronym title="Asynchronous JavaScript and XML">AJAX</acronym> ou qui sait, quand vous travaillerez chez Netvibes <img src='http://case.oncle-tom.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2007/jquery-optimisation-selecteurs-css/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Modifier du HTML à la volée de manière non intrusive</title>
		<link>http://case.oncle-tom.net/2007/modifier-html-non-intrusif/</link>
		<comments>http://case.oncle-tom.net/2007/modifier-html-non-intrusif/#comments</comments>
		<pubDate>Mon, 10 Sep 2007 11:00:55 +0000</pubDate>
		<dc:creator>Oncle Tom</dc:creator>
				<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[Standards du Web]]></category>
		<category><![CDATA[bonnes pratiques]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[xpath]]></category>
		<guid isPermaLink="false">http://case.oncle-tom.net/2007/09/10/modifier-html-non-intrusif/</guid>
		<description><![CDATA[Lors de la refonte de ce blog, j&#8217;ai concocté un petit script JavaScript (non intrusif bien entendu) affichant et modifiant le contenu d&#8217;un bandeau sous la forme d&#8217;une classe statique reponsant sur jQuery. J&#8217;explique aujourd&#8217;hui comment ces 48 petits lignes de code (en comptant commentaires, sauts de lignes et accolades) fonctionnent, comment il est aisé [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align:center"><img src="http://case.oncle-tom.net/images/2007/09/javascript.png" alt="Javascript" /></p>
<p><a href="http://case.oncle-tom.net/2007/07/27/blog-nouveau-look/">Lors de la refonte de ce blog</a>, j&#8217;ai concocté un petit script JavaScript (non intrusif bien entendu) affichant et modifiant le contenu d&#8217;un bandeau sous la forme d&#8217;une classe statique reponsant sur <a href="http://jquery.com/">jQuery</a>. J&#8217;explique aujourd&#8217;hui comment ces 48 petits lignes de code (en comptant commentaires, sauts de lignes et accolades) fonctionnent, comment il est aisé de mettre en place de telles routines de manière intelligente, souple et non intrusive.</p>
<p>Et comme l&#8217;indique le slogan de <cite>jQuery</cite> : <q>Write less, do more</q>.<br />
<span id="more-769"></span></p>
<h3>Le besoin</h3>
<p>Avant de se lancer tête baissée dans le code, <strong>prenons le temps d&#8217;exprimer avec des mots ce que l&#8217;on aimerait faire</strong>.</p>
<p>On souhaite disposer d&#8217;une <strong>liste de liens</strong>. <strong>Lors d&#8217;un clic</strong> sur un lien de cette liste, l&#8217;<strong>encart correspondant doit s&#8217;afficher</strong> pour illustrer davantage son sens. Eventuellement, lorsque l&#8217;on <strong>reclique sur ce même lien</strong>, le visiteur est transporté sur la page en question.</p>
<p>J&#8217;ai grassé les mots importants de ce besoin. Vous le verrez par la suite, ils vont régir le comportement du script.</p>
<h3>La structure <acronym title="HyperText Markup Language">HTML</acronym></h3>
<p>Nous allons donc nous retrouver avec trois grosses parties dans le code :</p>
<ul>
<li><strong>la liste de liens</strong>, une balise <code>ul</code> semble toute indiquée)</li>
<li><strong>une liste de textes correspondants</strong>, il n&#8217;a pas lieu d&#8217;être visible pour l&#8217;utilisateur final concerné par le code</li>
<li>un <strong>bloc conteneur neutre</strong> destiné à recevoir les textes d&#8217;enrichissement de manière visuelle</li>
</ul>
<p>Des mots au code, voici ce que donnerait la structure balisée :</p>
<pre><code class="html">&lt;body&gt;
&lt;!-- (...) --&gt;
	&lt;div id="conteneur_cible"&gt;&lt;/div&gt;
	&lt;!-- (...) --&gt;
	&lt;ul id="liens_etendus"&gt;
		&lt;li&gt;&lt;a href="page1.html" class="page1"&gt;Page 1&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="page2.html" class="page2"&gt;Page 2&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="page3.html" class="page3"&gt;Page 3&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;!-- (...) --&gt;
	&lt;div id="conteneur_source"&gt;
		&lt;h2&gt;Titre&lt;/h2&gt;
		&lt;p&gt;Texte explicatif apportant de la cohérence aux utilisateurs dépourvus de JavaScript et d'interprétation des feuilles de style.&lt;/p&gt;
		&lt;ul&gt;
			&lt;li class="page1"&gt;Texte page 1&lt;/li&gt;
			&lt;li class="page2"&gt;Texte page 2&lt;/li&gt;
			&lt;li class="page3"&gt;Texte page 3&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;
&lt;!-- (...) --&gt;
&lt;/body&gt;
</code></pre>
<p><strong>L&#8217;ordre de la structure importe peu</strong> mais dans tous les cas, leur position dans le flux <acronym title="HyperText Markup Language">HTML</acronym> dépend avant tout de leur importance au sein de celui-ci. De manière générale, <strong>il vaut mieux disposer le contenu principal tout en haut du flux et le faire suivre par le contenu secondaire</strong> tels que les menus de navigation et les textes supplémentaires.<br />
Je pense que le code parle de lui-même, posez vos questions en commentaires si jamais il y a besoin d&#8217;explications plus poussées.</p>
<p>Côté <acronym title="HyperText Markup Language">HTML</acronym> tout est réglé avec ceci. <strong>Il ne restera éventuellement que du travail de stylage pour lui donner une apparence plus conviviale</strong>.<br />
Vous remarquerez qu&#8217;il n&#8217;y a aucune mention à du JavaScript à l&#8217;intérieur de ce code et ce sera le cas jusqu&#8217;au bout. C&#8217;est tout l&#8217;intérêt de séparer fond et forme et donc, du <strong>JavaScript non intrusif</strong>.</p>
<h3>Le code Javascript</h3>
<p>J&#8217;ai pris la décision d&#8217;écrire ce code pour <em>jQuery</em> car cette bibliothèque (ou <em>framework</em>) est embarquée dans WordPress et réduit drastiquement la quantité de code à écrire pour produire des résultats.</p>
<p>Dans la pratique, le code va se charger dès que possible (c&#8217;est à dire dès que le <acronym title="Document Object Model"><acronym title="Document Object Model">DOM</acronym></acronym> est prêt) et exécutera une méthode en se servant des paramètres prédéfinis ou passés manuellement à la classe. Le code suivant est structuré et suffisamment commenté pour le comprendre sans trop de difficulté. J&#8217;expliquerai en-dessous sa logique :</p>
<pre><code class="javascript">/*////////////////////////////////////////
// Classe statique 'oncletom_text_grabber'
// # Permet d'afficher un slide d'informations en cliquant sur un lien
// # C'est rigolo et en plus ça sert à quelque chose
// @ parametres (objet, optionnel) : objet de clé:valeur paramétrant le comportement
////////////////////////////////////////*/
function oncletom_text_grabber()
{
	var parametres = arguments.length == 1 &amp;&amp; typeof arguments[0] == 'object' ? arguments[0] : {};
	//Paramétrage de la fonction
	//# permet un lancement de la classe avec un paramétrage par défaut
	parametres.source = typeof parametres.source == 'undefined' ? '#conteneur_source &gt; ul &gt; li' : parametres.source;
	parametres.bindto = typeof parametres.bindto == 'undefined' ? '#liens_etendus a' : parametres.bindto;
	parametres.target = typeof parametres.target == 'undefined' ? '#conteneur_cible' : parametres.target;
	/*////////////////////////////////////////
	// Méthode publique 'ot_text_caller'
	// # Récupère le contenu associé à l'attribut 'rel'
	// # Méthode à appeler sur un évènement
	////////////////////////////////////////*/
	function ot_text_caller()
	{
		//sélection de l'élément à récupérer
		var id = $(this).attr('class');
		//hop ! on vérifie c'est déjà ouvert. Auquel cas le lien redevient cliquable
		if( $( parametres.target ).attr('class') == id )
		{
			return true;
		}
		//on nettoie le contenu de la destination
		$( parametres.target ).empty();
		$( parametres.target ).attr({ 'class' : '' });
		//on remplit la destination avec le bon contenu
		//on le fait en utilisant une expression régulières pour récupérer l'élément voulu
		$( parametres.target ).fadeIn( 'slow' ).append(  $( parametres.source+"."+id ).html() ).toggleClass( id );
		//évite que le lien soit cliqué
		return false;
	}
	//On greffe les différentes méthodes
	$( parametres.bindto ).click( ot_text_caller );
}
//exécution automatique de fonctions au lancement du document
$( oncletom_text_grabber );
//FACULTATIF
//pour assigner une deuxième liste de liens, il suffirait d'écrire le code ci-contre, par exemple :
//tous les paramètres non renseignés prennent la valeur par défaut de la classe
$( function(){ oncletom_text_grabber({ 'target' : '#nouveau_conteneur_cible', 'bindto' : '#exemple_entete ol a[@rel]', 'source' : '#liste_source2' }); } );
</code></pre>
<ol>
<li>Dans un premier temps, je m&#8217;applique toujours à pouvoir <strong>proposer une utilisation de la classe sans avoir à fournir de paramètre lors de son appel</strong>. C&#8217;est un côté pratique qui permet en plus de documenter les différentes options possibles. Ces options correspondent aux différents <a href="http://docs.jquery.com/DOM/Traversing/Selectors">sélecteurs jQuery</a> dont on aura besoin par la suite ;</li>
<li>Dans un deuxième temps, je déclare une méthode interne à la classe. <em>La cascade des accolades</em> fait qu&#8217;elle n&#8217;est accessible que depuis la classe. Cette méthode sera assignée à l&#8217;évènement <code>onclick</code> de tous les éléments concernés par <code>parametre.bindto</code>. En clair, des liens hypertextes. Le <code>this</code> y fait référence.
<ol>
<li>On stocke dans la variable interne <code>id</code> le nom de la classe. En effet, la classe du lien permet de récupérer le bon texte dans el conteneur source (<code>parametre.source</code>),</li>
<li>On vérifie que le conteneur cible ne porte pas le même nom de classe : si oui, on suit le lien, si non, on affiche d&#8217;abord le texte complémentaire (la suite),</li>
<li>Le passage le plus délicat consiste à extraire ce qu&#8217;il faut et le placer où il faut. Heureusement jQuery dispose de deux fonctions magiques : <code>append()</code> et <code>html()</code>. La première rajoute du <acronym title="HyperText Markup Language">HTML</acronym> à la suite du sélecteur tandis que la deuxième extrait le <acronym title="HyperText Markup Language">HTML</acronym> par sélection. Le fonctionnement en chaîne de jQuery permet de réaliser tout ceci en une ligne,</li>
<li>Pourquoi un <code>return false;</code> pour terminer ? Tout simplement pour éviter que le lien hypertexte contenu dans l&#8217;attribut <code>href</code> du lien soit suivi.</li>
</ol>
</li>
<li>Dans un troisième temps, on assigne la méthode déclarée juste avant. A chaque clic de chaque élément, elle sera appelée et surtout, aura accès à tous les paramètres de la classe ;</li>
<li>Enfin, après avoir clôturé la classe, on l&#8217;exécute dès que le <acronym title="Document Object Model">DOM</acronym> est chargé.</li>
</ol>
<h3>Conclusion et résultat</h3>
<p>Pour que ce code soit effectif, il faut bien évidemment l&#8217;insérer à même la page ou bien en appelant un script externe (cette méthode est recommandée justement pour dissocier fond et forme). Il faut aussi penser à inclure jQuery dans votre page sans quoi le compilateur JavaScript va tirer la tête.</p>
<p>Pour résumer, je résume la pensée des <strong>bonnes pratiques du JavaScript non intrusif</strong>, prouvant si besoin en était que JavaScript est loin d&#8217;être le Diable :</p>
<ol>
<li>définir sa structure <acronym title="HyperText Markup Language">HTML</acronym></li>
<li>styler le <acronym title="HyperText Markup Language">HTML</acronym></li>
<li>ajouter le JavaScript en surcouche</li>
</ol>
<p>Ainsi, <strong>on ne pénalise personne</strong> (y compris en cas d&#8217;erreur de programmation), <strong>on conserve un code lisible</strong> tout en <strong>facilitant sa réutilisation</strong> dans un autre document.</p>
]]></content:encoded>
			<wfw:commentRss>http://case.oncle-tom.net/2007/modifier-html-non-intrusif/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

