Gestion interactive avec jQuery

Share:
jQuery permet d’ajouter tout un certain nombre d’écouteurs sur l’ensemble des éléments contenu dans un document.
Ce type d’interactions peut s’appliquer à l’ensemble des éléments contenus dans un document, que celles-ci soient appliquées par le clavier, la souris, les formulaires de saisies ou encore le navigateur.Leur principe d’utilisation est identique à tout ce que nous avons vu dans l’article sur les premiers pas avec jQuery, c’est-à-dire qu’il suffit de cibler un ou plusieurs éléments en usant du sélecteur approprié, puis de lui appliquer un écouteur. Nous allons au cours de cet article, explorer plus avant certaines de ces possibilités.

Interaction de base

Nous avons utilisé au cours du précédent article deux ajouts d’écouteurs :
$(document).ready()
$('p').click()
Le premier est sollicité une fois le document prêt à être utilisé, c’est-à-dire, une fois l’ensemble de l’information HTML chargée, et le second lui, ajoute un écouteur de clic sur l’ensemble des éléments de type <p> du document. Cette manière d’ajouter des écouteurs aux éléments, en ‘pointant’ directement le type d’écouteur sous forme de fonction à l’objet ciblé, est un raccourci de la méthode on().
S’il est vrai que de prime abord, il semble n’y avoir aucune distinction particulière dans l’utilisation de l’une ou l’autre, nous allons voir que la seconde a l’avantage d’être plus ouverte et de permettre de très simplement ajouter :
D’une part, plusieurs types d’écouteurs sur l’élément :
$('p').click()
$('p').on('click dblclick',function(){})
$('p').on('mousedown mouseup',function(){})
Et d’autre part, de cibler de manière différente les éléments :
$('p','article').click()
$('article').on('click','p', function(){})
La différence majeure entre les deux lignes précédentes viendra du fait, que dans le premier cas, un écouteur sera placé sur chaque paragraphe contenu dans la balise <article>, ce qui peut rapidement être volumineux. Alors que dans le second cas, un seul écouteur est placé sur la balise <article>, mais ne cible que les déclenchements liés à une interaction appliqué à une balise <p>.

D’autres possibilités pour lier un écouteur à un objet…

Les raccourcis de ‘type’ (.click(), .dblclick(), .mousenter()...) et la fonction .on()… ne sont pas les seules manières à disposition pour attacher des écouteurs aux éléments. Il existe également d’autres fonctions disponibles comme .live() (attention cette fonction devient obsolète dans les dernières versions de la librairie), bind() (qui devient également déconseillée dans les dernières versions de la librairie), .delegate() (elle aussi rejoint les deux précédentes sur les étagères de la librairie).
Donc, parmi toutes ces possibilités, quelle méthode utiliser ?… et si .live(), .delegate et .bind() sont déconseillées, qui les remplace ? et à quoi servaient-elles ? L’article Differences between jQuery .bind() vs .live() vs .delegate() vs .on(), qui est relativement complet, permet de bien se faire une idée sur chacune des ces fonctions et précise clairement que depuis la version 1.7 de la librairie, tout porte vers l’utilisation de la fonction .on().
Au cours de cet article, nous utiliserons des formes raccourcies comme .click() dans certaines situations, afin de rapidement démontrer un mécanisme. Mais l’emploi de .on() sera préconisé lors de nos développements d’applications. Bien entendu, si nous optons pour l’usage d’une librairie plus récente que 1.7.

Utilisation de la fonction .on()

La fonction s’utilise de manière très simple, il suffit de l’attacher à un des éléments parents des éléments à cibler. Ensuite, appliquer le sélecteur affinant la requête, pour n’intercepter que les interactions des éléments souhaités. De plus, il est possible de passer un objet contenant des informations complémentaires.
Enfin on termine par la fonction à invoquer lors de l’interception de l’évènement. Voir la page d’illustration.
$('article').on('click','p',{info:"données complémentaires"},function(e) {
alert('Click sur une balise <p>, avec des ' + e.data.info)
})

Les diverses méthodes

En parrallèele de la classique fonction .click(), nous avons accès à tout un certains nombre d’autres fonctions. Vous en trouverez la liste complète depuis le site offciel Category:Events, mais en voici un résumé dans le tableau ci-dessous :
Liste des raccourcis des méthodes accessibles






























Interactions imbriquées

