jQuery : la puissance de l'outil

Dans ce quatrième chapitre sur jQuery je vais essayer de vous convaincre d'employer cet outil. Dans certains cas il simplifie énormément la programmation JavaScript.

Je vais vous montrer aussi que vous pouvez employer le mot magique this comme en JS traditionnel.

Exemple 1

Une page comprend N images miniatures et pratiquement transparentes.
Dès qu'une image est survolée sa taille doit être triplée et elle doit devenir parfaitement opaque.

Ce thème a déjà été évoqué dans le cadre de la programmation JS traditionnelle.

Ci-dessous rappel du code utilisé dans le cadre d'une programmation traditionnelle

... <style> img {display : block ; width : 100px; margin :10px auto 10px auto ; opacity : 0.2;} img.petit {width : 10% ; opacity : 0.2 ; } img.grand {width : 30% ; opacity : 1 ; } ... <body> <img src = '../images/toucan.jpg' class ='petit' onmouseover ="fgrand(this)" onmouseout ="fpetit(this)" /> <img src = '../images/tortue.jpg'class ='petit' onmouseover ="fgrand(this)" onmouseout ="fpetit(this)" /> <img src = '../images/foret.jpg' class ='petit' onmouseover ="fgrand(this)" onmouseout ="fpetit(this)" /> <img src = '../images/riviere.jpg'class ='petit' onmouseover ="fgrand(this)" onmouseout ="fpetit(this)" /> ... <script> function fpetit(image) {image.className ="petit" ; } function fgrand(image) {image.className ="grand" ; } ...

Via la feuille de style chaque image est traitée comme un élément "block" pour son centrage horizontal.

Notez aussi les deux classes spécifiques aux images : petit et grand.
La classe petit affecte une petite taille et une quasi transparence à l'image et la classe grand une taille triple et une opacité totale.

Le code HTML est particulièrement lourd car emploi du gestionnaire d'événements.
Notez l'emploi du mot this qui désigne l'image courante (survolée par la souris).

Par contre le script est simple : attribution de la classe "petit" ou de la classe "grand" à l'image courante.
Notez le passage de paramètre dans chaque fonction. La variable image désigne l'image courante.

La solution avec jQuery

Le code CSS et HTML

<style> img {display : block ; width : 10%; margin :10px auto 10px auto ; opacity : 0.2;} ... <body> ... <img src = '../images/toucan.jpg' /> <img src = '../images/tortue.jpg'/> <img src = '../images/foret.jpg' /> <img src = '../images/riviere.jpg' /> ...

CSS : les définitions de classe on disparu.
Dans le cadre du "responsive web design" la largeur des images est exprimée en %.
Le HTML est d'une simplificité déroutante. Plus besoin d'utiliser le gestionnaire d'événements.

Le script

$("img").mouseover(function() {$(this).css("width", "30%").css("opacity",1)}); $("img").mouseout(function() {$(this).css("width", "10%").css("opacity",0.2)});

Admirez la concision du code !
On combine le sélecteur $("img") et le sélecteur $(this) dans la même instruction.

Traduisons en Français la première instruction : si survol d'une image (sélecteur $("img")) par la souris (événement : mouseover) cette dernière (sélecteur $(this)) se voit appliquer deux propriétés de style : width et opacity.
Essayez ce code !

Boucle avec jQuery

Imaginons que nous voulions successivement examiner chaque image de la page pour afficher sa source et son éventuel texte alternatif.

En JS traditionnel il faut réaliser une boucle. Le code donne ceci :

var images = document.querySelectorAll('img') ; var vnombre = images.length ; // nombre d'éléments du tableau images for(i = 0 ; i<= vnombre ; i++) { alert(images[i].src); alert(images[i].alt); }

En jQuery nous avons la structure each ! Nous allons la présenter via un exemple.

Le code de l'exemple

... <h1>Boucle en jQuery</h1> <button onclick ="finfos()">Infos sur les images de la page </button> <img src = '../images/toucan.jpg' alt ="toucan" /> <img src = '../images/tortue.jpg'/> <img src = '../images/foret.jpg' /> <img src = '../images/riviere.jpg'/> <script> function finfos() { $("img").each(function(){ alert(" source image :" +$(this).attr("src") + " texte : " +$(this).attr("alt"));}); } ...

Commentaire du code

