<?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>JavaScript &#8211; Les intégristes</title>
	<atom:link href="/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description></description>
	<lastBuildDate>Tue, 09 Feb 2021 15:28:58 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0</generator>
	<item>
		<title>Les plugins, nos amis qui nous rendent la vie dure&#8230;</title>
		<link>/2012/11/07/les-plugins-nos-amis-qui-nous-rendent-la-vie-dure/</link>
					<comments>/2012/11/07/les-plugins-nos-amis-qui-nous-rendent-la-vie-dure/#comments</comments>
		
		<dc:creator><![CDATA[Guillaume Richard]]></dc:creator>
		<pubDate>Wed, 07 Nov 2012 12:36:22 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<guid isPermaLink="false">/?p=3264</guid>

					<description><![CDATA[On le sait, jQuery et sa facilité de prise en main ont fait énormément de bien à la communauté.
Via le biais des plugins, tout le monde a pu commencer à faire des effets « wahou » en deux secondes et a pu commencé à vouloir écrire ses propres plugins&#8230; Rendons à César ce qui est à César et remercions jQuery pour avoir apporté une idée différente du framework javascript. Dans une discussion future, je me ferai peut-être moins respectueux en évoquant les différents maux que cette librairie a pu apporter.
Rapidité &#60; Qualité
Ce qui reste très agaçant, surtout&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p>On le sait, jQuery et sa facilité de prise en main ont fait énormément de bien à la communauté.</p>
<p>Via le biais des plugins, tout le monde a pu commencer à faire des effets « wahou » en deux secondes et a pu commencé à vouloir écrire ses propres plugins&#8230; Rendons à César ce qui est à César et remercions jQuery pour avoir apporté une idée différente du framework javascript. Dans une discussion future, je me ferai peut-être moins respectueux en évoquant les différents maux que cette librairie a pu apporter.</p>
<h2>Rapidité &lt; Qualité</h2>
<p>Ce qui reste très agaçant, surtout lorsqu&rsquo;on commence à prendre un peu de niveau dans son métier, c&rsquo;est quand un chef de projet vous pose cette question: « pourquoi tu n&rsquo;as pas utilisé un <em>plugin tout fait</em> à la place ? »; alors que vous auriez bien aimé tout de même avoir la chance de pouvoir démontrer que vous pouviez faire mieux et surtout : <strong>plus adapté au projet</strong>.<br />
Qui ne s&rsquo;est jamais arraché les cheveux à <em>faire rentrer un plugin dans un projet</em> en bidouillant l&rsquo;impossible, ajoutant des options dans l&rsquo;objet d&rsquo;options même si ce n&rsquo;était pas vraiment le meilleur endroit&#8230;</p>
<p>Mais plus loin encore, est-ce là un vrai travail responsable que d&rsquo;accepter l&rsquo;utilisation de plugins par son équipe technique ?<br />
Non seulement l&rsquo;équipe ne risque pas de prendre du niveau et très certainement se ramollir, voir se démotiver, mais en plus, vous rendez votre travail dépendant de ce qui se passe ailleurs, <em>chez les autres&#8230; </em>dépendant donc de la veille « plugin ».<br />
C&rsquo;est un peu comme à l&rsquo;époque du designers que les intégrateurs bridaient afin de pouvoir avoir des maquettes intégrables « <em>comme on l&rsquo;a toujours fait depuis des années</em>« , à force on obtenait presque toujours les mêmes briefs: « <em>A gauche donc, on aura une sidebar, à droite.. le contenu et puis au milieu, un jQuery Carousel de chez bidule »</em>; Grisant.<br />
D&rsquo;ailleurs, la version 2013 de ces pratiques sera « <em>en haut, le header, au milieu&#8230; et bah un bon gros jQuery mansonry hein ? t&rsquo;en dis quoi ? le footer ? Oh y&rsquo;en a pas besoin..</em>. »</p>
<p>Donnez-vous une année comme cela, sans faire un peu de programmation chez vous et vous allez vite voir que vous allez très rapidement perdre vos compétences.</p>
<p>Petite blague à part: Vous n&rsquo;avez jamais remarqué que sur stackoverflow, à chaque question en js natif il y a toujours une armée de réponses type « <em>pourquoi tu n&rsquo;utilises pas jQuery</em>« . Et si demain vous ne deviez pas l&rsquo;utilisez, pour des raisons d&rsquo;optimisations ? Et si sans jQuery vous vous rendiez compte que vous ne compreniez qu&rsquo;une partie de la DOM API et donc, à votre métier ? True story que cela et je vous la raconterai peut-être en temps voulu&#8230; mais autre sujet, autre journée.</p>
<h2>L&rsquo;artisanat français</h2>
<p><small>Oui monsieur&#8230;</small></p>
<p>Il reste aussi le problème de l&rsquo;honnêteté.<br />
La plupart de ces <em>plugins</em> sont souvent réalisés à des fins de promotion personnelle, donner à ceux qui ne savent pas programmer l&rsquo;occasion d&rsquo;avoir un petit plus sur leur blog ou de réutiliser plusieurs fois un travail réalisé pour un client ou encore simplement démontrer un concept, une idée simple.</p>
<p>Il est évident qu&rsquo;à un certain niveau de la hiérarchie, on ne se préoccupe pas trop de comment un projet est commencé et fini, il faut tout simplement qu&rsquo;il soit fini.<br />
Là où cela devient préoccupant, c&rsquo;est lorsque le chef de projet technique ne s&rsquo;en préoccupe pas non plus&#8230; et encore plus préoccupant d&rsquo;entendre ce genre de propos dans la bouche d&rsquo;un développeur front-end.</p>
<p>C&rsquo;est peut-être du au fait qu&rsquo;en France, au delà de 8 à 10 ans en tant que technicien, il est inconcevable de ne pas rechercher ou accepter un magnifique poste de manager et / ou de chef de projet, poste qui fera systématiquement, si on n&rsquo;y prête pas garde, perdre le fil de la veille technologique (en fait plutôt les compétences que la veille).<br />
Quelle belle récompense pour tant d&rsquo;année de bon et loyaux services, mais ça, c&rsquo;est déjà un sujet assez récurrent sur ce blog et je n&rsquo;y reviendrais plus (promis juré !)</p>
<p>Cela est peut-être aussi du au fait que depuis les <em>plugins à tout va</em>, on sait qu&rsquo; un site Internet coutera moins cher et sera surtout réalisé plus rapidement. Par conséquent, « on » est toujours plutôt gagnant&#8230; enfin sauf pour les « techos » mais eux, ils attendent patiemment leur 8 à 10 ans pour devenir chef de projet (quoi, vous voulez pas être CP ou manager ? Mais puisqu&rsquo;on vous dit que vous n&rsquo;avez pas le choix !)</p>
<p>La seule question qui restent à mes yeux importante :  Est-ce un service que nous rendons au <strong>métier</strong> ?<br />
Je m&rsquo;étonne bien souvent de notre retard sur les points de l&rsquo;UX, de l&rsquo;UI et du design de site Internet mais n&rsquo;est-ce pas avant tout parce que nous travaillons presque toujours à l&rsquo;inspiration en regardant un peu ce qui a déjà été fait et finalement très peu en workshop ? Que les commerciaux vendent d&rsquo;office des promesses impossibles à tenir ? Ou, peut-être est-ce parce qu&rsquo;on s&rsquo;obstine à rechercher des ninjas en PHP/MYSQL/AS3/CSS3/HTML5/JS/ASP au lieu de profils spécialisés dans l&rsquo;interface utilisateur&#8230; Ou pire, que certains bloggeurs influents parlent partout de <em>webresponsive </em>sans exactement comprendre les implications (encore un bon sujet potentiel que celui-ci)</p>
<h2>Be open! Oui mais&#8230;</h2>
<p>Alors, au final, merci jQuery mais par pitié, vous, développeurs de plugins, soyez fermes avec vos licences d&rsquo;utilisations et menez la vie dure aux entreprises qui utilisent vos plugins sans en avoir l&rsquo;autorisation. De cette manière, nous pourrons ainsi tous combattre l&rsquo;utilisation de plugins en entreprise tout en permettant aux gens de s&rsquo;inspirer et/ou regarder directement le code via GitHub pour <strong>apprendre</strong> sans pour autant réutiliser&#8230; sinon dans quelques années, il faudra ajouter la ligne « <strong>google-isation de plugins</strong> » sur nos CVs.</p>
<p>Il serait d&rsquo;ailleurs intéressant de savoir ce que pense certaines personnes de l&rsquo;utilisation de leurs plugins pour des projets professionnels vendus à quelques dizaines voir centaines de milliers de <em>brouzoufs</em>&#8230; qui se souvient encore de l&rsquo;utilisation d&rsquo;un blog Dotclear pour un site Internet vivant à promouvoir certaines lois que l&rsquo;état était désireux de passer ? Et qui se souvient du prix à laquelle ce Dotclear avait été vendu ?</p>
]]></content:encoded>
					
					<wfw:commentRss>/2012/11/07/les-plugins-nos-amis-qui-nous-rendent-la-vie-dure/feed/</wfw:commentRss>
			<slash:comments>19</slash:comments>
		
		
			</item>
		<item>
		<title>Introduction à WAI ARIA (traduction)</title>
		<link>/2008/12/09/introduction-a-wai-aria-traduction/</link>
					<comments>/2008/12/09/introduction-a-wai-aria-traduction/#comments</comments>
		
		<dc:creator><![CDATA[Pierre Bertet]]></dc:creator>
		<pubDate>Tue, 09 Dec 2008 11:39:40 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[ARIA]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">/?p=399</guid>

					<description><![CDATA[Grégoire Dierendonck

L&#8217;article qui suit est la traduction de l&#8217;article « Introduction to WAI ARIA« , publié par Gez Lemon sur Dev Opera, le site d&#8217;Opera Software destiné aux développeurs.
Gez Lemon est un expert reconnu de l&#8217;accessibilité web. Il est membre du WaSP ( Accessibility Task Force ) et travaille pour The Paciello Group, entreprise de conseil spécialisée dans l&#8217;accessibilité web.
Cette traduction, comme l&#8217;article original, est placée sous licence Creative Commons by-nc-sa 2.5.

Cet article est destiné à des personnes ne connaissant pas ARIA. Vous devriez avoir une bonne connaissance du langage HTML et des problèmes que peuvent&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="text-align:center;font-size:10px;"><img loading="lazy" src="/wp-content/uploads/2008/12/illu-aria4.jpg" alt="Illustration par Grégoire Dierendonck" title="" width="380" height="435"><br />
<a style="margin-left:10px;text-decoration:none;" href="http://www.troispongdesign.fr/"><em>Grégoire Dierendonck</em></a></p>
<div class="preamble">
<p>L&rsquo;article qui suit est la traduction de l&rsquo;article « <a href="http://dev.opera.com/articles/view/introduction-to-wai-aria/">Introduction to WAI ARIA</a>« , publié par <a href="http://juicystudio.com/">Gez Lemon</a> sur <a href="http://dev.opera.com/">Dev Opera</a>, le site d&rsquo;Opera Software destiné aux développeurs.</p>
<p>Gez Lemon est un expert reconnu de l&rsquo;accessibilité web. Il est membre du <a href="http://www.webstandards.org/"><abbr title="The Web Standards Project">WaSP</abbr></a> ( <a href="http://www.webstandards.org/action/atf/">Accessibility Task Force</a> ) et travaille pour <a href="http://www.paciellogroup.com/">The Paciello Group</a>, entreprise de conseil spécialisée dans l&rsquo;accessibilité web.</p>
<p>Cette traduction, comme l&rsquo;article original, est placée sous licence <a href="http://creativecommons.org/licenses/by-nc-sa/2.5/deed.fr">Creative Commons by-nc-sa 2.5</a>.</p>
</div>
<p>Cet article est destiné à des personnes ne connaissant pas ARIA. Vous devriez avoir une bonne connaissance du langage HTML et des problèmes que peuvent rencontrer les personnes handicapées sur le web. Connaître quelques application web « riches » (RIA) d&rsquo;un point de vue utilisateur serait un plus.</p>
<p>Après avoir lu cet article, vous comprendrez à quoi sert ARIA, comment l&rsquo;intégrer à vos sites, et comment l&rsquo;utiliser dès immédiatement et même sur le plus simple des sites pour le rendre plus accessible.</p>
<h2>Introduction</h2>
<p>Le langage HTML (HyperText Markup Language) n&rsquo;a pas été conçu pour créer des applications web. Le nombre de contrôles (bouton, case à cocher, etc.) qu&rsquo;il propose est limité, et il est basé sur une communication client / serveur séquentielle. Les développeurs d&rsquo;applications web ont contourné ces limitations en créant leurs propres widgets (contrôles graphiques) associés à Javascript pour leur ajouter le comportement désiré.</p>
<p>Malheureusement, les techniques utilisées pour outrepasser ces limitations ne sont absolument pas accessibles. Bien que ces widgets ressemblent à ceux d&rsquo;une application bureau classique comme la représentation d&rsquo;une arborescence (tree view), le rôle (ce que le widget fait), l&rsquo;état (sa configuration, comme « checked » pour une case à cocher), et d&rsquo;autres informations importantes ne sont pas disponibles pour les technologies d&rsquo;assistance (comme les lecteurs d&rsquo;écran). Ce serait comme styler une ligne de texte pour qu&rsquo;elle ressemble à un titre, sans utiliser un élément définissant un titre (h1 à h6). Le texte ressemble à un titre, mais les technologies d&rsquo;assistance n&rsquo;ont pas accès à cette information.</p>
<p>Les mises à jour sont souvent mal perçues par les personnes utilisant une technologie d&rsquo;assistance. Ces outils s&rsquo;attendent à ce que le contenu change lors d&rsquo;un événement de navigation « classique », comme un clic sur un lien ou un envoi de formulaire. Les applications web utilisent des techniques comme <abbr title="Asynchronous JavaScript and XML">AJAX</abbr> pour mettre à jour le contenu en arrière plan, ce qui peut passer inaperçu pour les technologies d&rsquo;assistance. Si elles sont tout de même informées de ces mises à jour, l&rsquo;utilisateur n&rsquo;est pas pour autant informé que le contenu à été mis à jour, et n&rsquo;a aucun moyen de localiser la zone mise à jour.</p>
<p><a href="http://www.w3.org/WAI/intro/aria"><abbr title="Web Accessibility Initiative">WAI</abbr>&#8211;<abbr title="Accessible Rich Internet Applications">ARIA</abbr></a> est une spécification qui propose la possibilité de définir une description des rôles, des états et des propriétés pour les widgets personnalisés, de manière à ce qu&rsquo;ils soient reconnaissables et utilisables par les utilisateurs de technologies d&rsquo;assistance. WAI-ARIA propose également un système permettant de s&rsquo;assurer qu&rsquo;un utilisateur de technologie d&rsquo;assistance est informé des mises à jour de l&rsquo;application.</p>
<h2>Petit historique du langage HTML</h2>
<p>Le langage HTML a été conçu pour être un système hypertexte, permettant de structurer et de partager des documents liés entre eux. Les premiers brouillons de la spécification HTML définissaient des balises comme des titres, des paragraphes, des listes, ou des ancres, pour ajouter une structure à des documents texte. La <a href="http://www.w3.org/MarkUp/draft-ietf-iiir-html-01.txt">première proposition d&rsquo;une spécification HTML</a> par l&rsquo;<abbr title="Internet Engineering Task Force">IETF</abbr> incluait l&rsquo;élément <code>img</code>, permettant d&rsquo;ajouter des images à l&rsquo;intérieur du document. La première spécification formelle fût <a href="http://tools.ietf.org/html/rfc1866">HTML 2</a>, basée sur les premiers brouillons de HTML. Cette spécification a défini les formulaires, ainsi que quelques composants d&rsquo;interface permettant de créer des zones éditables, des boutons, des cases à cocher, des boutons radio, et des menus déroulants. Le petit ensemble de de contrôles définis dans HTML 2 n&rsquo;a quasiment pas changé jusqu&rsquo;à <a href="http://www.w3.org/TR/html401/">HTML 4.01</a>, que nous utilisons actuellement.</p>
<p>Le modèle de communication de HTML est basé sur un modèle client / serveur&nbsp;: le client envoie des requêtes et reçoit des réponses&nbsp;; Le serveur web attend les requêtes, les traite, puis renvoie une réponse au client. Puisque HTML ne définit pas de gestion de comportement, la communication est séquentielle&nbsp;: le client demande une page au serveur, le serveur traite la requête et renvoie une page au client.</p>
<h2>Applications web</h2>
<p>Les applications web essaient d&rsquo;imiter les applications bureau classiques, mais ces applications web sont elles-mêmes exécutées à l&rsquo;intérieur d&rsquo;une application bureau&nbsp;: le navigateur. Il existe deux différences fondamentales entre HTML, avec son modèle de communication, et une application de bureau traditionnelle&nbsp;:</p>
<ul>
<li>Les applications de bureau possèdent une couche de comportement qui ne repose pas sur des requêtes serveur.</li>
<li>Les applications de bureau possèdent un nombre bien plus élevé de widgets.</li>
</ul>
<h2>Reproduction d&rsquo;applications bureau</h2>
<h3>Requêtes serveur en arrière plan</h3>
<p>Pour simuler les applications bureau classiques, les applications web utilisent Javascript pour la partie comportement. Javascript peut par exemple être utilisé pour ouvrir et refermer un élément de menu lorsque l&rsquo;utilisateur intéragit avec l&rsquo;élément. Des données doivent parfois être récupérées sur le serveur&nbsp;: l&rsquo;application peut par exemple récupérer des enregistrement dans une base de données pour mettre à jour des informations sur la page. Lorsque l&rsquo;application doit interagir avec le serveur, des techniques comme AJAX ou un élément IFrame masqué sont utilisés pour communiquer de manière transparente avec le serveur.</p>
<h3>Reproduire des composants riches (widgets)</h3>
<p>Puisque HTML propose très peu de widgets (ndt&nbsp;: dans la suite de l&rsquo;article, ce mot sera souvent utilisé pour désigner les contrôles d&rsquo;interface), il est parfois nécessaire de créer des composants plus complexes pour une application web, comme une case à cocher proposant trois états, ou un bouton glissant (slider). Ces composants sont habituellement créés en utilisant des éléments graphiques couplés à Javascript pour qu&rsquo;ils ressemblent et se comportent comme des composants natifs.</p>
<p><img loading="lazy" src="/wp-content/uploads/2021/02/tristate.gif" alt="Trois cases à cocher&nbsp;: non cochée, cochée, et à moitié cochée" width="228" height="171"></p>
<p>Figure 1 — Une boîte de dialogue avec une case à cocher proposant trois états.</p>
<p><img loading="lazy" src="/wp-content/uploads/2021/02/slider.gif" alt="Un bouton glissant proposant d'indiquer la qualité d'un service" width="358" height="65"></p>
<p>Figure 2 — Un bouton glissant (slider) pouvant être utilisé pour indiquer la qualité d&rsquo;un service.</p>
<h2>Problèmes d&rsquo;accessibilité avec la reproduction de composants natifs</h2>
<p>Visuellement, créer des contrôles riches et effectuer des requêtes serveur en arrière plan permet de créer une meilleure expérience utilisateur. Malheureusement, ces techniques posent de graves problèmes d&rsquo;accessibilité pour les utilisateurs de technologies d&rsquo;assistance, comme les lecteurs d&rsquo;écran.</p>
<ul>
<li>Les composants créés de cette manière sont rarement accessibles au clavier.</li>
<li>Le rôle d&rsquo;un composant, « ce qu&rsquo;il fait », n&rsquo;est pas accessible aux technologies d&rsquo;assistance.</li>
<li>Les états et propriétés d&rsquo;un composant ne sont pas accessibles aux technologies d&rsquo;assistance.</li>
<li>Les mises à jour ne sont pas signalées aux technologies d&rsquo;assistance.</li>
</ul>
<h2>WAI-ARIA à la rescousse</h2>
<p>Tous les problèmes listés ci-dessus sont résolus par la specification <strong>WAI-ARIA</strong> (qui sera abrégée <strong>ARIA</strong> jusqu&rsquo;à la fin de cet article)&nbsp;: <strong>W</strong>eb <strong>A</strong>ccessibility <strong>I</strong>nitiative’s <strong>A</strong>ccessible <strong>R</strong>ich <strong>I</strong>nternet <strong>A</strong>pplications. ARIA est une technologie <em>positive</em>&nbsp;: plutôt que de dire aux développeurs ce qu&rsquo;ils ne peuvent pas faire, elle leur propose simplement de créer des applications web riches. ARIA est de plus une technologie très facile à implémenter.</p>
<h2>Navigation au clavier</h2>
<p>En plus de proposer une alternative aux éléments non-textuels, permettre d&rsquo;interagir avec les contrôles d&rsquo;interface à l&rsquo;aide du clavier fait partie du minimum à mettre en place pour rendre un système plus accessible. Un développeur sensibilisé à l&rsquo;accessibilité devrait réaliser des widgets dont les éléments permettent de recevoir le focus, tout comme le fait par défaut un élément <code>input</code> de type <code>image</code> (<code>&lt;input type="image" ...&gt;</code>). Malheureusement, la plupart des widgets ne sont pas réalisés de cette manière&nbsp;: ils utilisent plutôt des éléments comme <code>img</code>, ou peuvent être composés de plusieurs éléments placés dans un conteneur <code>div</code> qui ne reçoit pas le focus.</p>
<p>L&rsquo;attribut <code>tabindex</code> est arrivé avec HTML4, utilisable sur les éléments suivants&nbsp;: <code>a</code>, <code>area</code>, <code>button</code>, <code>input</code>, <code>object</code>, <code>select</code>, et <code>textarea</code>. Cet attribut accepte un nombre positif compris entre <code>0</code> et <code>32767</code>. La navigation commence avec les éléments ayant la plus petite valeur <code>tabindex</code>, et se poursuit jusqu&rsquo;à l&rsquo;élément ayant la valeur la plus élevée. Les éléments ayant pour valeur <code>0</code> sont visités dans leur ordre naturel d&rsquo;apparition dans le code. Si le document a une structure logique, l&rsquo;attribut <code>tabindex</code> n&rsquo;est pas requis car les éléments d&rsquo;interface sont naturellement définis dans l&rsquo;ordre de tabulation.</p>
<p>ARIA <a href="http://www.w3.org/TR/wai-aria/#tabindex">étend l&rsquo;attribut tabindex</a>, lui permettant d&rsquo;être utilisé sur tous les éléments visibles. ARIA autorise également l&rsquo;utilisation d&rsquo;une valeur négative pour les éléments ne devant pas être proposés à la navigation au clavier, mais pouvant recevoir le focus par programmation. Bien que la valeur d&rsquo;un attribut tabindex négatif n&rsquo;aie pas d&rsquo;importance (l&rsquo;élément ne pourra jamais recevoir le focus au clavier), la valeur -1 est couramment utilisée lorsqu&rsquo;un élément ne doit pas recevoir le focus au clavier, mais uniquement par programmation.<br />
Par exemple, vous pourriez réaliser un menu dont l&rsquo;élément conteneur est accessible à l&rsquo;aide de la tabulation clavier, mais pas les éléments qu&rsquo;il contient. Ces éléments peuvent alors être programmés pour être parcourus à l&rsquo;aide des touches fléchées du clavier. Ainsi, les utilisateur n&rsquo;ont pas à utiliser la touche tabulation sur chacun des éléments du menu, ce qui leur permet de mieux accéder au document. C&rsquo;est vrai pour tous les widgets ayant une série de composants nécessitant un accès au clavier, comme la représentation d&rsquo;une arborescence.</p>
<h3>Ajouter un élément à l&rsquo;ordre naturel des tabulations</h3>
<p>L&rsquo;exemple suivant affecte la valeur <code>0</code> à l&rsquo;attribut <code>tabindex</code> pour placer l&rsquo;élément <code>div</code> dans l&rsquo;ordre des tabulations, ce qui permettra  d&rsquo;y accéder à l&rsquo;aide de la navigation clavier.</p>
<pre><code class="language-markup">&lt;div tabindex="0"&gt;
...
&lt;/div&gt;</code></pre>
<h3>Tabindex négatif</h3>
<p>L&rsquo;exemple suivant utilise un <code>tabindex</code> d&rsquo;une valeur négative, cet élément pourra alors recevoir le focus par programmation.</p>
<pre><code class="language-markup">&lt;div id="progaccess" tabindex="-1"&gt;
...
&lt;/div&gt;</code></pre>
<p>Dans cet exemple, l&rsquo;élément <code>div</code> n&rsquo;est pas placé dans l&rsquo;ordre des tabulations, mais possède un attribut <code>tabindex</code> d&rsquo;une valeur de <code>-1</code>. Le script qui suit sélectionne l&rsquo;élément précédemment défini et utilise la méthode <code>focus()</code> pour activer le focus sur cet élément.</p>
<pre><code class="language-javascript">var objDiv = document.getElementById('progaccess');

// Focus on the element
objDiv.focus();</code></pre>
<h2>Que suis-je&nbsp;?</h2>
<p>ARIA propose l&rsquo;<a href="http://www.w3.org/TR/wai-aria/#Using_intro">attribut <code>role</code></a> pour définir les widgets, comme un bouton glissant (slider), ou définir la structure de la page, comme un menu. Un problème majeur des applications web est que n&rsquo;importe quel élément peut être utilisé pour créer un widget. Les éléments HTML possèdent déjà des rôles prédéfinis. Le rôle d&rsquo;un élément est « ce qu&rsquo;il fait » &#8211; le rôle qu&rsquo;il a dans la structure. Par exemple, le rôle des titres est bien compris par les technologies d&rsquo;assistances. Lorsque des widgets sont réalisés à partir d&rsquo;éléments existants, le rôle d&rsquo;un élément est ce que la technologie d&rsquo;assistance définit plutôt que ce qu&rsquo;il représente visuellement en tant que widget. Par exemple, si le visuel d&rsquo;un slider est créé en utilisant un élément <code>img</code> avec un texte alternatif approprié, un lecteur d&rsquo;écran pourrait annoncer le contrôle comme ceci&nbsp;: « Image d&rsquo;un slider », plutôt que quelque chose de plus intéressant, comme « Bouton glissant, 16 pour cents ».</p>
<p><img loading="lazy" src="/wp-content/uploads/2021/02/thumb.gif" alt="Image d'un bouton glissant (slider)" width="166" height="81"></p>
<p>Figure 3 — L&rsquo;image d&rsquo;un bouton glissant (slider) classique.</p>
<p>Le rôle donné par l&rsquo;attribut <code>role</code> prend le pas sur le rôle natif de l&rsquo;élément. Dans l&rsquo;exemple suivant, un élément <code>input</code> possède un attribut <code>role</code> dont la valeur est <code>slider</code> (nous verrons d&rsquo;autres propriétés ARIA plus loin dans cet article) — le rôle indiqué à la technologie d&rsquo;assistance est <code>slider</code> (bouton glissant), plutôt que <code>input</code> (entrée utilisateur).</p>
<pre><code class="language-markup">&lt;input type="image" src="thumb.gif"
alt="Effectiveness"
role="slider"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="42"
aria-valuetext="42 percent"
aria-labelledby="leffective"&gt;</code></pre>
<p>Lorsque le focus est placé sur cet élément, un utilisateur de lecteur d&rsquo;écran comprend ce que fait ce widget. La spécification ARIA propose une <a href="http://www.w3.org/TR/wai-aria/#roles">liste de rôles</a>.</p>
<h3>Rôle des sections du document (document landmark roles)</h3>
<p>Les rôles que nous venons de voir permettent de décrire des widgets, mais il existe également des rôles permettant de décrire la structure du document. Les <a href="http://www.w3.org/TR/wai-aria/#roleattribute_inherits">document landmarks</a> (ou description des zones) sont un sous-ensemble des rôles classiques permettant aux utilisateurs de lecteurs d&rsquo;écran de comprendre le rôle d&rsquo;une zone pour mieux s&rsquo;orienter dans le document.</p>
<p><img loading="lazy" src="/wp-content/uploads/2021/02/pagestructure.gif" alt="Structure de la page" width="179" height="256"></p>
<p>Figure 4 — Une page classique avec une bannière, une barre latérale et une zone de contenu principale.</p>
<p>ARIA définit les rôles de document landmarks (zones du document) suivants&nbsp;:</p>
<dl>
<dt><code>article</code></dt>
<dd>Contenu ayant du sens par lui-même, comme un article ou un commentaire de blog, un message sur un forum, etc.</dd>
<dt><code>banner</code></dt>
<dd>Contenu à propos du site, comme le titre de la page ou le logo.</dd>
<dt><code>complementary</code></dt>
<dd>Permet éventuellement de définir une partie du contenu principal, mais est plus approprié pour du contenu séparé&nbsp;: la météo sur un portail web par exemple.</dd>
<dt><code>contentinfo</code></dt>
<dd>Contenu dépendant d&rsquo;un autre, comme des notes de bas de page, un copyright, un lien vers la déclaration de confidentialité, un lien vers les paramètres de l&rsquo;application, etc.</dd>
<dt><code>main</code></dt>
<dd>Contenu directement lié ou englobant le contenu central du document.</dd>
<dt><code>navigation</code></dt>
<dd>Contient des liens pour naviguer dans ou en dehors du document.</dd>
<dt><code>search</code></dt>
<dd>Cette section contient un formulaire de recherche permettant de chercher sur le site.</dd>
</dl>
<p>Les exemples suivants utilisent les rôles banner, navigation et main pour définir la structure de la page visible sur la figure 4.</p>
<pre><code class="language-markup">&lt;div role="banner"&gt;
...
&lt;/div&gt;
&lt;div role="navigation"&gt;
...
&lt;/div&gt;
&lt;div role="main"&gt;
...
&lt;/div&gt;</code></pre>
<h2>États et propriétés d&rsquo;ARIA</h2>
<p>Les <a href="http://www.w3.org/TR/wai-aria/#introstates">états (states) et propriétés (properties)</a> d&rsquo;ARIA permettent de décrire des informations supplémentaires sur les widgets et de les mettre à la disposition des technologies d&rsquo;assistance, afin d&rsquo;aider l&rsquo;utilisateur à comprendre comment intéragir avec le widget. L&rsquo;état définit une configuration ou une information unique sur un objet. Par exemple, la propriété <code>aria-checked</code> possède trois valeurs pour définir ses états&nbsp;: <code>true</code>, <code>false</code> et <code>mixed</code>.</p>
<p>Dans l&rsquo;exemple du bouton glissant vu un peu plus haut, nous avons inclus différentes propriétés que nous allons voir ci-dessous, aidant à décrire un widget à une technologie d&rsquo;assistance.</p>
<dl>
<dt><code>aria-valuemin</code></dt>
<dd>Stocke la valeur minimale qu&rsquo;un bouton glissant peut avoir.</dd>
<dt><code>aria-valuemax</code></dt>
<dd>Stocke la valeur maximale qu&rsquo;il peut avoir.</dd>
<dt><code>aria-valuenow</code></dt>
<dd>Stocke la valeur actuelle.</dd>
<dt><code>aria-valuetext</code></dt>
<dd>Stocke du texte lisible permettant à l&rsquo;utilisateur de comprendre le contexte. <code>"30 dollars"</code>, par exemple.</dd>
<dt><code>aria-labelledby</code></dt>
<dd>Stocke l&rsquo;identifiant (attribut id) d&rsquo;un élément contenant une description appropriée du widget.</dd>
</dl>
<p>Certaines propriétés peuvent être modifiées par programmation. Dans l&rsquo;exemple suivant, les propriétés <code>arial-valuenow</code> et <code>arial-valuetext</code> de notre widget de bouton glissant sont mises à jour lorsque le bouton change de position&nbsp;:</p>
<pre><code class="language-javascript">// Définit les valeurs des propriétés ARIA
// lorsque le bouton change de position
objThumb.setAttribute('aria-valuenow', iValue);
objThumb.setAttribute('aria-valuetext', iValue + ' %');</code></pre>
<p>Ajouter des rôles et attributs ARIA ne sera pas valide HTML 4.01 ou XHTML1.0, mais rassurez-vous, ARIA ne fait qu&rsquo;ajouter des informations importantes à des spécifications écrites depuis un bon moment maintenant. Des travaux sont en cours pour <a href="http://www.w3.org/WAI/PF/adaptable/StatesAndProperties-20051106.html">définir une DTD pouvant être utilisée avec du XML modulaire</a>, comme XHTML1.1. La spécification ARIA fournit une <a href="http://www.w3.org/TR/wai-aria/#supported">liste complète des états et propriétés</a> permettant de définir des widgets accessibles.</p>
<h2>Les « Live Regions » (zones mises à jour)</h2>
<p>Les Live Regions permettent à certains éléments du document d&rsquo;annoncer qu&rsquo;ils ont été mis à jour, sans que l&rsquo;utilisateur ne soit dérangé dans son activité. Cela signifie que les utilisateurs vont pouvoir être informés des mises à jour sans modifier leur position dans le contenu. Par exemple, une application de chat pourrait signaler une réponse de la personne avec qui l&rsquo;utilisateur est en train de discuter, sans être déplacé en-dehors du champ permettant d&rsquo;envoyer un nouveau message à la personne.</p>
<h3>aria-live</h3>
<p>Pour un utilisateur de lecteur d&rsquo;écran, il est très difficile de comprendre ce qui a été mis à jour sur une page. ARIA propose la propriété <code>aria-live</code>, dont la valeur indique l&rsquo;importance des mises à jour de la région. Voici les différents niveaux d&rsquo;alerte pouvant être utilisés avec la propriété <code>aria-live</code>&nbsp;:</p>
<dl>
<dt><code>off</code></dt>
<dd>Il s&rsquo;agit de la valeur par défaut, indiquant que la zone ne sera pas mise à jour.</p>
<pre><code class="language-markup">&lt;ul aria-live="off"&gt;</code></pre>
</dd>
<dt><code>polite</code></dt>
<dd>C&rsquo;est une notification normale, le comportement généralement attendu d&rsquo;une Live Region. La valeur polite indique qu&rsquo;il n&rsquo;est pas nécessaire d&rsquo;y répondre tant que l&rsquo;utilisateur n&rsquo;a pas terminé ce qu&rsquo;il est actuellement en train de faire.</p>
<pre><code class="language-markup">&lt;ul aria-live="polite"&gt;</code></pre>
</dd>
<dt><code>assertive</code></dt>
<dd>Ce niveau d&rsquo;alerte est plus élevé que la normale, mais n&rsquo;interrompt pas nécessairement l&rsquo;utilisateur.</p>
<pre><code class="language-markup">&lt;ul aria-live="assertive"&gt;</code></pre>
</dd>
<dt><code>rude</code></dt>
<dd>Cette valeur est la plus élevée, et interrompt l&rsquo;utilisateur pour lui notifier la mise à jour. Il peut s&rsquo;en trouver désorienté, et peut empêcher l&rsquo;utilisateur de reprendre la tâche qu&rsquo;il effectuait. Elle ne devrait être utilisée qu&rsquo;en cas d&rsquo;absolue nécessité.</p>
<pre><code class="language-markup">&lt;ul aria-live="rude"&gt;</code></pre>
</dd>
</dl>
<p>Quelques autres propriétés peuvent être utilisées lorsqu&rsquo;une Live Region est créée, en voici la liste.</p>
<h3>La propriété <code>aria-atomic</code></h3>
<p><code>aria-atomic</code> est une propriété optionnelle des Live Regions pouvant prendre comme valeur <code>true</code> ou <code>false</code> (par défaut si la propriété n&rsquo;est pas définie).</p>
<p>Lorsque la zone est mis à jour, la propriété <code>aria-atomic</code> permet à la technologie d&rsquo;assistance de savoir si elle doit décrire à l&rsquo;utilisateur la zone entière ou seulement la partie ayant été mise à jour. Si cette propriété est définie à <code>true</code>, la technologie d&rsquo;assistance devrait décrire complètement la zone. Si sa valeur est <code>false</code>, seule la partie mise à jour devrait être annoncée.</p>
<p>Dans l&rsquo;exemple suivant, tous les éléments de la liste non-ordonnée seront annoncés à l&rsquo;utilisateur, à moins qu&rsquo;un de ces éléments ne surcharge la propriété <code>aria-atomic</code>.</p>
<pre><code class="language-markup">&lt;ul aria-atomic="true"
aria-live="polite"&gt;</code></pre>
<h3>La propriété <code>aria-busy</code></h3>
<p><code>aria-busy</code> est une propriété optionnelle des Live Regions pouvant prendre comme valeur <code>true</code> ou <code>false</code> (par défaut si la propriété n&rsquo;est pas définie). Si plusieurs parties d&rsquo;une Live Region ont besoin d&rsquo;être chargées avant que la mise à jour ne soit annoncée à l&rsquo;utilisateur, la propriété <code>aria-busy</code> peut être définie à <code>true</code> jusqu&rsquo;à ce que la dernière partie soit chargée, puis à <code>false</code> lorsque la mise à jour est complètement terminée. Cette propriété empêche les technologies d&rsquo;assistance d&rsquo;annoncer un changement avant qu&rsquo;une mise à jour ne soit complétée.</p>
<pre><code class="language-markup">&lt;ul aria-atomic="true"
aria-busy="true"
aria-live="polite"&gt;</code></pre>
<h3>La propriété <code>aria-channel</code></h3>
<p><code>aria-channel</code> est une propriété optionnelle des Live Regions pouvant prendre comme valeur <code>main</code> (par défaut si la propriété n&rsquo;est pas définie) ou <code>notify</code>. Les canaux (channels) ont trait au matériel disponible sur le système de l&rsquo;utilisateur, comme un synthétiseur vocal ou une <a href="http://fr.wikipedia.org/wiki/Plage_braille">plage Braille</a> (ndt: lien ajouté). Si un seul canal est disponible, <code>main</code> et <code>notify</code> utiliseront tous deux le même canal. Le canal <code>notify</code> a une priorité plus élevée que le canal <code>main</code>.</p>
<pre><code class="language-markup">&lt;ul aria-atomic="true"
aria-channel="notify"
aria-live="polite"&gt;</code></pre>
<h3>La propriété <code>aria-relevant</code></h3>
<p><code>aria-revelant</code> est une propriété optionnelle des Live Regions indiquant quels types de changements sont considérés comme significatifs à l&rsquo;intérieur d&rsquo;une zone (ajout d&rsquo;un élément, suppression d&rsquo;un élément et modification de texte). Cette propriété accepte une ou plusieurs des valeurs suivantes, séparées par des espaces&nbsp;:</p>
<dl>
<dt><code>additions</code></dt>
<dd>Des noeuds sont ajoutés au DOM à l&rsquo;intérieur de la zone.</dd>
<dt><code>removals</code></dt>
<dd>Des noeuds sont supprimés du DOM à l&rsquo;intérieur de la zone.</dd>
<dt><code>text</code></dt>
<dd>Du texte est ajouté ou supprimé du DOM (modification de texte).</dd>
<dt><code>all</code></dt>
<dd>Toutes les valeurs définies précédemment (additions, removals, text) s&rsquo;appliquent à la zone.</dd>
</dl>
<p>En l&rsquo;absence de la propriété <code>aria-revelant</code>, le comportement par défaut considère que les modifications significatives sont les modifications de texte et les ajouts de noeuds (<code>aria-revelant="text additions"</code>). L&rsquo;exemple suivant n&rsquo;annoncera des changements que si des noeuds sont ajoutés à la région. Si des modifications de texte surviennent ou que des noeuds sont supprimés, l&rsquo;utilisateur n&rsquo;en sera pas averti.</p>
<pre><code class="language-markup">&lt;ul aria-relevant="additions"
aria-atomic="true"
aria-live="polite"&gt;</code></pre>
<h2>Quand pourrons nous utiliser ARIA&nbsp;?</h2>
<p>L&rsquo;utilisation d&rsquo;ARIA ne présente aucun inconvénient, vous pouvez l&rsquo;utiliser dès à présent. Les quatre principaux navigateurs du marché ont commencé ou prévoient de supporter ARIA. Opera 9.5 et Firefox 1.5+ disposent déjà d&rsquo;un support ARIA. Internet Explorer 8 beta supporte ARIA, et l&rsquo;équipe de développement de Webkit, le moteur libre utilisé par Safari (ndt: et Google Chrome), a annoncé que l&rsquo;intégration d&rsquo;ARIA avait commencé.</p>
<p>ARIA est également en train d&rsquo;être largement adopté par les technologies d&rsquo;assistance. JAWS 7.1+, Window-Eyes 5.5+, NVDA, Zoomtext 9+, et d&rsquo;autres offrent déjà un support basique d&rsquo;ARIA, et ce n&rsquo;est qu&rsquo;un début.</p>
<h2>Soyez parmi les premiers à l&rsquo;utiliser</h2>
<p>Puisque nous venons de voir que l&rsquo;utilisation d&rsquo;ARIA ne provoque aucun effet de bord et que le support est déjà présent, il n&rsquo;y a rien à perdre à l&rsquo;utiliser dès maintenant, et beaucoup à gagner. Même si votre site web est le plus simple du monde, vous pouvez y inclure des document landmarks (rôles des sections) pour aider l&rsquo;utilisateur à mieux naviguer et à s&rsquo;orienter à l&rsquo;intérieur du contenu.</p>
<h3>Utilisez les rôles de section (document landmark roles)</h3>
<p>Sur mon site web personnel, j&rsquo;ai utilisé les rôles de zones <code>main</code>, <code>navigation</code>, <code>search</code>, et <code>secondary</code>. Prenons la structure suivante.</p>
<pre><code class="language-markup">&lt;div id="ads"&gt;
...
&lt;/div&gt;
&lt;div id="nav"&gt;
&lt;form id="searchform" ...&gt;
...
&lt;/form&gt;
...
&lt;/div&gt;
&lt;div id="content"&gt;
...
&lt;/div&gt;</code></pre>
<p>Nous pourrions écrire l&rsquo;attribut <code>role</code> pour nos document landmarks directement dans le code HTML&nbsp;:</p>
<pre><code class="language-markup">&lt;div id="ads" role="banner"&gt;
...
&lt;/div&gt;
&lt;div id="nav" role="navigation"&gt;
&lt;form id="searchform" role="search" ...&gt;
...
&lt;/form&gt;
...
&lt;/div&gt;
&lt;div id="content" role="main"&gt;
...
&lt;/div&gt;</code></pre>
<p>Alternativement, puisque les pages sont structurées de manière à pouvoir être stylées avec CSS, la page a des chances d&rsquo;être structurée à l&rsquo;aide d&rsquo;attributs id pouvant être passés à une fonction Javascript. L&rsquo;exemple suivant est une fonction Javascript simple acceptant l&rsquo;attribut <code>id</code> d&rsquo;un élément et une valeur de <code>role</code>, lui permettant de définir l&rsquo;attribut <code>role</code> de l&rsquo;élément correspondant.</p>
<pre><code class="language-javascript">function addARIARole(strID, strRole)
{
// Find the element to add a role property to
var objElement = document.getElementById(strID);

if (objElement)
{
// Add the role property to the element
objElement.setAttribute('role', strRole);
}
}</code></pre>
<p>La fonction peut alors être appelée en passant en paramètre l&rsquo;attribut <code>id</code> de la section et son rôle dans le document. Considérez la structure de document ci-dessous&nbsp;: nous pourrions utiliser cette fonction Javascript pour insérer un attribut <code>role</code>, plutôt que de l&rsquo;écrire dans le code HTML.</p>
<pre><code class="language-javascript">function setupARIA()
{
// Add ARIA roles to the document
addARIARole('content', 'main');
addARIARole('nav', 'navigation');
addARIARole('searchform', 'search');
addARIARole('ads', 'banner');
}

window.onload = setupARIA;</code></pre>
<h3>Indiquer les champs requis</h3>
<p>Si certains de vos formulaires contiennent des champs requis, vous pouvez utiliser la propriété <code>aria-required</code>. Cette propriété indique qu&rsquo;une entrée utilisateur est requise pour envoyer le formulaire. L&rsquo;exemple suivant ajoute la propriété <code>aria-required</code> à un élément <code>input</code> classique.</p>
<pre><code class="language-markup">&lt;label for="contactname"&gt;Name&lt;/label&gt;
&lt;input type="text"
id="contactname"
name="contactname"
size="30"
aria-required="true"&gt;</code></pre>
<p>Le système de blog WordPress a déjà commencé à utiliser l&rsquo;attribut <code>aria-required</code> pour les champs requis du formulaire d&rsquo;envoi de commentaire.</p>
<h3>Ajouter d&rsquo;autres propriétés pertinentes</h3>
<p>Beaucoup de propriétés ARIA peuvent être utilisées sur des sites web très simples, comme <code>aria-labelledby</code> et <code>aria-describedby</code>. La propriété <code>aria-labelledby</code> pointe sur un ou plusieurs éléments considérés comme le libellé de l&rsquo;élément, tandis que l&rsquo;attribut <code>aria-describedby</code> pointe sur un ou plusieurs éléments considérés comme la description de l&rsquo;élément.</p>
<pre><code class="language-markup">&lt;h2 id="limg"&gt;Paragliding&lt;/h2&gt;
&lt;p id="dimg"&gt;
A long description of our paragliding trip ...
&lt;/p&gt;

&lt;div&gt;
&lt;img src="takeoff.png"
alt="Getting ready to take off"
aria-labelledby="limg"
aria-describedby="dimg"&gt;
&lt;/div&gt;</code></pre>
<h3>Priorité des attributs HTML</h3>
<p>Les attributs ARIA ont la priorité sur le code HTML de base. C&rsquo;est à dire que si <code>aria-labelledby</code> est utilisé parallèlement à <code>&lt;label for=""&gt;</code>, seul l&rsquo;attribut <code>aria-labelledby</code> sera pris en compte. L&rsquo;élément <code>label</code> est toujours encouragé pour les anciens navigateurs ne supportant pas ARIA. Une technique simple pour éviter les conflits est d&rsquo;utiliser l&rsquo;attribut <code>aria-labelledby</code> pour faire référence à l&rsquo;élément<br />
<code>label</code>, ce qui permet d&rsquo;être sûr que le libellé est lisible, quel que soit le support d&rsquo;ARIA.</p>
<pre><code class="language-markup">&lt;label id="lblef" for="effectiveness"&gt;Effectiveness&lt;/label&gt;

&lt;input type="image"
role="slider"
id="effectiveness"
aria-labelledby="lblef"
...&gt;</code></pre>
<p>Parcourez la <a href="http://www.w3.org/TR/wai-aria/#supported">liste complète des états et propriétés</a> pour en apprendre plus sur la manière dont ARIA peut vous aider à rendre votre contenu plus accessible.</p>
<h2>Ensemble, maintenant</h2>
<p>HTML n&rsquo;a pas été conçu dans le but de créer des applications web, mais les développeurs les ont créées en dessinant leurs propres widgets, et en leur ajoutant des comportements avec Javascript. Le problème est que le rôle, l&rsquo;état et les propriétés des widgets et du contenu mis à jour sur ces pages n&rsquo;est pas correctement transmis aux technologies d&rsquo;assistance. La spécification ARIA résoud ce problème en permettant aux développeurs de décrire précisément leurs éléments d&rsquo;interface, leur structure de document, et les zones de la page qui seront modifiées.<br />
Que vous développiez une application web complète avec de nombreux wigets et mises à jour dynamiques, ou le plus simple des sites web, vous pouvez commencer à utiliser ARIA dès maintenant pour vos utilisateurs handicapés.</p>
<h2>Pour en savoir plus</h2>
<ul>
<li><a href="http://www.w3.org/TR/wai-aria-practices/">Bonnes pratiques WAI-ARIA</a></li>
<li><a href="http://www.marcozehe.de/2008/02/29/easy-aria-tip-1-using-aria-required/">Utiliser <code>aria-required</code></a></li>
<li><a href="http://www.marcozehe.de/2008/03/23/easy-aria-tip-2-aria-labelledby-and-aria-describedby/">Utiliser <code>aria-labelledby</code> et <code>aria-describedby</code></a></li>
<li><a href="http://www.marcozehe.de/2008/07/16/easy-aria-tip-3-aria-invalid-and-role-alert/">Utiliser <code>aria-invalid</code> et <code>role</code> <code>alert</code></a></li>
<li><a href="http://www.paciellogroup.com/blog/?p=53">Exemple de case à cocher à trois états<br />
</a></li>
<li><a href="http://www.paciellogroup.com/blog/?p=68">Un exemple de bouton glissant (slider) avec ARIA</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>/2008/12/09/introduction-a-wai-aria-traduction/feed/</wfw:commentRss>
			<slash:comments>17</slash:comments>
		
		
			</item>
		<item>
		<title>Accessibilité VS référencement : quelles méthodes pour (ré-)concilier les deux ?</title>
		<link>/2008/11/27/accessibilite-vs-referencement-quelles-methodes-pour-re-concilier-les-deux/</link>
					<comments>/2008/11/27/accessibilite-vs-referencement-quelles-methodes-pour-re-concilier-les-deux/#comments</comments>
		
		<dc:creator><![CDATA[Eric Le Bihan]]></dc:creator>
		<pubDate>Thu, 27 Nov 2008 14:40:21 +0000</pubDate>
				<category><![CDATA[Référencement]]></category>
		<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">/?p=357</guid>

					<description><![CDATA[Après avoir lu sur de nombreux sites traitant de la question du référencement des pages web par les moteurs de recherches que le javascript était néfaste au référencement dans la mesure où les robots ne peuvent lire le contenu pertinent qui serait généré par javascript, ce langage serait-il devenu l’arme ultime des référenceurs, dans une utilisation à contrario ?
Alors que les intégrateurs, développeurs, webmasters et au sens le plus large, les créateurs de sites web échangent sur la meilleure façon d’utiliser javascript pour maintenir un site accessible, les professionnels du référencement n’hésitent pas à conseiller à leurs clients de&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Après avoir lu sur de nombreux sites traitant de la question du référencement des pages web par les moteurs de recherches que le javascript était néfaste au référencement dans la mesure où les robots ne peuvent lire le contenu pertinent qui serait généré par javascript, ce langage serait-il devenu l’arme ultime des référenceurs, dans une utilisation à contrario ?</p>
<p>Alors que les intégrateurs, développeurs, webmasters et au sens le plus large, les créateurs de sites web échangent sur la meilleure façon d’utiliser javascript pour maintenir un site accessible, les professionnels du référencement n’hésitent pas à conseiller à leurs clients de <em>faire des liens en javascript</em> ou à générer des parties de leur code html via javascript de manière à ne pas référencer certaines pages ou certaines parties de leur contenu dans le but de favoriser des pages au profit d&rsquo;autres. Les robots n’étant pas  à l’heure actuelle en mesure de comprendre et donc d’interpréter le javascript, les liens JS ne seront pas suivis et le contenu généré ne sera pas pris en compte. J&rsquo;ai également lu dernièrement que les robots seraient (je mets cette information au conditionnel) en mesure de décrypter les url dans le code javascript et donc de suivre ces liens comme des liens html, ce qui oblige actuellement les référenceurs à adopter des méthodes de cryptages &#8211; dans la limite de ce qu&rsquo;il est possible de faire en javascript &#8211; pour leurs url !</p>
<p>Cette pratique loin d’être confidentielle se répand comme une traînée de poudre sur les sites de e-commerce français où les liens <code class="prettyprint">&lt;a href="link"&gt;</code> sont remplacés par des  <code class="prettyprint">&lt;span onclick="fonction()"&gt;</code>. (L’exemple le plus flagrant en est donné sur la page d&rsquo;accueil du site de vente en ligne <em>rueducommerce.fr</em> sur laquelle pratiquement aucun lien de type <code class="prettyprint">&lt;a href="link"&gt;</code> n’est présent.)</p>
<p>Pour bien comprendre ce que ça implique, il faut d’une part rappeler que cette pratique va totalement à l’encontre des règles d’accessibilité les plus élémentaires :</p>
<p>En effet toute personne ayant javascript désactivé pour une raison ou pour une autre ne pourra pas afficher la page liée. Les personnes ayant javascript activé ne pourront pas utiliser le clic milieu de leur souris ou l’option <em>ouvrir un nouvel onglet</em> de leur menu contextuel. Ce procédé restreint donc les possibilités de l’utilisateur qu’il ait ou pas javascript activé dans son navigateur. Il est important de rappeler que la conception de pages avec le langage html répond à des normes : <em>les standards du web</em>, dont les recommandations sont rédigés par le W3C, organisme qui supervise le développement des standards du web, et pour que ces pages puissent fonctionner de façon satisfaisante dans les principaux navigateurs du marché, ces recommandations ou règles doivent être suivies. Il est également important de rappeler que de nombreuses applications et extensions, notamment celles de Firefox sont basées sur ce socle commun qu&rsquo;il est primordial de respecter, faute de quoi l&rsquo;utilisateur s&rsquo;en trouve obligatoirement lésé.</p>
<p>Lisons ce qu’il est dit dans la documentation du groupe <abbr title="Web Accessibility Initiative">WAI</abbr> du W3C, référence majeure pour l’accessibilité des sites web :</p>
<p><strong><abbr title="Web Content Accessibility Guideline">WCAG</abbr> 1.0  (version par lagrange.net)</strong></p>
<blockquote cite="http://www.la-grange.net/w3c/wcag1/wai-pageauth.html#gl-new-technologies"><p>Guideline 6. S’assurer que les pages qui contiennent de nouvelles technologies se transforment de façon élégante.</p>
<p>6.3 S&rsquo;assurer que les pages soient visibles lorsque les scripts, les applets ou autres artefacts programmables sont désactivés ou non supportés. Lorsque ce n&rsquo;est pas possible, fournissez une information équivalente sur une page alternative. [Priorité 1]<br />
Par exemple, assurez vous que les liens qui activent les scripts fonctionnent même lorsque ces derniers sont désactivés ou non supportés (par ex. Il ne faut pas utiliser « javascript: » comme cible des liens).</p></blockquote>
<p><strong>W3C : Techniques pour les règles d&rsquo;accessibilité du contenu Web 1.0 (version par lagrange.net)</strong></p>
<blockquote cite="http://www.la-grange.net/w3c/WAI-WEBCONTENT-TECHS/#scripts"><p>4.12.1 Scripts de transformation</p>
<p>Les développeurs de contenu doivent s&rsquo;assurer que les pages sont accessibles avec les scripts désactivés ou dans des navigateurs qui ne supportent pas les scripts.</p>
<p>* Eviter la création de contenu à la volée par le client. Si un navigateur d&rsquo;utilisateur ne gère pas les scripts, aucun contenu ne sera généré ou affiché. Cependant, Ceci est différent lorsqu&rsquo;il s&rsquo;agit d&rsquo;afficher ou de cacher un contenu déjà existant en utilisant une combinaison de feuilles de style et de scripting ; S&rsquo;il n&rsquo;y a pas de scripts, le contenu sera tout de même affiché. Cela ne s&rsquo;applique pas aux pages générées à la volée par le serveur et distribuées au client.<br />
* Eviter la création de liens qui utilisent « javascript » pour l&rsquo;URI. Si un utilisateur n&rsquo;utilise pas les scripts, il sera alors incapable d&rsquo;utiliser le lien car le navigateur ne pourra créé le lien.</p></blockquote>
<p>Que recommande Google à ce sujet ?</p>
<p><strong>Google (Centre d’aide Webmasters/propriétaires de sites web)</strong></p>
<blockquote><p>Si votre site contient du texte ou des liens cachés, il risque d&rsquo;être considéré comme peu fiable, car il présente aux moteurs de recherche un contenu différent de celui destiné aux visiteurs […]</p></blockquote>
<blockquote cite=" http://www.google.com/support/webmasters/bin/answer.py?answer=66353&amp;hl=fr"><p>[…] Si votre site contient du texte et des liens cachés conçus pour induire les moteurs de rechercher en erreur, votre site peut être retiré de l&rsquo;index Google et ne plus être affiché dans les pages de résultats de recherche. Lorsque vous évaluez votre site afin de vérifier s&rsquo;il contient du texte ou des liens cachés, recherchez tout ce qui n&rsquo;est pas facilement affichable par les visiteurs. Existe-t-il du texte ou des liens accessibles uniquement aux moteurs de recherche et non aux visiteurs ? […]</p></blockquote>
<blockquote cite="http://www.google.com/support/webmasters/bin/answer.py?answer=66355&amp;ctx=sibling"><p>[…] Lorsque Googlebot indexe une page contenant un script JavaScript, il ne peut pas suivre ou indexer les liens cachés dans le script lui-même. L&rsquo;utilisation d&rsquo;un script JavaScript est une pratique Web totalement légitime. Toutefois, son utilisation dans le but de tromper les moteurs de recherche ne l&rsquo;est pas. […]</p></blockquote>
<p>Pour résumer, il n’est pas interdit d’utiliser des liens javascript dans la mesure où la page présentée aux moteurs de recherche est la même que celle présentée aux utilisateurs. Ce qui n’est pas le cas dans la mesure où les robots ne pouvant lire javascript considèrent que les liens n’existent pas et ne référencent pas la page liée…</p>
<p>Devons-nous considérer que puisque le nombre des visiteurs sans javascript est faible, il n’est plus utile de se préoccuper de faire du javascript non-intrusif ? Comment se maintenir dans un secteur où toutes les méthodes même les plus contestables sont utilisées pour maintenir un taux de visites important sur son site ? Est-il possible de rester concurrentiel en utilisant les bonnes pratiques et en maintenant un site accessible, sans pour autant négliger la partie référencement ?</p>
<p>Pour continuer la réflexion quelques liens utiles :</p>
<ul>
<li><a href="http://www.google.com/support/webmasters/bin/answer.py?hl=fr&amp;answer=35769">Support Google : Conseils aux webmasters</a></li>
<li><a href="http://www.pompage.net/pompe/accesibilitemoteursderecherche/">Vous aimez l’accessibilité ? Les moteurs de recherche aussi !</a></li>
<li><a href="http://www.wizishop.com/blog/les-dossiers-du-e-commerce/accessibilite-et-e-commerce-interets.html">Accessibilité et e-commerce : Pourquoi rendre son site accessible ?</a></li>
<li><a href="http://webyboom.canalblog.com/archives/2008/08/28/10378459.html">Target condamné pour l&rsquo;inaccessibilité de son site aux non-voyants</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>/2008/11/27/accessibilite-vs-referencement-quelles-methodes-pour-re-concilier-les-deux/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>jQuery : l’événement !</title>
		<link>/2008/09/16/jquery-l-evenement/</link>
					<comments>/2008/09/16/jquery-l-evenement/#comments</comments>
		
		<dc:creator><![CDATA[Pierre Bertet]]></dc:creator>
		<pubDate>Mon, 15 Sep 2008 23:23:32 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<guid isPermaLink="false">/?p=63</guid>

					<description><![CDATA[Enfin « les », événements. Je voulais un titre sensationnel.
Vous connaissez certainement jQuery, l&#8217;excellente bibliothèque Javascript. Non ? Alors c&#8217;est ici.
Le développement DOM/Javascript repose en grande partie sur les événements. Vous savez certainement qu&#8217;il est possible d&#8217;affecter un événement à un objet jQuery, c&#8217;est à dire qu&#8217;une fonction se déclenchera lors d&#8217;un événement sur l&#8217;objet sélectionné.
jQuery propose deux manières de définir les événements : nous allons les analyser.
Les « Event Helpers »
Joli nom. Pas très causant, mais sympa comme tout.
Il s&#8217;agit d&#8217;une série de méthodes, reprenant le nom des événements DOM. Elles prennent comme&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Enfin « les », événements. Je voulais un titre sensationnel.</p>
<p>Vous connaissez certainement <a href="http://jquery.com/">jQuery</a>, l&rsquo;excellente bibliothèque Javascript. Non ? Alors <a href="/category/jquery/">c&rsquo;est ici</a>.</p>
<p>Le développement DOM/Javascript repose en grande partie sur les événements. Vous savez certainement qu&rsquo;il est possible d&rsquo;affecter un événement à un objet jQuery, c&rsquo;est à dire qu&rsquo;une fonction se déclenchera lors d&rsquo;un événement sur l&rsquo;objet sélectionné.</p>
<p>jQuery propose deux manières de définir les événements : nous allons les analyser.</p>
<h3>Les « Event Helpers »</h3>
<p>Joli nom. Pas très causant, mais sympa comme tout.</p>
<p>Il s&rsquo;agit d&rsquo;une série de méthodes, reprenant le nom des événements DOM. Elles prennent comme unique paramètre une fonction, et leur nom correspond à celui de l&rsquo;événement DOM, allégé de son préfixe « <strong>on</strong> » (onclick, onmouseout, etc. ).</p>
<p>Si aucun paramètre n&rsquo;est passé, cette méthode <strong>déclenche</strong> l&rsquo;événement.</p>
<p>Si une fonction est passée en paramètre, elle s&rsquo;exécutera lorsque l&rsquo;événement sera déclenché (depuis le code comme vu juste au-dessus, ou « naturellement »).</p>
<p>Vous trouverez la liste complète de ces méthodes sur la page de documentation des événements : <a href="http://docs.jquery.com/Events">http://docs.jquery.com/Events</a>.</p>
<h4>Définir un événement</h4>
<p>Commençons par un exemple. Tout le monde aime les exemples !</p>
<p>L&rsquo;événement <code class="prettyprint">onclick</code> peut être défini sur un objet jQuery à l&rsquo;aide de la méthode <code class="prettyprint">click()</code> à laquelle est passée une fonction :</p>
<pre><code class="language-javascript">$("a#test1").click(function(){
  window.alert("Clic sur a#test1.");
});
</code></pre>
<p>La fonction passée en paramètre peut attendre un paramètre. Il représente l&rsquo;objet événement, et possède plusieurs propriétés et méthodes. J&rsquo;ai l&rsquo;habitude d&rsquo;utiliser une variable nommée « e » (event), mais on peut évidemment utiliser un autre nom.</p>
<p>La méthode preventDefault() de cet objet permet d&#8217;empêcher le navigateur de déclencher son comportement par défaut.<br />
Sur un lien, cette méthode empêchera simplement le navigateur de le suivre.</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">$("a#test1").click(function(e){
  e.preventDefault(); // Empêche le navigateur de suivre le lien.
  window.alert("Clic sur a#test1.");
});
</code></pre>
<p>Démonstration : <a id="test1" href="http://www.example.com/">a#test1</a></p>
<p><script type="text/javascript"><!--
jQuery("a#test1").click(function(e){
e.preventDefault();
window.alert("Clic sur a#test1.");
});
// --></script></p>
<h4>Déclencher un événement depuis le code</h4>
<p>Il est parfois utile de déclencher un événement depuis le code. Pour cela, les mêmes méthodes seront appelées, mais cette fois sans paramètre.</p>
<p>Un exemple. « 例 », dirait un japonais, mais vous n&rsquo;êtes pas obligé de me croire.</p>
<p>Nous allons réutiliser l&rsquo;événement précédemment défini dans le premier exemple, en le déclenchant depuis le code.</p>
<p>Lorsque le lien du second exemple ( « a#test2 » ) sera cliqué, un clic sera déclenché sur le lien du premier exemple ( « a#test1 » ).</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">$("a#test2").click(function(e){
  e.preventDefault();
  window.alert("Clic sur a#test2, déclenchement du clic sur a#test1...");
  $("a#test1").click();
});
</code></pre>
<p>Démonstration : <a id="test2" href="http://www.example.com/">a#test2</a></p>
<p><script type="text/javascript"><!--
jQuery("a#test2").click(function(e){
e.preventDefault();
window.alert("Clic sur a#test2, déclenchement du clic sur a#test1...");
jQuery("a#test1").click();
});
// --></script></p>
<h4>La méthode ready()</h4>
<p>Vous avez certainement déjà utilisé la méthode <code class="language-javascript">ready()</code> d&rsquo;un objet jQuery contenant l&rsquo;objet DOM <code class="language-javascript">document</code>.</p>
<p>Si un script est défini et exécuté dans la partie <code class="language-javascript">&lt;head&gt;</code> d&rsquo;une page et qu&rsquo;il essaie de manipuler des éléments, le navigateur se comportera comme s&rsquo;ils n&rsquo;existaient pas.</p>
<p>Le script est exécuté au moment où il est lu par le navigateur (<a href="http://www.la-grange.net/w3c/html4.01/interact/scripts.html#adef-defer">sauf avec l&rsquo;attribut defer</a>). Puisque la suite du document n&rsquo;a pas encore été chargée, le navigateur n&rsquo;a pas connaissance de ces éléments.</p>
<p>Pour remédier à cela, il est possible d&rsquo;attacher un événement <code class="language-javascript">onload</code> sur l&rsquo;objet <code class="language-javascript">window</code>, qui sera déclenché lorsque la page <strong>et tous ses éléments</strong> seront chargés.</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">$(window).load(function(){
  // Le code placé ici sera déclenché
  // au chargement complet de la page.
});
</code></pre>
<p>Il s&rsquo;agit de l&rsquo;équivalent jQuery du célèbre <code class="language-javascript">window.onload = function(){}</code>. Évidemment, si un élément appelé sur votre page met un certain temps à répondre (une image hébergée ailleurs, ou votre outil d&rsquo;analyse de statistiques basé sur un script externe), un long moment peut s&rsquo;écouler avant que votre script ne soit exécuté.</p>
<p>C&rsquo;est pourquoi la méthode <code class="language-javascript">ready()</code> de l&rsquo;élément <code class="language-javascript">document</code> a été créée : la fonction affectée à cet événement sera déclenchée dès que le document HTML <strong>et les CSS</strong> seront chargés.</p>
<p>Le mécanisme de cet événement jQuery est plutôt intéressant. Il ne s&rsquo;agit pas d&rsquo;un événement natif DOM, ou pas tout à fait : Mozilla Firefox, Opera et les dernières versions de <a rel="external" href="http://webkit.org/">Webkit</a> déclenchent bien un événement DOMContentLoaded lorsque le document HTML est chargé, mais <a rel="external" href="http://my.opera.com/nicomen/blog/2007/07/08/domcontentloaded-gotcha-with-external-stylesheets">Opera n&rsquo;attend pas que les styles soient chargés</a> pour le déclencher. On ne peut pas vraiment lui donner tort, puisque sur le brouillon de la spécification HTML5 <a rel="external" href="http://www.whatwg.org/specs/web-apps/current-work/#the-end">rien n&rsquo;est précisé à propos du chargement des styles</a>.</p>
<p>jQuery résout ce problème sur Opera en attendant que chaque feuille de style soit disponible. Pour cela, la propriété <code class="language-javascript">disabled</code> de chacun des objets contenus dans <code class="language-javascript">document.styleSheets</code> (chaque fichier CSS) est testée jusqu&rsquo;à ce qu&rsquo;elle renvoie <code class="language-javascript">false</code>, c&rsquo;est à dire lorsque la CSS est chargée.</p>
<p>Pour Internet Explorer, <a href="http://javascript.nwbox.com/IEContentLoaded/">l&rsquo;astuce consiste à tester la méthode <code class="language-javascript">document.documentElement.doScroll("left");</code></a> jusqu&rsquo;à ce qu&rsquo;elle ne retourne plus d&rsquo;erreur. Dès que c&rsquo;est le cas, cela signifie que les styles sont chargés.</p>
<p>Pour Webkit, c&rsquo;est la propriété <code class="language-javascript">document.readyState</code> qui est testée, puis un test similaire à celui utilisé pour Opera se charge de vérifier le chargement complet des CSS.</p>
<p>Certains navigateurs supportent l&rsquo;événement <code class="language-javascript">document.DOMContentLoaded</code> (Mozilla Firefox), c&rsquo;est donc ce dernier qui est utilisé.</p>
<p>Pour les navigateurs ne supportant pas <code class="language-javascript">document.DOMContentLoaded</code> et n&rsquo;entrant pas dans les cas particuliers traités par jQuery (Opera, Webkit, Internet Explorer), c&rsquo;est un simple événement <code class="language-javascript">window.onload qui est utilisé</code>.</p>
<p>Voilà, vous oubliez ça, jQuery le fait pour vous :</p>
<pre><code class="language-javascript">function bindReady(){
	if ( readyBound ) return;
	readyBound = true;

	// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
	if ( document.addEventListener &amp;&amp; !jQuery.browser.opera)
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );

	// If IE is used and is not in a frame
	// Continually check to see if the document is ready
	if ( jQuery.browser.msie &amp;&amp; window == top ) (function(){
		if (jQuery.isReady) return;
		try {
			// If IE is used, use the trick by Diego Perini
			// http://javascript.nwbox.com/IEContentLoaded/
			document.documentElement.doScroll("left");
		} catch( error ) {
			setTimeout( arguments.callee, 0 );
			return;
		}
		// and execute any waiting functions
		jQuery.ready();
	})();

	if ( jQuery.browser.opera )
		document.addEventListener( "DOMContentLoaded", function () {
			if (jQuery.isReady) return;
			for (var i = 0; i &lt; document.styleSheets.length; i++)
				if (document.styleSheets[i].disabled) {
					setTimeout( arguments.callee, 0 );
					return;
				}
			// and execute any waiting functions
			jQuery.ready();
		}, false);

	if ( jQuery.browser.safari ) {
		var numStyles;
		(function(){
			if (jQuery.isReady) return;
			if ( document.readyState != "loaded" &amp;&amp; document.readyState != "complete" ) {
				setTimeout( arguments.callee, 0 );
				return;
			}
			if ( numStyles === undefined )
				numStyles = jQuery("style, link[rel=stylesheet]").length;
			if ( document.styleSheets.length != numStyles ) {
				setTimeout( arguments.callee, 0 );
				return;
			}
			// and execute any waiting functions
			jQuery.ready();
		})();
	}

	// A fallback to window.onload, that will always work
	jQuery.event.add( window, "load", jQuery.ready );
}
</code></pre>
<p>Vous l&rsquo;aurez compris, il s&rsquo;agit d&rsquo;un extrait du code de jQuery.</p>
<p>Il existe deux autres « Event Helpers » particuliers, appelés « Interaction Helpers ». Les deux fonctionnent de la même manière, à la différence qu&rsquo;ils attendent deux fonctions en paramètre plutôt qu&rsquo;une.</p>
<p>La méthode <strong><code class="language-javascript">hover()</code></strong> permet de spécifier deux événements, pour l&rsquo;entrée et la sortie du curseur souris dans la zone que couvre le ou les éléments de notre objet jQuery. <a href="/wp-content/uploads/2007/08/superman.jpg">Mon vieil ami Superman</a> appelle ce comportement le « survol ».</p>
<p>Ils ne sont pas tout à fait équivalents aux événements <code class="language-javascript">onmouseover</code> et <code class="language-javascript">onmouseout</code>, existant nativement en DOM.<br />
En utilisant ces derniers, lorsque le curseur se déplace d&rsquo;un élément à un autre au sein de l&rsquo;élément sur lequel est attaché l&rsquo;événement (par exemple lorsqu&rsquo;il passe sur une image se trouvant à l&rsquo;intérieur d&rsquo;un élément &lt;div&gt;), <code class="language-javascript">onmouseover</code> sera déclenché sur l&rsquo;image (sur laquelle aucun événement n&rsquo;est défini), et « remontera » jusqu&rsquo;à son conteneur, pour déclencher une seconde fois l&rsquo;événement. La cible de l&rsquo;événement va également changer, ce sera l&rsquo;image et non le conteneur.<br />
En sortant le curseur de l&rsquo;image, même problème : c&rsquo;est cette fois l&rsquo;événement onmouseout qui sera déclenché sur le conteneur, mais avec l&rsquo;image pour cible.</p>
<p>Pour en savoir plus, c&rsquo;est ici : http://www.quirksmode.org/js/events_mouse.html</p>
<p>Si nous ne voulons pas de ce comportement, il faut vérifier que l&rsquo;élément survolé au déclenchement de l&rsquo;événement corresponde bien à l&rsquo;élément sur lequel l&rsquo;événement a été défini. C&rsquo;est fastidieux. jQuery s&rsquo;en charge automatiquement lorsque vous utilisez <code class="language-javascript">hover()</code>.</p>
<p>La seconde méthode est <strong><code class="language-javascript">toggle()</code></strong>. Elle est équivalente à la méthode <code class="language-javascript">click()</code>, mais la deuxième fonction passée sera déclenchée une fois sur deux à la place de la première, ce qui est très intéressant, par exemple pour faire apparaître et disparaître en alternance un élément à chaque clic sur un bouton. Vous pouvez également passer plus de deux fonctions, elles seront alors exécutées les unes à la suite des autres, à chaque clic.</p>
<h3>Les méthodes bind et trigger (affecter et déclencher)</h3>
<h4>La méthode bind()</h4>
<p>Vous pouvez utiliser la méthode <code class="language-javascript">bind()</code> pour affecter un <strong>ou plusieurs</strong> événements à un objet jQuery. Voici une première différence avec les « Event Helpers » vus au-dessus. Le premier paramètre doit être une chaîne de caractère, représentant les événements (séparés par des espaces) sur lesquels sera exécutée la fonction passée en deuxième paramètre. Allez !</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">$("a#test3").bind("mouseover mouseout", function(e){
  $(this).text( "-- " + $(this).text() + " --" );
});
</code></pre>
<p>Démonstration : <a id="test3" href="http://www.example.com/">a#test3</a></p>
<p><script type="text/javascript"><!--
jQuery("a#test3").bind("mouseover mouseout", function(e){
jQuery(this).text( "-- " + jQuery(this).text() + " --");
});
// --></script></p>
<p>Deux événements « spéciaux » sont disponibles avec la méthode <code class="language-javascript">bind()</code> : <code class="language-javascript">mouseenter</code> et <code class="language-javascript">mouseleave</code>.<br />
Ils correspondent à l&rsquo;entrée la sortie du curseur sur un élément, sans déclencher l&rsquo;événement lorsqu&rsquo;un élément enfant est survolé. Ces événements correspondent à ceux définis par la méthode <code class="language-javascript">hover()</code>.</p>
<h4>La méthode trigger()</h4>
<p>Comme pour les « Event Helpers », il est possible de déclencher depuis le code un événement défini sur un élément. La méthode <code class="language-javascript">trigger()</code> sera utilisée.</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">$("a#test4").bind("click", function(e){
  e.preventDefault();
  jQuery("a#test3").trigger("mouseover");
});
</code></pre>
<p>Démonstration : <a id="test4" href="http://www.example.com/">a#test4 : un clic sur ce lien déclenchera un survol sur l&rsquo;élément a#test3 (démonstration précédente)</a><br />
<script type="text/javascript"><!--
jQuery("a#test4").bind("click", function(e){
  e.preventDefault();
  jQuery("a#test3").trigger("mouseover");
});
// --></script></p>
<h4>Supprimer un événement avec unbind()</h4>
<p>Supprimer un événement est trivial. Il suffit d&rsquo;appeler la méthode <code class="language-javascript">unbind()</code> en lui passant en paramètre le ou les événements à supprimer. Si aucun événement n&rsquo;est passé en paramètre, <strong>tous les événements affectés à cet objet jQuery seront supprimés</strong>.</p>
<p>Vous avez également la possibilité de passer en second paramètre une référence vers une fonction en particulier, de manière à ne pas supprimer toutes les fonctions attachées à cet événement.</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">function affiche1(){
  window.alert('1');
};
function affiche2(){
  window.alert('2');
};