Le tableau qui illustre le chapitre précédent est en fait basé uniquement sur HTML. Chaque cellule contient un lien de type <a href="">. Il serait complètement envisageable de le réaliser intégralement en jQuery et pour cela avoir recours à un bout de code du type :
$('td').click()
Bien que cela soit totalement fonctionnel, le système de boucles mis en place par jQuery pourrait rapidement devenir gourmand en ressources dès lors que le tableau augmenterait en volume. Pour contourner cette problématique, il sera alors plus judicieux d’utiliser les particularités de la propagation évènementielle et notamment son principe de ‘bulle’ qui permet d’intégrer, de manière individuelle, chacun des enfants de l’élément auquel l’écouteur est attaché.
jQuery nous aide en cela dans le sens où il nous propose la propriété target qui renvoi un pointeur vers l’élément qui a intercepté l’action.
De ce fait, en plaçant un écouteur sur la balise <table>, il est très facile d’identifier la cellule qui a intercepté le click. Le code n’est pas plus court, certes, mais grandement plus économe en ressources. Vous pouvez consulter la page d’illustration et visualiser ci-dessous le code utilisé :
$(document).ready(function(){
$('table.a').click(function(event){
var that = $(this).get(0).nodeName
alert(that + " -- " + event.target.firstChild.nodeValue)
});
$('table.b').on('click','td',function(event){
var that = $(this).get(0).nodeName
alert(that + " -- " + event.target.firstChild.nodeValue)
});
});

Interactions multiples

De la même manière qu’il est possible d’ajouter un écouteur sur un élément, il est possible de retirer ce même écouteur. Cependant, et du fait que plusieurs actions peuvent être affectées au même écouteur, il peut y avoir des fonctionnements inattendus qui se produisent.
Pour le mettre en évidence, imaginons la situation suivante :
Ajoutons à l’ensemble des balises <p> du document un écouteur 'click' qui applique une action A. Ajoutons maintenant un écouteur 'click' uniquement à la première balise <p> du document, qui cette fois-ci applique une action B.
Utilisons un tierce élément qui a pour fonction de retirer l’écouteur 'click' de cette même première balise <p>. Il est facile de constater depuis la page d’illustration que par cette action, les deux actions A et B sont retirées.
Il est à noter que lors de l’utilisation de la fonction .on(), on use de la fonction .off() pour retirer la première, alors que lors de l’utilisation des anciennes fonctions dont nous parlions précédemment il existait à chaque fois la paire adaptée, à savoir, .bind(), .unbind(), puis .live(), .die(), et .delegate(), .undelegate().
$(document).ready(function(){
$('p:not(#retrait)').on('click',function(){
alert('Action A');
});
$('p:first-child').on('click',function(){
alert('Action B');
});
$('p:first-child').addClass('special');
$('p#retrait').on('click',function(){
$('p:first-child').off('click')
$('p:first-child').removeClass('special')
});
});
Si notre objectif dans l’exemple précédent serait de ne retirer que l’action B de la première balise <p>, jQuery nous propose l’utilisation d’espace de nommage lors de la mise en place de nos écouteurs. Les espaces de nommage se mettent en place tout simplement en indiquant sous forme de propriété un nom d’identification à l’écouteur ajouté.
$('p').on('click.identificateur',function(){});
Dans l’exemple précédent, il nous suffit donc d’identifier les écouteurs lors de leur mise en place et de ne supprimer que l’écouteur désiré pour atteindre les objectifs que nous nous étions fixés. Vous pouvez consulter la page d’illustration et visualiser le nouveau code à mettre en place ci dessous :
$(document).ready(function(){
$('p:not(#retrait)').on('click.actionA',function(){
alert('Action A');
});
$('p:first-child').on('click.actionB',function(){
alert('Action B');
});
$('p:first-child').addClass('special');
$('p#retrait').on('click',function(){
$('p:first-child').off('click.actionB')
$('p:first-child').removeClass('special')
});
});

Interactions alternées