Il y a quatre images.
Toutes les images ont l'attribut src mais seule une image a l'attribut alt ...
Quand vous cliquez sur le bouton de commande la boîte de dialogue alert est affichée quatre fois.
Pour un attribut non utilisé la réponse est "undefined".
On a donc bien réalisé une boucle !

Notez bien la syntaxe : $("sélecteur").each(function() {instruction1 ; instruction2; ... }); .
Le sélecteur utilisé doit bien sûr désigner une collection d'éléments (ici l'ensemble des balises img).
Rendu de ce code !

Remarque importante

Dans de nombreux sites et ouvrages traitant de jQuery il vous est indiqué que le script jQuery doit démarrer ainsi :

<script> $(document).ready(function() { // le code Jquery }) ; </script>

Hors dans mes scripts je n'utilise jamais $(document).ready(function() {...}); et pourtant ça marche ...

Cette instruction veut dire que le jQuery doit être exécuté seulement lorsque la page est chargée (et donc le DOM constitué).
Ce qui tout à fait logique. En effet si vous tentez via jQuery de manipuler des noeuds du DOM alors que ce dernier n'a pas été créé il y aura forcément "plantage" !

Cette instruction est indispensable si le script jQuery se situe dans la partie HEAD de la page.

Or mon script jQuery n'est jamais dans la partie HEAD mais toujours dans la partie BODY et juste avant </body> donc après tout le code HTML.
Donc il est exécuté seulement après que la page ait été chargée (et le DOM construit).
Donc l'instruction $(document).ready(function() est alors totalement inutile !

Exemple 2 : de nouvelles méthodes

Dans un exemple précédent j'ai utilisé la propriété de style display pour masquer/démasquer des éléments.
Mais il y a plus simple en jQuery !
En effet il a les méthodes hideet show().

Nous allons utiliser ces deux méthodes pour réaliser des menus horizontaux déroulants.
Si vous avez lu dans mon site le tuto "HTML & CSS pour débutants" ou le tuto "CSS3" vous savez qu'il est possible de réaliser des menus déroulants sans recourir au Javascript mais uniquement en HTML & CSS.

Mais vous avez pu remarquer que c'est de la "bidouille". Il faut utiliser plusieurs astuces en jouant sur plusieurs propriétés de style. Bref c'est pas très simple. Dans ce chapitre je vous propose une solution plus cartésienne en utilisant jQuery.

Le code CSS & HTML

<style> div {width : 30% ; height : auto ; display : inline-block ; background : pink; margin-right : 1% ; vertical-align :top; } ul {display : none ; list-style :none ; } p {height : 30px ; line-height : 30px ; text-align : center; font-weight : bold; } ... <body> ... <div> <p>Menu 1</p> <ul> <li><a href ="#">lien 1</a> <li><a href ="#">lien 2</a> <li><a href ="#">lien 3</a> </ul> </div> <div> <p>Menu 2</p> <ul> <li><a href ="#">lien 21</a> <li><a href ="#">lien 22</a> <li><a href ="#">lien 23</a> </ul> </div> <div> <p>Menu 3</p> <ul> <li><a href ="#">lien 31</a> <li><a href ="#">lien 32</a> <li><a href ="#">lien 33</a> </ul> </div> ...

Chaque menu correspond à un DIV qui contient une balise P et une liste à puces (UL).
Les liste(balise UL) sont par défaut masquées.
Les boîtes DIV se positionnent côte à côte (display : inline-block)
Chaque lien est contenu dans un item de liste.
Dans le cadre d'un site adaptatif la largeur de chaque DIV et des marges exprimée en %.

Le script

$("p").mouseover(function() {$(this).next("ul").show();}); $("p").mouseout(function() {$(this).next("ul").hide();});

Oui, vous ne rêvez pas. Il n'y a que deux instructions. Mais deux instructions d'une puissance exceptionnelle !

$("p").mouseover(function() {$(this).next("ul").show();}); : si survol avec la souris d'une balise P la liste à puces (UL) qui suit la balise P courante (sélecteur : $(this).next("ul")) est affichée (méthode : show()).

Nous avons utilisé la méthode next() argumentée avec le sélecteur "ul" pour sélectionner la liste à puces qui suit le paragraphe pointé.

Essayez de programmer la même chose en JS traditionnel ... Je vous souhaite beaucoup de courages et de tasses de café et de nuits blanches ...
Essayez les menus déroulants en Jquery !

Le problème c'est que le menu s'affiche puis disparaît de façon instantanée.
Il serait préférable qu'il y ait une transition : affichage et disparition lente ou bien un effet "fondu" (menu de plus en plus opaque puis de plus en plus transparent).

Si vous avez visité le tuto "CSS 3" vous savez qu'il est possible désormais en CSS d'effectuer des transitions.
En fait c'est CSS3 qui s'est inspiré de Jquery car le Jquery a été inventé entre autres pour permettre la programmer facilement ces effets.

Menus déroulants avec transitions

Nous voulons que le menu se déroule lentement et disparaîsse tout aussi lentement.

Le code CSS & HTML ne change pas !

Le script

$("p").mouseover(function() {$(this).next("ul").slideDown(1000);}); $("p").mouseout(function() {$(this).next("ul").slideUp(1000);});

slideDown(1000) : l'objet sélectionné s'affiche lentement (en 1000 millisecondes ou un seconde).

slideUp(1000) : l'objet sélectionné disparaît lentement (en 1000 millisecondes ou 1 seconde).
Essayez les menus déroulants avec transitions !

Menus déroulants avec effet "fondu"

Nous voulons maintenant un effet "fondu" c'est à dire que l'objet est de plus en plus opaque puis de plus en plus transparent jusqu'à diparaître (opacité = 0).

Toujours pas de changement dans le HTML & CSS !

Il faut alors écrire le script de la façon suivante :

$("p").mouseover(function() {$(this).next("ul").fadeIn(1000);}); $("p").mouseout(function() {$(this).next("ul").fadeOut(1000);});
Testez les menus déroulants avec effet "fondu" !

Simplification de la syntaxe

Lorsque vous devez modifier plusieurs propriétés de style ou plusieurs attributs il peut devenir fastidieux d'indiquer à chaque fois la méthode css ou la méthode attr.

Thème

Si une image est survolée elle est agrandie et devient plus opaque (deux propriétés de style modifiées)

Si double clic sur une image elle est remplacée par celle d'une baigneuse en burkini et un message moralisateur apparaît si survol de cette nouvelle image.

Le code (extraits)

... <style> img {width : 15% ;opacity : 0.1; } ... <body> ... <img src = '../images/bikini.jpg'/> <img src = '../images/trikini.jpg'/> <script> $("img").mouseover(function(){$(this).css({"opacity": "1", "width":"50%"});}); $("img").mouseout(function(){$(this).css({"opacity": "0.1", "width":"15%"});}); $("img").dblclick(function(){$(this).attr({"src": "../images/burkini.jpg", "title":"Gros vicieux. C'est un site sérieux et pas un site pornographique !"}).css("opacity","1");}); ...
Testez cet exemple moralisateur !

Commentaire du script

Dans les première et deuxième instructions la méthode css n'est pas répétée deux fois ; elle est mise en facteur commun.
On utilise la même syntaxe mais avec la méthode attr cette fois dans la troisième instruction.
N'oubliez pas les accolades !

Cette syntaxe doit vous faire penser à quelque chose ...
En fait on a utilisé la fameuse notation JSON que j'ai déjà utilisé pour définir les variables indicées (voir tuto de JavaScript traditionnel).

En définitive la syntaxe est :
css/attr({"propriété/attribut":"valeur","propriété/attribut":"valeur","propriété/attribut":"valeur", ...})

Notez que la commande width est exprimée en %.

Le "slideshow" (diaporama)

Reprenons le thème du SLIDESHOW traité en JS traditionnel.
Vous allez voir que jQuery permet de simplifier non seulement le script mais aussi le code HTML

Le code HTML

... <table> <tr> <td><img src ="../images/palourde_royale.jpg" alt ='Palourde royale'></td> <td><img src ="../images/danseuse_espagnole.jpg" alt ='Danseuse espagnole'></td> <td><img src ="../images/ormeau.jpg" alt ='Ormeau'></td> <td><img src ="../images/nautile.jpg" alt ='Nautile'></td> </tr> </table> ...

Plus besoin d'utiliser le gestionnaire d'événements de HTML. Donc les "onclick ... " ont disparu de chaque balise img.

Le script

$("img").click(function() { var source = $(this).attr("src"); source ="url(" + source +")" ; $("div").css("backgroundImage", source); var texte = $(this).attr("alt"); $("h4").text(texte); } );
Testez cette version jQuery du Slideshow !
Retour menu