$("#test").bind("click", affiche1);
$("#test").bind("click", affiche2);

// Si le script s'arrêtait ici, un clic sur l'élément afficherait "1" puis "2"

$("#test").unbind("click", affiche1);

// Mais la première fonction attachée à l'événement a été supprimée en passant sa référence, seul "2" est affiché
</code></pre>
<h4>Passer des données à un événement</h4>
<p>La méthode <code class="language-javascript">trigger()</code> permet également d&rsquo;envoyer des données à la fonction déclenchée par l&rsquo;événement. On passera alors ces données en second paramètre, après le nom de l&rsquo;événement. Elles seront regroupées dans un tableau, sauf si un seul paramètre est passé : vous avez alors la possibilité de le passer directement.</p>
<pre><code class="language-javascript">$("a#test5").trigger("click", ["paramètre 1", 2, {parametre: "3"}]);</code></pre>
<p>Lors de la définition de l&rsquo;événement avec la méthode bind(), la fonction passée en paramètre devra définir ces paramètres pour pouvoir les utiliser.<br />
Tous les paramètres supplémentaires sont ajoutés après le premier, qui représente toujours l&rsquo;objet événement (« e » dans l&rsquo;exemple suivant).</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">$("a#test5").bind("click", function(e, param1, param2, param3){
  e.preventDefault();
  window.alert(param1); // Affiche "paramètre 1"
  window.alert(param2); // Affiche "2"
  window.alert(param3["parametre"]); // Affiche "3" (cet argument est un tableau associatif)
});</code></pre>
<p>Démonstration (cliquez sur le bouton) : <button id="btn-test1">Déclencher un clic sur a#test5</button>, <a id="test5" href="http://www.example.com/">a#test5</a></p>
<p><script type="text/javascript"><!--
jQuery("a#test5").bind("click", function(e, param1, param2, param3){
  e.preventDefault();
  window.alert(param1); // Affiche "paramètre 1"
  window.alert(param2); // Affiche "2"
  window.alert(param3["parametre"]); // Affiche "3" (cet argument est un tableau associatif)
});
jQuery("#btn-test1").bind("click", function(e){
  e.preventDefault();
  jQuery("a#test5").trigger("click", ["paramètre 1", 2, {parametre: "3"}]);
});
// --></script></p>
<p>Essayez maintenant de cliquer sur le lien juste au-dessus, vous verrez que les paramètres ont la valeur <code class="language-javascript">undefined</code> la boîte de dialogue déclenchée par window.alert ne s&rsquo;affiche même pas pour le troisième paramètre : le fait d&rsquo;appeler une clé inexistante (<code class="language-javascript">param3["parametre"]</code>) déclenchera une erreur Javascript.</p>
<p>Comme dit plus haut, si un seul paramètre est passé, vous pouvez l&rsquo;utiliser directement :</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">$("a#test5").trigger("click", "paramètre 1");</code></pre>
<p>Bien entendu, la fonction n&rsquo;attend qu&rsquo;un paramètre dans ce cas :</p>
<pre><code class="language-javascript">$("a#test5").bind("click", function(e, param1){
  e.preventDefault();
  window.alert(param1); // Affiche "paramètre 1"
});</code></pre>
<h4>Les événements « sur mesure »</h4>
<p>Il est possible d&rsquo;utiliser <code class="language-javascript">bind()</code> pour affecter un événement personnalisé. Cet événement ne pourra être déclenché qu&rsquo;avec la méthode <code class="language-javascript">trigger()</code>.</p>
<p>&#8211; A quoi ça sert, exactement ?<br />
&#8211; Principalement, à découper certaines parties d&rsquo;un script, liées à un objet jQuery, en événements. Mais c&rsquo;est quoi ces questions ? C&rsquo;est pour me déstabiliser, c&rsquo;est ça ?</p>
<p>Prenons un lien, auquel nous attacherons l&rsquo;événement « StyleFunky ». Lorsque cet événement sera déclenché, notre lien va naturellement s&rsquo;imposer dans le page, montrer à tous qu&rsquo;il n&rsquo;est pas le genre de lien qu&rsquo;il fait bon prendre pour une ancre. En réalité, un ensemble de propriétés CSS seront définies sur cet élément, ainsi qu&rsquo;un <code class="language-javascript">window.setInterval()</code> pour changer sa couleur de fond, mais ce sera transparent pour nous, une fois notre fonction définie. Seul l&rsquo;événement « StyleFunky » sera ensuite déclenché.</p>
<p>Nous attacherons également un autre événement à ce lien, « StyleNormal », qui annulera les effets de l&rsquo;événement précédent (y compris le <code class="language-javascript">window.setInterval</code>) :</p>
<p><strong>Exemple.</strong></p>
<pre><code class="language-javascript">$("a#test6").bind("StyleFunky", function(){
  var jElt = $(this);
  jElt
  .css({
    "display": "block",
    "padding": "20px",
    "fontSize": "300%",
    "fontWeight": "bold",
    "textAlign": "center",
    "color": "#fff",
    "background": "#f00"
  });
  jElt.data("redBackground", true);
  jElt.data("interval", window.setInterval(function(){
    if (jElt.data("redBackground")) {
      jElt.css("background", "#f0f")
    } else {
      jElt.css("background", "#f00");
    }
    jElt.data("redBackground", ! (jElt.data("redBackground")) );
  }, 500));
});
$("a#test6").bind("StyleNormal", function(e){
  var jElt = $(this);
  window.clearInterval(jElt.data("interval"));
  jElt.css({
    "display": "inline",
    "padding": "0",
    "fontSize": "100%",
    "fontWeight": "normal",
    "textAlign": "left",
    "color": "#7F89A6",
    "background": "none"
  });
});
</code></pre>
<p>Demostración (c&rsquo;est de l&rsquo;espagnol) :<br />
<button type="button" id="btn-test2">$(« a#test6 »).trigger(« StyleFunky »)</button> <button type="button" id="btn-test3">$(« a#test6 »).trigger(« StyleNormal »)</button></p>
<p><a id="test6" href="http://www.example.com/">a#test6</a></p>
<p><script type="text/javascript"><!--
jQuery("a#test6").bind("StyleFunky", function(e){
  var jElt = jQuery(this);
  jElt
  .css({
    "display": "block",
    "padding": "20px",
    "fontSize": "300%",
    "fontWeight": "bold",
    "textAlign": "center",
    "color": "#fff",
    "background": "#f00"
  });
  jElt.data("redBackground", true);
  jElt.data("interval", window.setInterval(function(){
    if (jElt.data("redBackground")) {
      jElt.css("background", "#f0f")
    } else {
      jElt.css("background", "#f00");
    }
    jElt.data("redBackground", ! (jElt.data("redBackground")) );
  }, 500));
});
jQuery("a#test6").bind("StyleNormal", function(e){
  var jElt = jQuery(this);
  window.clearInterval(jElt.data("interval"));
  jElt.css({
    "display": "inline",
    "padding": "0",
    "fontSize": "100%",
    "fontWeight": "normal",
    "textAlign": "left",
    "color": "#7F89A6",
    "background": "none"
  });
});
jQuery("#btn-test2").click(function(){jQuery("a#test6").trigger("StyleFunky")});
jQuery("#btn-test3").click(function(){jQuery("a#test6").trigger("StyleNormal")});
// --></script></p>
<h4>Les Namespaced Events (événements nommés)</h4>
<p>Nous avons vu qu&rsquo;il était possible avec <code class="language-javascript">unbind()</code> de supprimer une seule des fonctions attachées à un événement, mais cette méthode est peu élégante, puisqu&rsquo;elle n&rsquo;autorise pas l&rsquo;utilisation de fonctions anonymes.</p>
<p>Pour remédier à cela, jQuery permet de nommer une fonction attachée à un événement.<br />
Une notation similaire à celle des classes CSS est utilisée, accolée au nom de l&rsquo;événement (« .action1 », « .action2 » et « .action3 » ici) :</p>
<pre><code class="language-javascript">$(element).bind("click.action1", function(){ /* Action 1 */ });
$(element).bind("click.action2", function(){ /* Action 2 */ });
$(element).bind("click.action3", function(){ /* Action 3 */ });</code></pre>
<p>Il sera alors possible de déclencher un événement en particulier en ciblant une fonction événement en particulier, ou toutes les fonctions attachées, en déclenchant simplement l&rsquo;événement « click » :</p>
<pre><code class="language-javascript">$(element).trigger("click.nom1"); /* Déclenche l'action 1 */
$(element).trigger("click"); /* Déclenche les actions 1, 2 et 3 */</code></pre>
<p>Évidemment, il  sera possible de les supprimer, individuellement, ou non.</p>
<pre><code class="language-javascript">$(element).unbind("click.nom1"); /* Supprime l'action 1 */
$(element).trigger("click"); /* Déclenche les actions 2 et 3 (la 1 vient d'être supprimée, sois attentif) */</code></pre>
<h4>La méthode .triggerHandler()</h4>
<p>Pour finir, la méthode <code class="language-javascript">triggerHandler()</code> permet de déclencher les différentes fonctions attachées à un événement, sans déclencher l&rsquo;action par défaut du navigateur.</p>
<p>Prenons l&rsquo;événement <code class="language-javascript">focus</code> sur un champ texte de formulaire. Si vous lui affectez une action particulière (comme afficher une bulle d&rsquo;information), vous pourrez alors déclencher cette action sans déplacer le curseur de l&rsquo;utilisateur dans le champ :</p>
<pre><code class="language-javascript">$(input[type=text]).bind("focus", function(){ /* Affichage de la bulle d'information */ });
$(input[type=text]).trigger("focus"); /* Déplacement du curseur dans le champ texte, affichage de la bulle d'information */
$(input[type=text]).triggerHandler("focus"); /* Affichage de la bulle d'information seulement */</code></pre>
<p style="line-height:normal;font-size:300%"><strong>Voilà, c&rsquo;est fini.</strong></p>
]]></content:encoded>
					
					<wfw:commentRss>/2008/09/16/jquery-l-evenement/feed/</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
			</item>
		<item>
		<title>Les nouveaux navigateurs débarquent (attention ils mordent)</title>
		<link>/2008/06/12/les-nouveaux-navigateurs-debarquent-attention-ils-mordent/</link>
					<comments>/2008/06/12/les-nouveaux-navigateurs-debarquent-attention-ils-mordent/#comments</comments>
		
		<dc:creator><![CDATA[Pierre Bertet]]></dc:creator>
		<pubDate>Thu, 12 Jun 2008 12:44:25 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[Actualité]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Navigateurs]]></category>
		<guid isPermaLink="false">/?p=64</guid>

					<description><![CDATA[Opera 9.5 vient tout juste de sortir dans sa version finale, et la liste des changements est impressionnante (vous pouvez également consulter un article présentant les nouveautés aux développeurs).
La date de sortie de Firefox 3 a été fixée au 17 juin.
Safari 3.1 attend ses nouveaux camarades depuis quelques temps déjà.
Dans quelques jours, les internautes auront à disposition trois navigateurs web d&#8217;excellente qualité.
Javascript
Les performances de Javascript sont plus élevées que jamais, et c&#8217;est loin d&#8217;être fini :
Firefox 4 utilisera le moteur ECMAScript de Flash Player, Tamarin.
Le projet Webkit (le moteur de rendu utilisé par&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Opera 9.5</strong> <a href="http://my.opera.com/community/blog/2008/06/10/dear-opera-community">vient tout juste de sortir</a> dans sa version finale, et la <a href="http://www.opera.com/docs/changelogs/windows/950/">liste des changements</a> est impressionnante (vous pouvez également consulter un <a href="http://dev.opera.com/articles/view/opera-9-5-the-next-generation-of-web-s/">article présentant les nouveautés aux développeurs</a>).</p>
<p>La date de sortie de <strong>Firefox 3</strong> a été fixée au <a href="http://developer.mozilla.org/devnews/index.php/2008/06/11/coming-tuesday-june-17th-firefox-3/">17 juin</a>.</p>
<p><strong>Safari 3.1</strong> attend ses nouveaux camarades depuis quelques temps déjà.</p>
<p>Dans quelques jours, les internautes auront à disposition trois navigateurs web <em>d&rsquo;excellente qualité</em>.</p>
<h2>Javascript</h2>
<p>Les performances de Javascript sont plus élevées que jamais, et c&rsquo;est loin d&rsquo;être fini :</p>
<p>Firefox 4 utilisera le moteur ECMAScript de Flash Player, <a href="http://www.mozilla.org/projects/tamarin/">Tamarin</a>.</p>
<p>Le projet Webkit (le moteur de rendu utilisé par Safari) est lui aussi en train de passer à un nouveau moteur Javascript, <a href="http://webkit.org/blog/189/announcing-squirrelfish/">SquirrelFish</a>, qui est extrêmement rapide.</p>
<p>Le nom de code de la prochaine version du navigateur Opera est <a href="http://www.opera.com/products/desktop/next/">Peregrine</a>, « pèlerin » en français, et il n&rsquo;a pas été choisi au hasard :</p>
<blockquote><p>Le faucon pèlerin, ou Falco peregrinus (Tunstall, 1771), est un rapace robuste de taille moyenne, réputé pour être l’oiseau le plus rapide du monde. Les mesures de la vitesse lors de la phase plongeante de l&rsquo;attaque varient généralement entre 130 et 184 km/h. La vitesse maximale mesurée serait de 390 km/h.</p></blockquote>
<h2>CSS</h2>
<p>CSS 2.1 est maintenant correctement supporté dans ces trois navigateurs (Firefox 3 permet <strong>enfin</strong> d&rsquo;utiliser la propriété <code>display:inline-block</code> !), et de plus en plus de propriétés CSS 3 (qui n&rsquo;est pas une recommandation et continue d&rsquo;évoluer) sont d&rsquo;ores et déjà implémentées.</p>
<p>Évidemment, Firefox passe avec succès le <a href="http://www.webstandards.org/files/acid2/test.html">test Acid2</a>.</p>
<h2>HTML</h2>
<p>Certains éléments de la future recommandation HTML5 (encore loin d&rsquo;être finalisé) commencent réellement à être utilisables.</p>
<p>L&rsquo;élément <strong><a href="http://www.whatwg.org/specs/web-apps/current-work/#the-canvas">canvas</a></strong> est en plein explosion. Les exemples suivants utilisent cet élément et fonctionnent sur Firefox 3, Opera 9.5 et Safari 3.1 :</p>
<ul>
<li><a href="http://www.abrahamjoffe.com.au/ben/canvascape/">Canvascape</a>, une démo de moteur 3D de type « Doom-like ».</li>
<li><a href="http://blog.nihilogic.dk/2008/05/8-kilobytes-of-mario.html">Un clone de Mario Bros</a></li>
<li><a href="http://blog.nihilogic.dk/2008/05/javascript-super-mario-kart.html">Un clone de Super Mario Kart</a></li>
<li><a href="http://bomomo.com/">Bomomo</a>, une expérimentation très intéressante<a href="http://bomomo.com/"><br />
</a></li>
<li><a href="http://www.pixastic.com/">Pixastic</a>, un outil de retouche photo</li>
<li><a href="http://www.nihilogic.dk/labs/chess/">Un jeu d&rsquo;échecs en 3D</a></li>
</ul>
<p>Ce n&rsquo;est qu&rsquo;un début : <a href="http://blog.vlad1.com/2007/11/26/canvas-3d-gl-power-web-style/">l&rsquo;élément canvas3D</a> devrait permettre d&rsquo;utiliser l&rsquo;accélération 3D des cartes graphiques.</p>
<p>Le support de <strong>SVG</strong> s&rsquo;améliore encore, et il est maintenant aussi simple d&rsquo;afficher des images vectorielles que d&rsquo;afficher une image bitmap (Jpeg, PNG) dans une page. Les nouvelles versions de Safari et d&rsquo;Opera permettent d&rsquo;utiliser des images SVG dans la propriété CSS background-image.</p>
<p>Des versions expérimentales de Firefox, Opera et Safari permettent d&rsquo;utiliser l&rsquo;élément <a href="http://www.whatwg.org/specs/web-apps/current-work/#video"><strong>video</strong> défini dans HTML5</a>.</p>
<h2>Et Internet Explorer ?</h2>
<p>Il semblerait que plus personne n&rsquo;attende quoi que ce soit de ce navigateur. L&rsquo;innovation sur le web, longtemps paralysée, est enfin repartie à plein régime, laissant de côté ce navigateur.</p>
<p>Internet Explorer 6 est toujours en circulation, et la plupart des sites se doivent encore de le prendre en compte aujourd&rsquo;hui, mais on est très loin des méthodes de conception utilisées il y a quelques années : créer différentes versions d&rsquo;un site par navigateur est non seulement impossible, mais également inadapté au web d&rsquo;aujourd&rsquo;hui, standard et universel.</p>
<p>Les méthodes de travail ont changé : un site est d&rsquo;abord conçu pour les standards, puis adapté pour Internet Explorer, de manière <a href="/2008/04/08/cibler-internet-explorer-dans-une-css-oui-et-sans-hack/">plus</a> ou <a href="/2008/01/08/ie7js-v20-beta/">moins</a> élégante. Des hacks existent pour émuler SVG, l<a href="http://code.google.com/p/explorercanvas/">&lsquo;élément canvas </a>et CSS2.1. Les exigences pour ce navigateur ont été globalement revues à la baisse : l&rsquo;essentiel est que l&rsquo;internaute accède aux informations.</p>
<p>Internet Explorer 8 nous promet de belles choses, mais personne ne l&rsquo;attend plus. <a href="http://standblog.org/blog/post/2005/11/06/93114485-promouvoir-le-choix-et-l-innovation"><strong>Le choix et l&rsquo;innovation sur le web sont définitivement de retour</strong></a>, et ils s&rsquo;en passeront volontiers.</p>
<p>Comment voyez-vous l&rsquo;évolution du web dans les douze prochains mois ?</p>
]]></content:encoded>
					
					<wfw:commentRss>/2008/06/12/les-nouveaux-navigateurs-debarquent-attention-ils-mordent/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Webkit supporte document.query­Selector­All();</title>
		<link>/2008/02/10/webkit-supporte-documentqueryselectorall/</link>
		
		<dc:creator><![CDATA[Pierre Bertet]]></dc:creator>
		<pubDate>Sun, 10 Feb 2008 12:00:33 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">/2008/02/10/webkit-supporte-documentqueryselectorall/</guid>

					<description><![CDATA[Le seul moyen de sélectionner des éléments en Javascript est d&#8217;utiliser les méthodes DOM classiques : document.getElementById(), getElementsByTagName(), nexSibling(), etc.
C&#8217;est assez fastidieux, et n&#8217;incite pas vraiment les développeurs à concevoir leurs scripts de manière non-intrusive.
Voilà pourquoi plusieurs librairies Javascript ont ajouté une couche supplémentaire : il suffit de passer une chaîne de sélecteur CSS, et cette chaîne est retranscrite en méthodes DOM classique par le moteur de la librairie pour retourner un tableau d&#8217;éléments correspondant à ce sélecteur. Evidemment, toutes ces opérations ont un coût en termes de performances.
Selectors API propose de régler ce problème : il&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Le seul moyen de sélectionner des éléments en Javascript est d&rsquo;utiliser les méthodes DOM classiques : <code class="prettyprint">document.getElementById()</code>, <code class="prettyprint">getElementsByTagName()</code>, <code class="prettyprint">nexSibling()</code>, etc.</p>
<p>C&rsquo;est assez fastidieux, et n&rsquo;incite pas vraiment les développeurs à concevoir leurs scripts de manière non-intrusive.</p>
<p>Voilà pourquoi plusieurs librairies Javascript ont ajouté une couche supplémentaire : il suffit de passer une chaîne de sélecteur CSS, et cette chaîne est retranscrite en méthodes DOM classique par le moteur de la librairie pour retourner un tableau d&rsquo;éléments correspondant à ce sélecteur. Evidemment, toutes ces opérations ont un coût en termes de performances.</p>
<p><a href="http://www.w3.org/TR/selectors-api/#documentselector">Selectors API</a> propose de régler ce problème : il sera tout simplement possible de passer une chaîne CSS à la méthode <code class="prettyprint">document.querySelectorAll();</code>, qui renverra un tableau d&rsquo;éléments correspondant à la sélection. Bien entendu, cette méthode sera exécutée par le navigateur, ce qui est beaucoup plus intéressant.</p>
<p>La dernière version de Webkit vient d&rsquo;intégrer cette méthode, et les résultats sont très concluants. Pour le démontrer, ils ont utilisé le benchmark <a href="http://mootools.net/slickspeed/">slickspeed</a> du projet <a href="http://mootools.net/slickspeed/">mootools</a>, permettant justement de comparer les performances des sélecteurs CSS pour chaque bibliothèque : http://webkit.org/perf/slickspeed/ .</p>
<p>Les différentes bibliothèques utilisant un sélecteur de ce type, comme jQuery, peuvent d&rsquo;ores et déjà prendre en compte les navigateurs supportant cette méthode : il suffit de tester <code class="prettyprint">document.querySelectorAll()</code>, et de lui passer la main s&rsquo;il existe.</p>
<p>L&rsquo;article sur Webkit.org : <a href="http://webkit.org/blog/156/queryselector-and-queryselectorall/">http://webkit.org/blog/156/queryselector-and-queryselectorall/</a><br />
Télécharger la dernière version de Webkit : <a href="http://nightly.webkit.org/">http://nightly.webkit.org/</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Les pop-ups sont morts</title>
		<link>/2008/01/29/les-pop-ups-sont-morts/</link>
					<comments>/2008/01/29/les-pop-ups-sont-morts/#comments</comments>
		
		<dc:creator><![CDATA[Eric Le Bihan]]></dc:creator>
		<pubDate>Tue, 29 Jan 2008 00:17:34 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">/2008/01/29/les-pop-ups-sont-morts/</guid>

					<description><![CDATA[Certaines pratiques ont la vie dure… La navigation par pop-up  à l’intérieur d’un site en est une des plus tenaces.
Pourquoi utiliser des pop-up ?
Le raisonnement que j’entends souvent est : « le contenu n’est pas assez important pour une nouvelle page ». Ce raisonnement  aussitôt contredit par des demandes de pop-up de 650px sur 800 px … Pourquoi tant d’acharnement ??!!
Bien sur je ne parle  pas des pop-up non sollicitées qui ne méritent même pas qu’on s’y arrête ne serait-ce qu’un instant, les navigateurs tels que Firefox ou Opéra, nous en débarassent sans que nous ne nous&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Certaines pratiques ont la vie dure… La navigation par pop-up  à l’intérieur d’un site en est une des plus tenaces.</p>
<h3>Pourquoi utiliser des pop-up ?</h3>
<p>Le raisonnement que j’entends souvent est : « le contenu n’est pas assez important pour une nouvelle page ». Ce raisonnement  aussitôt contredit par des demandes de pop-up de 650px sur 800 px … Pourquoi tant d’acharnement ??!!</p>
<p>Bien sur je ne parle  pas des pop-up non sollicitées qui ne méritent même pas qu’on s’y arrête ne serait-ce qu’un instant, les navigateurs tels que Firefox ou Opéra, nous en débarassent sans que nous ne nous en rendions même compte.</p>
<p>Alors que la plupart des  sites a abandonné cette habitude d’un autre temps, certains résistent encore  et toujours bien que les arguments contre l’utilisation de ces petites  fenêtres ne manquent pas :</p>
<h3>Ergonomie :</h3>
<ol>
<li>Les utilisateurs en navigant sur leur site préféré ne  s’attendent pas à ce que les liens sur lesquels ils cliquent ouvrent une autre  fenêtre.</li>
<li>Une pop-up peut passer en dessous de la fenêtre  principale si on clique malencontreusement sur cette dernière.</li>
<li>Si une pop-up est ouverte et se trouve sous la fenêtre  principale toutes les pages ouvertes dans la popup (si elle n’est pas nommée ou  porte le même nom dans toutes les fonctions d’ouverture de la popup) demeureront invisibles pour l’internaute qui croira se trouver en présence de liens  non-fonctionnels.</li>
</ol>
<h3>Accessibilité :</h3>
<ol>
<li>L&rsquo;ouverture d&rsquo;une pop up perturbe  la navigation notamment pour les personnes qui utilisent des aides  techniques pour naviguer. En règle générale, l&rsquo;ouverture d&rsquo;une nouvelle fenêtre  est déstabilisant pour les personnes aveugles.<br />
Il est de plus impossible de revenir à la page précédente par l&rsquo;historique du navigateur.</li>
<li> Une popup est  ouverte par une fonction javascript, sans js la popup ne s’ouvre pas à moins  qu’on prenne le soin d’avoir recours à cette technique (ce qui est loin d’être  le cas, le plus souvent) :</li>
</ol>
<p><code class="prettyprint">        &lt;a href="page.htm" onclick="window.open(this.href); return false;"&gt; </code></p>
<p><em>Il existe d’autres solutions beaucoup plus sympa pour  afficher des informations sans changer de page à l’aide de javascripts  non-intrusifs (il suffit de regarder les scripts et plugins proposés par des  bibliothèques comme <a href="http://fr.wikipedia.org/wiki/JQuery" title="Information sur la bibliothèque javascript jQuery" target="_blank">jQuery </a>ou <a href="http://wiki.script.aculo.us/scriptaculous/" title="Informations sur labibliothèque javascript sciptaculous" target="_blank">script.aculo.us</a>) </em></p>
<h3>Crédibilité :</h3>
<ol>
<li>les pop-up nuisent à l&rsquo;image du site qui les utilise et  donnent une impression générale d’amateurisme.</li>
<li>Les pop-up sont dans la plupart des cas associées à de la pub et  bénéficient de moins d’attention de la part des internautes.</li>
</ol>
<h3>Contraintes des navigateurs :</h3>
<p>Dans les navigateurs modernes, et ceci pour éviter les  abus, il n’est plus possible d’intervenir sur les propriétés des popup  (emplacement, redimensionnement, déplacement, etc.)</p>
<p>Conclusion : on ne devrait plus se poser la question, <strong style="font-size: 14px">les popup, c’est NON !</strong></p>
<p>Quelques liens pour poursuivre cette réflexion :</p>
<ul>
<li>The  Jarrett-Zetie Rules of Pop- ups : <a href="http://www.ergologique.com/actualites/actus.php?id_actu=123">http://www.ergologique.com/actualites/actus.php?id_actu=123</a></li>
<li>Interview Jakob Nielsen sur JDN :  <a href="http://www.journaldunet.com/itws/it_nielsen.shtml">http://www.journaldunet.com/itws/it_nielsen.shtml</a></li>
<li>Créer des popup intelligentes : <a href="http://openweb.eu.org/articles/popup/">http://openweb.eu.org/articles/popup/</a></li>
<li>Lazy, stupid and evil design : <a href="http://www.guardian.co.uk/technology/2005/jun/23/columnists.comment">http://www.guardian.co.uk/technology/2005/jun/23/columnists.comment</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>/2008/01/29/les-pop-ups-sont-morts/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>jQuery : codez branché !</title>
		<link>/2008/01/14/jquery-codez-branche/</link>
					<comments>/2008/01/14/jquery-codez-branche/#comments</comments>
		
		<dc:creator><![CDATA[Pierre Bertet]]></dc:creator>
		<pubDate>Sun, 13 Jan 2008 23:41:00 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<guid isPermaLink="false">/2008/01/14/jquery-codez-branche/</guid>

					<description><![CDATA[Vous avez toujours voulu être branché ? Non ? Pourquoi tu dis rien ?
T&#8217;aimes pas les accroches interrogatives 
Voici donc la suite de notre série d&#8217;articles consacrés à jQuery, avec aujourd&#8217;hui : le plugin !
La conception de jQuery, centrée sur un même objet, permet d&#8217;étendre naturellement notre bibliothèque en créant de nouvelles méthodes. Un plugin sera alors utilisé de cette façon :
$("p").monplugin();
Nous créerons pour l&#8217;exemple un plugin qui fait danser les éléments sélectionnés, appelons-le « jQuery Dance ».
On pourra éventuellement lui passer des options : le tempo, et la taille de la piste de danse&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Vous avez toujours voulu être branché ? Non ? Pourquoi tu dis rien ?</p>
<p>T&rsquo;aimes pas les accroches interrogatives <img src="/wp-content/uploads/2007/12/interrogation.png" alt="?" style="width:200px;vertical-align:middle" /></p>
<p>Voici donc la suite de notre série d&rsquo;articles consacrés à jQuery, avec aujourd&rsquo;hui : le plugin !</p>
<p>La conception de jQuery, centrée sur un même objet, permet d&rsquo;étendre naturellement notre bibliothèque en créant de nouvelles méthodes. Un plugin sera alors utilisé de cette façon :</p>
<pre class="brush:js;">$("p").monplugin();</pre>
<p>Nous créerons pour l&rsquo;exemple un plugin qui fait danser les éléments sélectionnés, appelons-le « jQuery Dance ».</p>
<p>On pourra éventuellement lui passer des options : le tempo, et la taille de la piste de danse bien entendu !</p>
<p>Il sera utilisé ainsi :</p>
<pre class="brush:js;">$("p").dance();</pre>
<p>Ah, vous l&rsquo;aviez certainement noté : la sonorité de jQuery est proche de celle de charcuterie. Et comme pour la <a href="http://fr.wikipedia.org/wiki/Saucisson" title="Saucisson - Wikipedia">rosette</a>, certaines règles sont à respecter pour créer un <a href="http://docs.jquery.com/Plugins/Authoring" title="Créer un plugin jQuery sur la documentation officielle">plugin de qualité</a>, les voici.</p>
<h3>Nommez votre fichier</h3>
<p>Un plugin doit toujours se nommer ainsi, de manière à ce qu&rsquo;il soit immédiatement identifiable : <strong>jquery.nom_du_plugin.js</strong><br />
Notre fichier se nommera donc <strong>jquery.dance.js</strong>.</p>
<h3>Isolez votre code</h3>
<p>Dans ce fichier nouvellement créé, nous allons commencer par englober tout ce qui va être écrit dans une fonction anonyme qui sera immédiatement executée. De cette manière, toutes les variables que vous créerez ne rentrerons pas en collision avec les autres scripts présents sur la page.</p>
<pre class="brush:js;">(function(){
	// Code
})()</pre>
<p>Nous allons en profiter pour passer la variable jQuery (dont $ n&rsquo;est qu&rsquo;un alias) à cette fonction, de cette manière :</p>
<pre class="brush:js;">(function($){
	// Code
})(jQuery)</pre>
<p>Cela permettra d&rsquo;utiliser la variable <code>$</code> à l&rsquo;intérieur de notre fonction.<br />
Pourquoi, puisque <code>$</code> est déjà un alias de <code>jQuery</code> ?</p>
<p>jQuery permet de renommer cette fonction à l&rsquo;aide de <a href="http://docs.jquery.com/Core/jQuery.noConflict">jQuery.noConflict()</a>.<br />
Il est donc possible de faire cohabiter jQuery et l&rsquo;une des nombreuses librairies utilisant la fonction <code>$()</code> (comme <a href="http://www.prototypejs.org/">Prototype</a>), en renommant l&rsquo;alias comme bon nous semble :</p>
<pre class="brush:js;">var $j = jQuery.noConflict();</pre>
<p>Nous devons donc nous assurer que la fonction <code>$()</code> existe bien, et que nous n&rsquo;utilisons pas une autre librairie à la place de <code>jQuery</code>.</p>
<h3>Ajoutez votre nouvelle méthode à jQuery.fn</h3>
<p>Après avoir créé notre environnement, nous sommes prêts à écrire notre plugin.<br />
Nous voulons donc ajouter une nouvelle méthode aux objets jQuery. Il faut pour cela ajouter une nouvelle fonction à l&rsquo;objet jQuery.fn. Dans cette fonction, le mot-clé <code>this</code> représente l&rsquo;objet jQuery sélectionné par l&rsquo;utilisateur de votre plugin.</p>
<p>Dans le cas où notre plugin serait défini de cette façon :</p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(){
		alert(this == ma_selection);
	};
})(jQuery)</pre>
<p>Et qu&rsquo;une variable globale (absence du mot <code>var</code>) <code>ma_selection</code> soit définie ainsi :</p>
<pre class="brush:js;">// Au chargement...
$(function(){
	ma_selection = $("p");
	ma_selection.dance();
});</pre>
<p>Le message affiché par la fonction <code>alert()</code> serait <code>true</code>.</p>
<h3>Bouclez sur les éléments sélectionnés</h3>
<p>Vous devez toujours considérer que plusieurs éléments ont été sélectionnés avant d&rsquo;appeler votre méthode.</p>
<p>Pour traiter chacun de ces éléments, la méthode <a href="http://docs.jquery.com/Core/each#callback"><code>each()</code></a> de jQuery sera utilisée. cette méthode prend en paramètre une fonction, qui sera executée pour chaque élément. Dans cette boucle, le mot <code>this</code> correspondra cette fois à chacun des éléments DOM de cette sélection.<br />
Pour obtenir un objet jQuery, il faudra passer cet élément à la fonction <code>$()</code>.</p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(){
		this.each(function(){
		  // this : élément DOM classique
		  // $(this) : élément jQuery
		});
	};
})(jQuery)</pre>
<p>Gardez à l&rsquo;esprit que cette fonction est executée pour chacun des éléments de la sélection. Il est donc préférable de ne placer dans cette fonction que les traitements liés à chaque élément en particulier.</p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(){

		// Le tempo est le même pour tous les éléments,
		// inutile de le redéfinir à chaque  fois.
		var tempo = 300;

		// Cette fonction n'est définie qu'une fois,
		// puis appelée par chacun des éléments.
		function move(jElt){
			// Nous placerons ici le code permettant
			// de faire danser le Boogie Woogie à un élément
		};

		this.each(function(){
			move( $(this) );
		});
	};
})(jQuery)</pre>
<h3>Retournez l&rsquo;objet sélectionné</h3>
<p>Cette pratique permettra d&rsquo;<a href="/2007/08/16/jquery-dansez-maintenant/" title="jQuery : dansez maintenant !">utiliser plusieurs méthodes en chaîne</a> :</p>
<pre class="brush:js;">$("p").dance().css("color", "red");</pre>
<p>Evidemment, si votre plugin renvoie une information, il ne sera alors pas possible de chaîner plusieurs méthodes (comme avec la méthode width() par exemple).</p>
<p>Il faudra donc que votre méthode retourne <code>this</code> avant de  se terminer.</p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(){

		// Code...

		<strong>return this;</strong>
	};
})(jQuery)</pre>
<p>Et puisque la méthode each() de jQuery renvoie l&rsquo;élément sélectionné, vous pouvez retourner votre sélection en bouclant sur chacun des éléments :</p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(){

		// Code...

		<strong>return this</strong>.each(function(){
			move( $(this) );
		});
	};
})(jQuery)</pre>
<p>Bien, nous avons vu les bases de la création d&rsquo;un plugin. Le plugin « jQuery Dance » peut maintenant être utilisé de cette façon :</p>
<pre class="brush:js;">$("p").dance().css("border","1px");</pre>
<h3>Passez des paramètres à votre méthode</h3>
<p>Comme nous l&rsquo;avons vu au début de cet article, la méthode <code>dance()</code> prendra deux paramètres : <code>tempo</code> et <code>dancefloorArea</code>, correspondant respectivement à la fréquence d&rsquo;execution de chaque mouvement(en millisecondes), et à la surface que pourra utiliser cet élément (en pixels).</p>
<p>Définir des paramètres pour notre méthode est très simple :</p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(<strong>tempo</strong>, <strong>dancefloorArea</strong>){

		// Code...

	};
})(jQuery)</pre>
<p>La méthode pourra donc être appelée de cette façon :</p>
<pre class="brush:js;">$("p").dance(<strong>300</strong>, <strong>400</strong>)</pre>
<h3>Etendez vos paramètres optionnels</h3>
<p>Avant d&rsquo;avancer dans la réalisation de jQuery Dance et de permettre à nos éléments de se déhancher sur le dancefloor, nous allons voir une dernière technique, permettant de passer des paramètres optionnels à une méthode jQuery.</p>
<p>Nos paramètres ne seront alors plus passés directement, mais à l&rsquo;aide d&rsquo;un tableau associatif :</p>
<pre class="brush:js;">$("p").dance(<strong>{tempo: 300, danceFloorArea: 400}</strong>)</pre>
<p>La fonction <a href="http://docs.jquery.com/Utilities/jQuery.extend#targetobject1objectN"><code>jQuery.extend(a, b)</code></a> permet d&rsquo;étendre un objet <code>a</code> avec un objet <code>b</code>, en écrasant les propriétés redéfinies.<br />
Voici un exemple :</p>
<pre class="brush:js;">var objet_a = {
	param_1: "Bonjour",
	param_2: "les p'tits gars"
};
var objet_b = {
	param_2: "tout le monde",
	param_3: "ça va ?"
};