jQuery nous propose d’autres types d’écouteurs très intéressants à explorer. Par exemple, nous sommes souvent amenés à utiliser des interactions à bascule. C’est à dire une interaction qui active / désactive une fonctionnalité à chacun des clics, ou permet de varier l’action en se basant sur une série d’enchainements. Une fois oui, une fois non, ou alors une fois l’une, une fois l’autre et encore une fois une autre…
Il existe pour cela une mécanique intégrée qui permet de le traiter ce genre de comportement, mais uniquement jusqu’à la version 1.8.3 de la librairie, il s’agit de la fonction toggle(). L’instruction accepte plusieurs fonctions comme paramètres, chacune étant une des fonctions devant être utilisée en alternance, voir la page d’illustration :
$('p').toggle(function(){alert('a')}, function(){alert('b')}, function(){alert('c')}...)
Une autre méthode souvent nécessaire sur une série d’élément, est de pouvoir sélectionner un des éléments, puis d’en sélectionner un second et le premier serait alors déselectionné. Une possibilité toute simple, est d’utiliser une classe qui servira de pointeur. Par exemple lors d’un clic sur un élément, on recherche la présence d’une classe spécifique (par exemple .surbrillance), on retire alors cette classe des éléments trouvés, et on l’applique au nouvel élément cliqué. Le plus simple reste d’analyse la page d’illustration.
$('p').click(function(){
$('.surbrillance').removeClass('surbrillance')
$(this).addClass('surbrillance')
});
En parallèle de cela, certaines autres fonctionnalités sont également intégrées à jQuery, qui permettent de rapidement mettre en place ce genre de besoins. Par exemple, nous avons vu qu’il était possible d’ajouter, ou de retirer, une classe CSS d’un élément, en usant de addClass('') et removeClass('').
En utilisant conjointement l’instruction toggle(), cela nous permet de prendre en charge l’affichage / masquage d’un élément. Mais il y a plus simple, il existe une autre instruction qui permet en une seule manœuvre d’ajouter ou retirer une classe donnée : toggleClass('laclasse').

Le toggle se décline sur diverses possibilités.

En allant encore plus loin, et si l’utilisation d’une classe n’est pas strictement nécessaire, il existe encore d’autres jeux instructions qui permettent cette fois-ci d’user d’une d’animation pour obtenir l’effet. Il s’agit des instructions show() / hide() et fadeIn() / fadeOut(). Ces dernières acceptent un paramètre fixe ayant pour valeur slow, normal ou fast.
Mettons cela en pratique afin de mieux évaluer les articulations. Imaginons un document composé de citations courtes <q> et de citations longues <blockquote>.
Il peut être intéressant alors de n’afficher que les citations courtes et de n’afficher / masquer les citations longues, qu’à la demande, par clic utilisateur sur les citations courtes.
Paradoxalement, la complexité ne vient pas du code jQuery, mais de la mise en relation des citations courtes, avec les citations longues qui leurs correspondent. Pour cela, nous userons de l’attribut title qui sera identique entre les diverses citations en relation. Ceci dit, le plus simple reste encore de laisser parler la page d’illustration et le code qui lui est associé (attention à utiliser avant la version 1.9 de la librairie) :
$(document).ready(function(){
$('blockquote').hide()
$('q').toggle(function(){
$('blockquote[title="'+this.title+'"]').fadeIn('slow')
},function(){
$('blockquote[title="'+this.title+'"]').fadeOut('slow')
})
})
et nous pourrions même avoir recourt à une autre instruction de la panoplie jQuery qui est fadeToggle et qui réduit encore plus le code, voir la page d’illustration et constater encore une fois la simplicité et la réduction du code :
$(document).ready(function(){
$('blockquote').hide()
$('q').click(function(){
$('blockquote[title="'+this.title+'"]').fadeToggle("slow", "linear");
})
})

Coupler sélecteur, toggle et autres instructions…

On retrouve de plus en plus les modèles de menus accordéons, et pour cela il n’est pas nécessaire d’avoir systématiquement recours à une librairie de module d’interface de type jQuery UI. Avec une combinaison de quelques instructions jQuery, comme dirait Ludovic, le tour peut être joué. Prenons l’exemple d’une liste imbriquée qui ne doit laisser apparaitre son contenu secondaire qu’à l’interaction. Il est alors nécessaire de bloquer l’interaction de la liste supérieure envers la liste inférieure et vice versa également. Voir le code ci-dessous ainsi que la page d’illustration :
$('ul ul').slideUp('fast')
$('ul ul').on("click", "li",function(e) {
alert($(this).text()).stop();
})
$('ul').on("click", "li:not(>ul)",function(e) {
$('.actif')
.find('ul')
.slideUp("slow",function(e){})
.end()
.removeClass('actif')
$(this)
.addClass('actif')
.find("ul")
.slideToggle("slow",function(e){});
})

Conclusion

Avec ces quelques illustrations, nous venons de mettre le pied dans un univers sur lesquels les librairies apportent énormément, l’interaction et la gestion de l’interface, l’animation et les effets. Bien que l’une des premières librairies à avoir placer ses marques sur l’animation et/ou les effets soit script.aculo.us, très proche de prototype dont elle en est le complément, jQuery, de son coté, n’est pas sans reste sur le sujet et propose de nombreuses possibilités.
Nous n’allons pas déborder outre mesure sur le sujet, mais simplement faire mention de l’une des composantes intéressantes de l’animation avec l’instruction animate(). Cela fera certainement l’objet d’un billet dédié et plus approprié.

No comments