jQuery : l’événement !
Enfin « les », événements. Je voulais un titre sensationnel.
Vous connaissez certainement jQuery, l’excellente bibliothèque Javascript. Non ? Alors c’est ici.
Le développement DOM/Javascript repose en grande partie sur les événements. Vous savez certainement qu’il est possible d’affecter un événement à un objet jQuery, c’est à dire qu’une fonction se déclenchera lors d’un événement sur l’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’agit d’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’événement DOM, allégé de son préfixe « on » (onclick, onmouseout, etc. ).
Si aucun paramètre n’est passé, cette méthode déclenche l’événement.
Si une fonction est passée en paramètre, elle s’exécutera lorsque l’événement sera déclenché (depuis le code comme vu juste au-dessus, ou « naturellement »).
Vous trouverez la liste complète de ces méthodes sur la page de documentation des événements : http://docs.jquery.com/Events.
Définir un événement
Commençons par un exemple. Tout le monde aime les exemples !
L’événement onclick
peut être défini sur un objet jQuery à l’aide de la méthode click()
à laquelle est passée une fonction :
$("a#test1").click(function(){
window.alert("Clic sur a#test1.");
});
La fonction passée en paramètre peut attendre un paramètre. Il représente l’objet événement, et possède plusieurs propriétés et méthodes. J’ai l’habitude d’utiliser une variable nommée « e » (event), mais on peut évidemment utiliser un autre nom.
La méthode preventDefault() de cet objet permet d’empêcher le navigateur de déclencher son comportement par défaut.
Sur un lien, cette méthode empêchera simplement le navigateur de le suivre.
Exemple.
$("a#test1").click(function(e){
e.preventDefault(); // Empêche le navigateur de suivre le lien.
window.alert("Clic sur a#test1.");
});
Démonstration : a#test1
Déclencher un événement depuis le code
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.
Un exemple. « 例 », dirait un japonais, mais vous n’êtes pas obligé de me croire.
Nous allons réutiliser l’événement précédemment défini dans le premier exemple, en le déclenchant depuis le code.
Lorsque le lien du second exemple ( « a#test2 » ) sera cliqué, un clic sera déclenché sur le lien du premier exemple ( « a#test1 » ).
Exemple.
$("a#test2").click(function(e){
e.preventDefault();
window.alert("Clic sur a#test2, déclenchement du clic sur a#test1...");
$("a#test1").click();
});
Démonstration : a#test2
La méthode ready()
Vous avez certainement déjà utilisé la méthode ready()
d’un objet jQuery contenant l’objet DOM document
.
Si un script est défini et exécuté dans la partie <head>
d’une page et qu’il essaie de manipuler des éléments, le navigateur se comportera comme s’ils n’existaient pas.
Le script est exécuté au moment où il est lu par le navigateur (sauf avec l’attribut defer). Puisque la suite du document n’a pas encore été chargée, le navigateur n’a pas connaissance de ces éléments.
Pour remédier à cela, il est possible d’attacher un événement onload
sur l’objet window
, qui sera déclenché lorsque la page et tous ses éléments seront chargés.
Exemple.
$(window).load(function(){
// Le code placé ici sera déclenché
// au chargement complet de la page.
});
Il s’agit de l’équivalent jQuery du célèbre window.onload = function(){}
. É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’analyse de statistiques basé sur un script externe), un long moment peut s’écouler avant que votre script ne soit exécuté.
C’est pourquoi la méthode ready()
de l’élément document
a été créée : la fonction affectée à cet événement sera déclenchée dès que le document HTML et les CSS seront chargés.
Le mécanisme de cet événement jQuery est plutôt intéressant. Il ne s’agit pas d’un événement natif DOM, ou pas tout à fait : Mozilla Firefox, Opera et les dernières versions de Webkit déclenchent bien un événement DOMContentLoaded lorsque le document HTML est chargé, mais Opera n’attend pas que les styles soient chargés pour le déclencher. On ne peut pas vraiment lui donner tort, puisque sur le brouillon de la spécification HTML5 rien n’est précisé à propos du chargement des styles.
jQuery résout ce problème sur Opera en attendant que chaque feuille de style soit disponible. Pour cela, la propriété disabled
de chacun des objets contenus dans document.styleSheets
(chaque fichier CSS) est testée jusqu’à ce qu’elle renvoie false
, c’est à dire lorsque la CSS est chargée.
Pour Internet Explorer, l’astuce consiste à tester la méthode document.documentElement.doScroll("left");
jusqu’à ce qu’elle ne retourne plus d’erreur. Dès que c’est le cas, cela signifie que les styles sont chargés.
Pour Webkit, c’est la propriété document.readyState
qui est testée, puis un test similaire à celui utilisé pour Opera se charge de vérifier le chargement complet des CSS.
Certains navigateurs supportent l’événement document.DOMContentLoaded
(Mozilla Firefox), c’est donc ce dernier qui est utilisé.
Pour les navigateurs ne supportant pas document.DOMContentLoaded
et n’entrant pas dans les cas particuliers traités par jQuery (Opera, Webkit, Internet Explorer), c’est un simple événement window.onload qui est utilisé
.
Voilà, vous oubliez ça, jQuery le fait pour vous :
function bindReady(){
if ( readyBound ) return;
readyBound = true;
// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
if ( document.addEventListener && !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 && 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 < 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" && 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 );
}
Vous l’aurez compris, il s’agit d’un extrait du code de jQuery.
Il existe deux autres « Event Helpers » particuliers, appelés « Interaction Helpers ». Les deux fonctionnent de la même manière, à la différence qu’ils attendent deux fonctions en paramètre plutôt qu’une.
La méthode hover()
permet de spécifier deux événements, pour l’entrée et la sortie du curseur souris dans la zone que couvre le ou les éléments de notre objet jQuery. Mon vieil ami Superman appelle ce comportement le « survol ».
Ils ne sont pas tout à fait équivalents aux événements onmouseover
et onmouseout
, existant nativement en DOM.
En utilisant ces derniers, lorsque le curseur se déplace d’un élément à un autre au sein de l’élément sur lequel est attaché l’événement (par exemple lorsqu’il passe sur une image se trouvant à l’intérieur d’un élément <div>), onmouseover
sera déclenché sur l’image (sur laquelle aucun événement n’est défini), et « remontera » jusqu’à son conteneur, pour déclencher une seconde fois l’événement. La cible de l’événement va également changer, ce sera l’image et non le conteneur.
En sortant le curseur de l’image, même problème : c’est cette fois l’événement onmouseout qui sera déclenché sur le conteneur, mais avec l’image pour cible.
Pour en savoir plus, c’est ici : http://www.quirksmode.org/js/events_mouse.html
Si nous ne voulons pas de ce comportement, il faut vérifier que l’élément survolé au déclenchement de l’événement corresponde bien à l’élément sur lequel l’événement a été défini. C’est fastidieux. jQuery s’en charge automatiquement lorsque vous utilisez hover()
.
La seconde méthode est toggle()
. Elle est équivalente à la méthode click()
, 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.
Les méthodes bind et trigger (affecter et déclencher)
La méthode bind()
Vous pouvez utiliser la méthode bind()
pour affecter un ou plusieurs é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 !
Exemple.
$("a#test3").bind("mouseover mouseout", function(e){
$(this).text( "-- " + $(this).text() + " --" );
});
Démonstration : a#test3
Deux événements « spéciaux » sont disponibles avec la méthode bind()
: mouseenter
et mouseleave
.
Ils correspondent à l’entrée la sortie du curseur sur un élément, sans déclencher l’événement lorsqu’un élément enfant est survolé. Ces événements correspondent à ceux définis par la méthode hover()
.
La méthode trigger()
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 trigger()
sera utilisée.
Exemple.
$("a#test4").bind("click", function(e){
e.preventDefault();
jQuery("a#test3").trigger("mouseover");
});
Démonstration : a#test4 : un clic sur ce lien déclenchera un survol sur l’élément a#test3 (démonstration précédente)
Supprimer un événement avec unbind()
Supprimer un événement est trivial. Il suffit d’appeler la méthode unbind()
en lui passant en paramètre le ou les événements à supprimer. Si aucun événement n’est passé en paramètre, tous les événements affectés à cet objet jQuery seront supprimés.
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.
Exemple.
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é
Passer des données à un événement
La méthode trigger()
permet également d’envoyer des données à la fonction déclenchée par l’événement. On passera alors ces données en second paramètre, après le nom de l’é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.
$("a#test5").trigger("click", ["paramètre 1", 2, {parametre: "3"}]);
Lors de la définition de l’événement avec la méthode bind(), la fonction passée en paramètre devra définir ces paramètres pour pouvoir les utiliser.
Tous les paramètres supplémentaires sont ajoutés après le premier, qui représente toujours l’objet événement (« e » dans l’exemple suivant).
Exemple.
$("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)
});
Démonstration (cliquez sur le bouton) : , a#test5
Essayez maintenant de cliquer sur le lien juste au-dessus, vous verrez que les paramètres ont la valeur undefined
la boîte de dialogue déclenchée par window.alert ne s’affiche même pas pour le troisième paramètre : le fait d’appeler une clé inexistante (param3["parametre"]
) déclenchera une erreur Javascript.
Comme dit plus haut, si un seul paramètre est passé, vous pouvez l’utiliser directement :
Exemple.
$("a#test5").trigger("click", "paramètre 1");
Bien entendu, la fonction n’attend qu’un paramètre dans ce cas :
$("a#test5").bind("click", function(e, param1){
e.preventDefault();
window.alert(param1); // Affiche "paramètre 1"
});
Les événements « sur mesure »
Il est possible d’utiliser bind()
pour affecter un événement personnalisé. Cet événement ne pourra être déclenché qu’avec la méthode trigger()
.
– A quoi ça sert, exactement ?
– Principalement, à découper certaines parties d’un script, liées à un objet jQuery, en événements. Mais c’est quoi ces questions ? C’est pour me déstabiliser, c’est ça ?
Prenons un lien, auquel nous attacherons l’événement « StyleFunky ». Lorsque cet événement sera déclenché, notre lien va naturellement s’imposer dans le page, montrer à tous qu’il n’est pas le genre de lien qu’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’un window.setInterval()
pour changer sa couleur de fond, mais ce sera transparent pour nous, une fois notre fonction définie. Seul l’événement « StyleFunky » sera ensuite déclenché.
Nous attacherons également un autre événement à ce lien, « StyleNormal », qui annulera les effets de l’événement précédent (y compris le window.setInterval
) :
Exemple.
$("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"
});
});
Demostración (c’est de l’espagnol) :
Les Namespaced Events (événements nommés)
Nous avons vu qu’il était possible avec unbind()
de supprimer une seule des fonctions attachées à un événement, mais cette méthode est peu élégante, puisqu’elle n’autorise pas l’utilisation de fonctions anonymes.
Pour remédier à cela, jQuery permet de nommer une fonction attachée à un événement.
Une notation similaire à celle des classes CSS est utilisée, accolée au nom de l’événement (« .action1 », « .action2 » et « .action3 » ici) :
$(element).bind("click.action1", function(){ /* Action 1 */ });
$(element).bind("click.action2", function(){ /* Action 2 */ });
$(element).bind("click.action3", function(){ /* Action 3 */ });
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’événement « click » :
$(element).trigger("click.nom1"); /* Déclenche l'action 1 */
$(element).trigger("click"); /* Déclenche les actions 1, 2 et 3 */
Évidemment, il sera possible de les supprimer, individuellement, ou non.
$(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) */
La méthode .triggerHandler()
Pour finir, la méthode triggerHandler()
permet de déclencher les différentes fonctions attachées à un événement, sans déclencher l’action par défaut du navigateur.
Prenons l’événement focus
sur un champ texte de formulaire. Si vous lui affectez une action particulière (comme afficher une bulle d’information), vous pourrez alors déclencher cette action sans déplacer le curseur de l’utilisateur dans le champ :
$(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 */
Voilà, c’est fini.
Les commentaires sont fermés sur cet article.
12 commentaires
Flux RSS des commentaires de cet article
jQuery : l’événement !…
Vous trouverez dans ce tutoriel les différentes manières d’utiliser les événements avec jQuery….
Le 16 Sep. 2008 à 13h33 par Anonyme
Chouette tuto !
Ca me donne envie de faire quelques tests et d’essayer de casse mon navigateur :D
Le 16 Sep. 2008 à 17h23 par raphaël
Merci Pierre pour ce chouette billet !
Le 17 Sep. 2008 à 18h44 par Vincent Valentin
[…] jQuery : l’événement ! | Les intégristes […]
Le 24 Sep. 2008 à 10h07 par digg-design.fr - le blog! » Archive du blog » Articles les plus votés
Bonjour,
Juste pour vous déclarer mon enthousiasme.
Je bosse actuellement dur sur un plugin WordPress : Events-Calendar. C’est passionnant et il y a beaucoup à faire. Allez donc voir un peu de quoi il s’agit sur mon blog ;)
Enfin bon, il y a quelques semaine je ne connaissais ni bian Javascript et encore moins jQuery et j’ai pas mal galérer.
Et là je tombe sur votre site et vos charmants tutos. Bah je sens que vous allez être mes nouveaux Dieux !
J’ai mille et une question évidemment. Mais je vais tout d’abord lire vos tutos avant de voir si ce sont vraiment des questions à poser ;)
Cordialement
Heirem
Le 25 Sep. 2008 à 16h42 par Heirem
Heirem : C’est malin, vous m’avez fait rougir ;-)
Le 26 Sep. 2008 à 12h21 par Pierre Bertet
C’est un excellent article, en tout cas, ça m’a permis de beaucoup mieux comprendre JQUERY :)
Merci beaucoup :)
Le 24 Oct. 2008 à 16h03 par Sun Location
Excellent article comme toujours.
Un peu fébrile, faut dire qu’il se fait tard ou tôt, enfin il fait nuit, j’ai plusieurs fois cliqué sur le « StyleFunky », ben très très speed le style et il ne veut plus devenir « StyleNormal ». J’espère pas avoir tout cassé.
JLMag
Le 30 Nov. 2008 à 05h38 par jlmag
Très bon tutoriel,
bonne continuation pour la suite.
Le 18 Avr. 2009 à 10h32 par Masin
j’ai un probleme ! avec IE tout fonctionne mais pas avec FireFox
j’utilise JQuery, j’aimerais que au moment que la page LOAD que mes TEXTAREA ce CACHE automatiquement lorsque la page ce load. avec la commande suivante:
$(‘#example’).hide().hide(‘fast’);
me comprenez-vous bien ?
Le 25 Août. 2009 à 16h11 par Mathieu St-Germain
Excellent tutoriel sur les évènements jQuery . Merci !
Le 13 Jan. 2010 à 18h56 par Blog referencement
très bon tutoriel, merci ^^
Le 23 Avr. 2011 à 18h53 par El garch