$.extend(objet_a, objet_b);

alert(objet_a.param_1); // Bonjour
alert(objet_a.param_2); // tout le monde
alert(objet_a.param_3); // ça va ?</pre>
<p>En plus de l&rsquo;étendre, cette fonction renvoie le premier objet modifié, ce qui est très pratique lorsque le premier objet est défini en paramètre :</p>
<pre class="brush:js;">var objet_b = {
	param_2: "tout le monde",
	param_3: "ça va ?"
};

var objet_a = $.extend({
	param_1: "Bonjour",
	param_2: "les p'tits gars"
}, objet_b);</pre>
<p>Nous utiliserons cette technique pour étendre nos paramètres par défaut avec ceux passés à la méthode, de cette façon :</p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(params){

		// Si aucun paramètre n'est passé
		// et que params est vide, alors $.extend()
		// renverra simplement le premier objet passé
		var params = $.extend({
			tempo: 300,
			dancefloorArea: 400
		},params);

		function move(jElt){
			// Boogie Woogie
		};

		return this.each(function(){
			move( $(this) );
		});
	};
})(jQuery)</pre>
<h3>Voulez-vous danser mademoiselle ?</h3>
<p>Chacun de nos éléments sera déplacé, au hasard, sur la surface définie par <code>dancefloorArea</code> (400px par défaut). Chacun de ces déplacements sera déclenché selon l&rsquo;intervalle définie par <code>tempo</code> (300 millisecondes par défaut).</p>
<p>Nous allons définir une nouvelle fonction (tirée de la <a href="http://developer.mozilla.org/fr/docs/R%C3%A9f%C3%A9rence_de_JavaScript_1.5_Core:Objets_globaux:Math:random">documentation Mozilla</a>), permettant d&rsquo;obtenir un nombre entier situé entre les deux passés en paramètres.</p>
<p>Nous allons également définir les variables <code>minPosition</code> et <code>maxPosition</code> d&rsquo;après <code>params.dancefloorArea</code></p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(params){

		// Paramètres
		var params = $.extend({
			tempo: 300,
			dancefloorArea: 400
		},params);

		// Renvoie un entier situé entre min et max
		<strong>function getRandomInt(min, max)</strong>{
		  return Math.floor(Math.random() * (max - min + 1)) + min;
		};

		// Positions minimales et maximales
		// que pourra prendre un élément
		<strong>var minPosition</strong> = -(params.dancefloorArea/2);
		<strong>var maxPosition</strong> = params.dancefloorArea/2;

		// Mouvement d'un élément
		function move(jElt){
			<strong>var topPos</strong> = getRandomInt(minPosition, maxPosition);
			<strong>var leftPos</strong> = getRandomInt(minPosition, maxPosition);
		};

		return this.each(function(){
			move( $(this) );
		});
	};
})(jQuery)</pre>
<p>Pour chaque élément, une position sera définie à l&rsquo;aide des variables <code>leftPos</code> et <code>topPos</code>.</p>
<p>Il nous reste donc à animer notre élément vers cette position pendant le temps défini par <code>tempo</code>, puis à appeler cette fonction, encore et encore, jusqu&rsquo;au bout de la nuit. Nous utiliserons la méthode <a href="http://docs.jquery.com/Effects/animate#paramsdurationeasingcallback"><code>animate()</code></a> de jQuery. Les éléments seront également positionnés en relatif pour être déplacés par rapport à leur position, sans gêner les voisins parce que bon, ils n&rsquo;ont rien demandé eux.</p>
<pre class="brush:js;">(function($){
	$.fn.dance = function(params){

		// Paramètres
		var params = $.extend({
			tempo: 300,
			dancefloorArea: 400
		},params);

		// Renvoie un entier situé entre min et max
		function getRandomInt(min, max){
		  return Math.floor(Math.random() * (max - min + 1)) + min;
		};

		// Positions minimales et maximales
		// que pourra prendre un élément
		var minPosition = -(params.dancefloorArea/2);
		var maxPosition = params.dancefloorArea/2;

		// Mouvement d'un élément
		function move(jElt){
			var topPos = getRandomInt(minPosition, maxPosition);
			var leftPos = getRandomInt(minPosition, maxPosition);

			// Préfixer une variable par la lettre j
			// (ou ce qui vous semblera pertinent)
			// permet d'identifier facilement un objet jQuery.
			<strong>jElt.animate</strong>(

				// Premier paramètre : les nouvelles propriétés CSS
				// vers lesquelles l'élément va être animé.
				{
					<strong>top: topPos + "px"</strong>,
					<strong>left: leftPos + "px"</strong>
				},

				// Deuxième paramètre : le temps que durera l'animation
				<strong>params.tempo</strong>,

				// Troisième paramètre, la fonction qui sera appelée
				// lorsque l'animation sera terminée.
				function(){
					<strong>move(jElt);</strong> // Nous appelons à nouveau la fonction move()
				}
			);
		};

		return this<strong>.css("position", "relative")</strong>.each(function(){
			move( $(this) );
		});
	};
})(jQuery)</pre>
<p>Vous trouverez une démonstration de notre plugin à cette adresse : <a href="/demos/jquery/dance.html" title="Démonstration du plugin jQuery Dance">/demos/jquery/dance.html</a></p>
<p>Je dois avouer, et vous le reconnaîtrez sûrement, que le résultat est affligeant. Mais bon, hein.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2008/01/14/jquery-codez-branche/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>IE7.js v2.0 (Beta)</title>
		<link>/2008/01/08/ie7js-v20-beta/</link>
					<comments>/2008/01/08/ie7js-v20-beta/#comments</comments>
		
		<dc:creator><![CDATA[Pierre Bertet]]></dc:creator>
		<pubDate>Tue, 08 Jan 2008 11:27:41 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">/2008/01/08/ie7js-v20-beta/</guid>

					<description><![CDATA[Dean Edwards vient de mettre à jour son célèbre script IE7.js, permettant de corriger un paquet de limitations CSS / HTML sur notre navigateur préféré : Internet Explorer.
Puisque IE7 est sorti, et que certaines limitations sont encore d&#8217;actualités, le script a été scindé en deux parties : IE7.js se limite maintenant aux améliorations d&#8217;IE7 qu&#8217;il apporte à IE5/6, tandis qu&#8217;IE8.js reprend les fonctionnalités d&#8217;IE7.js toujours absentes dans Internet Explorer 7.
Un projet a été créé chez Google Code pour l&#8217;occasion : http://code.google.com/p/ie7-js/
Voici un bon moyen d&#8217;accompagner doucement ce vieux navigateur vers ses derniers instants, tout en profitant des&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="http://dean.edwards.name/weblog/2008/01/ie7-2/">Dean Edwards vient de mettre à jour</a> son célèbre script IE7.js, permettant de <a href="http://ie7-js.googlecode.com/svn/test/index.html">corriger un paquet de limitations CSS / HTML</a> sur notre navigateur préféré : Internet Explorer.</p>
<p>Puisque IE7 est sorti, et que certaines limitations sont encore d&rsquo;actualités, le script a été scindé en deux parties : IE7.js se limite maintenant aux améliorations d&rsquo;IE7 qu&rsquo;il apporte à IE5/6, tandis qu&rsquo;IE8.js reprend les fonctionnalités d&rsquo;IE7.js toujours absentes dans Internet Explorer 7.</p>
<p>Un projet a été créé chez Google Code pour l&rsquo;occasion : <a href="http://code.google.com/p/ie7-js/">http://code.google.com/p/ie7-js/</a></p>
<p>Voici un bon moyen d&rsquo;accompagner doucement ce vieux navigateur vers ses derniers instants, tout en profitant des sélecteurs (classes multiples, sélecteurs d&rsquo;attributs, :hover sur tous les éléments, &#8230;) et propriétés (min-height, max-height&#8230;) CSS. Sans même utiliser IE8.js, placer IE6 au même niveau que son jeune frérot procure un sacré confort !</p>
<p>Evidemment, cette solution n&rsquo;est pas parfaite : le style de vos pages sera en partie altéré pour un utilisateur d&rsquo;IE6 ayant désactivé javascript. Il faut alors s&rsquo;assurer que chaque page reste bien accessible.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2008/01/08/ie7js-v20-beta/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>jQuery : dansez maintenant !</title>
		<link>/2007/08/16/jquery-dansez-maintenant/</link>
					<comments>/2007/08/16/jquery-dansez-maintenant/#comments</comments>
		
		<dc:creator><![CDATA[Pierre Bertet]]></dc:creator>
		<pubDate>Wed, 15 Aug 2007 22:27:40 +0000</pubDate>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<guid isPermaLink="false">/2007/08/16/jquery-dansez-maintenant/</guid>

					<description><![CDATA[Il est grand temps de publier la suite du précédent article sur jQuery, dans lequel nous abordions le fonctionnement global de la bibliothèque, suivi de la construction d&#8217;un objet.
Nous allons maintenant voir ce qu&#8217;il est possible de faire à partir de cet objet.
Méthodes de jQuery
L&#8217;objet jQuery, comme tout objet, dispose de méthodes. Grossièrement, il s&#8217;agit d&#8217;actions qu&#8217;un objet sait accomplir.
Pour comparaison, si notre objet était une grosse voiture rouge (on vend du rêve sur lesintegristes.net), elle aurait la faculté d&#8217;avancer vite.
Ca pourrait donner en français la syntaxe suivante :
Voiture, avance (vite) !
jQuery dispose&#160;[&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Il est grand temps de publier la suite du <a href="/2007/06/11/inauguration-et-introduction-a-jquery/" title="Introduction à jQuery">précédent article sur jQuery</a>, dans lequel nous abordions le fonctionnement global de la bibliothèque, suivi de la construction d&rsquo;un objet.</p>
<p>Nous allons maintenant voir ce qu&rsquo;il est possible de faire à partir de cet objet.</p>
<h3>Méthodes de jQuery</h3>
<p>L&rsquo;objet jQuery, comme tout objet, dispose de méthodes. Grossièrement, il s&rsquo;agit d&rsquo;actions qu&rsquo;un objet sait accomplir.<br />
Pour comparaison, si notre objet était une grosse voiture rouge (on vend du rêve sur lesintegristes.net), elle aurait la faculté d&rsquo;avancer vite.</p>
<p>Ca pourrait donner en français la syntaxe suivante :<br />
Voiture, avance (vite) !</p>
<p>jQuery dispose de la méthode <code class="prettyprint">fadeOut()</code>, pour masquer les éléments englobés dans notre objet jQuery avec un effet de fondu certifié « Ouais bah deux pouin zéro. »<br />
&#8211; « Hein ? »<br />
&#8211; « Ouais bah j&rsquo;dis c&rsquo;que j&rsquo;veux. »</p>
<p>Prenons pour exemple ce petit morceau de HTML, qui ne se doute de rien :</p>
<pre><code class="prettyprint">&lt;p class="outi"&gt;Lalalala, je me balade dans la forêt...&lt;/p&gt;</code></pre>
<p>Nous allons maintenant sélectionner ce paragraphe, et le faire disparaître avec un effet de fondu :</p>
<pre><code class="prettyprint">$("p.outi").fadeOut();</code></pre>
<p>Notre objet est <code class="prettyprint">$("p.outi")</code>, à qui nous demandons de disparaître ( <code class="prettyprint">.fadeOut()</code> ).</p>
<p>La méthode <code class="prettyprint">fadeOut()</code> accepte un paramètre qui permet de modifier la vitesse de l&rsquo;effet : on peut lui passer le temps, en millisecondes, ou les chaînes « slow », « normal » et « fast » :</p>
<pre><code class="prettyprint">$("p.outi").fadeOut("slow");
$("p.outi").fadeOut(300);</code></pre>
<p>Il est également possible de passer un deuxième paramètre, appelé callback. Il s&rsquo;agit d&rsquo;une fonction qui va être appelée lorsque l&rsquo;effet sera terminé. Essayons !</p>
<pre><code class="prettyprint">// Au chargement du DOM...
$(function(){
	// On sélectionne notre paragraphe
	$("p.outi")
	// On lui applique l'effet fadeOut()
	.fadeOut(
		// Avec "slow" en premier paramètre
		"slow",
		// Et une fonction de "callback"
		// en deuxième paramètre
		function(){$(this).fadeIn("slow");}
	);
});</code></pre>
<p>Dans notre callback, nous utilisons <code class="prettyprint">this</code>, qui correspond dans ce contexte à l&rsquo;objet DOM sur lequel l&rsquo;effet est appliqué.<br />
Nous le transformons donc en objet jQuery avant de lui appliquer la méthode <code class="prettyprint">fadeIn()</code>, qui va comme vous l&rsquo;avez deviné faire exactement l&rsquo;inverse de <code class="prettyprint">fadeOut()</code>, et faire apparaître de nouveau notre paragraphe.</p>
<h3>Les méthodes en chaîne</h3>
<p>La plupart des méthodes de jQuery ont une particularité : elles renvoient l&rsquo;objet jQuery lui-même.<br />
Prenons un exemple, à l&rsquo;aide de <a href="http://www.mozilla-europe.org/fr/products/firefox/">Mozilla Firefox</a> et de son excellent plugin <a href="http://www.getfirebug.com/">Firebug</a>, qui permet (entre autres) d&rsquo;afficher n&rsquo;importe quel objet à l&rsquo;aide de l&rsquo;objet <code class="prettyprint">console</code>.<br />
Nous allons utiliser la méthode <code class="prettyprint">css()</code>, qui permet de modifier une ou plusieurs propriétés CSS des éléments sélectionnés :</p>
<pre><code class="prettyprint">$(function(){
	console.log( $("p.outi") );
	// Affiche [p.outi]

	console.log( $("p.outi").css("color", "red") );
	// Affiche [p.outi], la méthode css()
	// renvoie bien notre objet.
});
</code></pre>
<p>Ainsi, il va être possible de réutiliser notre objet, pour lui appliquer tout ce que l&rsquo;on veut.</p>
<p>Pour illustrer ceci, nous allons créer notre premier script « utile ».<br />
Notre client s&rsquo;est réveillé cette nuit pour noter une idée, qui va à coup sûr donner un énorme avantage technologique à son  site sur la concurrence :<br />
&#8211; « Le texte de ce paragraphe apparaîtra en&#8230; glissant, après avoir survolé le bouton rouge : Survolez-moi ! »<br />
&#8211; « Ha »<br />
&#8211; « Imaginez la tête du visiteur ! »<br />
&#8211; « &#8230; »<br />
&#8211; « Sinon ça va, vous ? »<br />
&#8211; « &#8230; O&#8230; Oui, ça va. »</p>
<p>Bon, il est temps d&rsquo;enfiler notre costume de Superman pour trouver une solution accessible avec ça.</p>
<p><img src="/wp-content/uploads/2007/08/superman.jpg" alt="Superman" style="margin: 0pt 0pt 14px; float: left" /><br />
&#8211;  » Ca gratte un peu, mais bon.  »</p>
<p style="clear: left">Pour que ce texte reste accessible à tout ce qui n&rsquo;utilise pas Javascript, il va devoir être masqué au chargement de la page, en Javascript.<br />
Le bouton qui permettra de l&rsquo;afficher n&rsquo;ayant aucun sens sans script, nous allons également le générer. Il nous restera ensuite à créer l&rsquo;effet voulu.<br />
Hop :</p>
<pre><code class="prettyprint">$(function(){
	$("p.outi").before("&lt;span&gt;Survolez-moi !&lt;/span&gt;").hide();
});
</code></pre>
<p>Nous avons sélectionné le paragraphe, ajouté un élément <code class="prettyprint">&lt;span&gt;</code> qui va nous servir de bouton, puis nous avons masqué notre paragraphe, car la méthode <code class="prettyprint">before()</code>, qui permet d&rsquo;ajouter un élément avant celui sélectionné, va retourner l&rsquo;objet jQuery.</p>
<p>Nous allons maintenant modifier notre sélection jQuery, à l&rsquo;aide de la méthode <code class="prettyprint">prev()</code>, qui permet de sélectionner l&rsquo;élément précédent (le <code class="prettyprint">&lt;span&gt;</code>).<br />
Nous voyons donc ici notre première méthode qui ne retourne pas l&rsquo;objet jQuery premièrement sélectionné.<br />
C&rsquo;est très intéressant, car cela va nous permettre de continuer à « chaîner » nos méthodes à partir de l&rsquo;élément <code class="prettyprint">&lt;span&gt;</code> nouvellement créé.</p>
<p>Nous lui appliquerons ensuite un style à l&rsquo;aide de la méthode <code class="prettyprint">css()</code> que nous avons vu précédemment.<br />
Mais plutôt que de modifier une seule propriété en passant deux chaînes de caractère, nous allons lui passer un tableau associatif, contenant toutes les propriétés CSS que nous voulons définir.</p>
<pre><code class="prettyprint">$(function(){
	$("p.outi").before("&lt;span&gt;Survolez-moi !&lt;/span&gt;").hide()
	.prev().css({
		display: "block",
		height: "30px",
		width: "100px",
		lineHeight: "30px",
		textAlign: "center",
		border: "1px solid #f00",
		cursor: "pointer"
	});
});
</code></pre>
<p>Facile, non ?</p>
<p>Il ne nous reste plus qu&rsquo;à attacher un événement au survol de cet élément. jQuery propose un tas de méthodes, permettant d&rsquo;associer des événements à des éléments. Leur nom reprend ceux de DOM, sans le préfixe « on ». Ils prennent en paramètre une fonction.<br />
Nous allons donc utiliser la méthode <code class="prettyprint">mouseover()</code> :</p>
<pre><code class="prettyprint">$(function(){
	$("p.outi").before("&lt;span&gt;Survolez-moi !&lt;/span&gt;").hide()
	.prev().css({
		display: "block",
		height: "30px",
		width: "100px",
		lineHeight: "30px",
		textAlign: "center",
		border: "1px solid #f00",
		cursor: "pointer"
	})
	.mouseover(function(){
		$(this).next().slideDown();
	});
});
</code></pre>
<p>A l&rsquo;intérieur de cette fonction, qui va se déclencher au survol, nous avons englobé notre <code class="prettyprint">&lt;span&gt;</code>, représenté par <code class="prettyprint">this</code>, dans un objet jQuery, puis sélectionné l&rsquo;élément suivant à l&rsquo;aide de <code class="prettyprint">next()</code>, et finalement affiché notre paragraphe à l&rsquo;aide de la méthode <code class="prettyprint">slideDown()</code>.</p>
<p>Vous avez remarqué ?<br />
Nous sommes partis d&rsquo;une unique sélection, <code class="prettyprint">$("p.outi")</code>.</p>
<p>Oui, c&rsquo;est beau. Oui, c&rsquo;est propre. C&rsquo;est jQuery.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2007/08/16/jquery-dansez-maintenant/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
	</channel>
</rss>
