Les événements au travers du DOM

Parent Previous Next



Les événements au travers du DOM



Bien, maintenant que nous avons vu l'utilisation des événements sans le DOM, nous allons passer à leur utilisation au travers de l'interface implémentée par Netscape que l'on appelle le DOM-0 puis au standard de base actuel : le DOM-2.


Le DOM-0


Cette interface est vieille mais n'est pas forcément dénuée d'intérêt. Elle reste très pratique pour créer des événements et peut parfois être préférée au DOM-2.

Commençons par créer un simple code avec un événement click :


<span id="clickme">Cliquez-moi !</span>

 

<script>

 

  var element = document.getElementById('clickme');

 

  element.onclick = function() {

      alert("Vous m'avez cliqué !");

  };

 

</script>



Alors, voyons par étapes ce que nous avons fait dans ce code :


Comme vous le voyez, on définit maintenant les événements non plus dans le code HTML mais directement en Javascript. Chaque événement standard possède donc une propriété dont le nom est, à nouveau, précédé par les deux lettres « on ». Cette propriété ne prend plus pour valeur un code Javascript brut, mais soit le nom d'une fonction, soit une fonction anonyme. Bref, dans tous les cas, il faut lui fournir une fonction qui contiendra le code à exécuter en cas de déclenchement de l'événement.


Concernant la suppression d'un événement avec le DOM-0, il suffit tout simplement de lui attribuer une fonction anonyme vide :

element.onclick = function() {};


Voilà tout pour les événements DOM-0, nous pouvons maintenant passer au cœur des événements : le DOM-2 et l'objet Event.


Le DOM-2


Nous y voici enfin ! Alors, tout d'abord, pourquoi le DOM-2 et non pas le DOM-0 voire pas de DOM du tout ? Concernant la méthode sans le DOM, c'est simple : on ne peut pas y utiliser l'objet Event qui est pourtant une mine d'informations sur l'événement déclenché. Il est donc conseillé de mettre cette méthode de côté dès maintenant (nous l'avons enseignée juste pour que vous sachiez la reconnaître).


En ce qui concerne le DOM-0, il a deux problèmes majeurs : il est vieux, et il ne permet pas de créer plusieurs fois le même événement.


Le DOM-2, lui, permet la création multiple d'un même événement et gère aussi l'objet Event. Autrement dit, le DOM-2 c'est bien, mangez-en !


En clair, il faut constamment utiliser le DOM-2 ?


Non, pas vraiment. Autant la technique sans le DOM est à bannir, autant l'utilisation du DOM-0 est largement possible, tout dépend de votre code.
D'ailleurs, dans la majorité des cas, vous choisirez le DOM-0 pour sa simplicité d'utilisation et sa rapidité de mise en place. Ce n'est, généralement, que lorsque vous aurez besoin de créer plusieurs événements d'un même type (click, par exemple) que vous utiliserez le DOM-2.


Cependant, attention ! S'il y a bien une situation où nous conseillons de toujours utiliser le DOM-2, c'est lorsque vous créez un script Javascript que vous souhaitez distribuer. Pourquoi ? Eh bien admettons que votre script ajoute (avec le DOM-0) un événement click à l'élément <body>, si la personne qui décide d'ajouter votre script à sa page a déjà créé cet événement (avec le DOM-0 bien sûr) alors il va y avoir une réécriture puisque cette version du DOM n'accepte qu'un seul événement d'un même type !


Le DOM-2 selon les standards du Web


Comme pour les autres interfaces événementielles, voici un exemple avec l'événement click :

<span id="clickme">Cliquez-moi !</span>

 

<script>

 

  var element = document.getElementById('clickme');

 

  element.addEventListener('click', function() {

      alert("Vous m'avez cliqué !");

  }, false);

 

</script>



Concrètement, qu'est-ce qui change par rapport au DOM-0 ? Alors tout d'abord nous n'utilisons plus une propriété mais une méthode nommée addEventListener() (qui ne fonctionne pas sous IE8 et antérieur, mais nous en reparlerons par la suite), et qui prend trois paramètres :


Une petite explication s'impose pour ceux qui n'arriveraient éventuellement pas à comprendre le code précédent : nous avons bel et bien utilisé la méthode addEventListener(), elle est simplement écrite sur trois lignes :


Ce code revient à écrire le code suivant, de façon plus rapide :

var element = document.getElementById('clickme');

 

var myFunction = function() {

    alert("Vous m'avez cliqué !");

};

 

element.addEventListener('click', myFunction, false);


Comme indiqué plus haut, le DOM-2 permet la création multiple d'événements identiques pour un même élément, ainsi, vous pouvez très bien faire ceci :

<span id="clickme">Cliquez-moi !</span>

 

<script>

 

  var element = document.getElementById('clickme');

 

  // Premier événement click

  element.addEventListener('click', function() {

      alert("Et de un !");

  }, false);

   

  // Deuxième événement click

  element.addEventListener('click', function() {

      alert("Et de deux !");

  }, false);

 

</script>



Si vous avez exécuté ce code, vous avez peut-être eu les événements déclenchés dans l'ordre de création, cependant ce ne sera pas forcément le cas à chaque essai. En effet, l'ordre de déclenchement est un peu aléatoire…

Venons-en maintenant à la suppression des événements ! Celle-ci s'opère avec la méthoderemoveEventListener() et se fait de manière très simple :

element.addEventListener('click', myFunction, false); // On crée l'événement

 

element.removeEventListener('click', myFunction, false); // On supprime l'événement en lui repassant les mêmes paramètres


Toute suppression d'événement avec le DOM-2 se fait avec les mêmes paramètres utilisés lors de sa création ! Cependant, cela ne fonctionne pas aussi facilement avec les fonctions anonymes ! Tout événement DOM-2 créé avec une fonction anonyme est particulièrement complexe à supprimer, car il faut posséder une référence vers la fonction concernée, ce qui n'est généralement pas le cas avec une fonction anonyme.


Le DOM-2 selon Internet Explorer


Ah ! Le fameux Internet Explorer ! Jusqu'à présent nous n'avions quasiment aucun problème avec lui, il respectait les standards, mais cela ne pouvait pas durer éternellement. Et voilà que les méthodes addEventListener() et removeEventListener() ne fonctionnent pas !
Alors que faut-il utiliser du coup ? Eh bien les méthodes attachEvent() et detachEvent() ! Celles-ci s'utilisent de la même manière que les méthodes standards sauf que le troisième paramètre n'existe pas et que l'événement doit être préfixé par « on » (encore, oui…). Exemple :

// On crée l'événement

element.attachEvent('onclick', function() {

    alert('Tadaaaam !');

});

 

// On supprime l'événement en lui repassant les mêmes paramètres

element.detachEvent('onclick', function() {

    alert('Tadaaaam !');

});


Internet Explorer, à partir de sa neuvième version, supporte les méthodes standards. En revanche, pour les versions antérieures il vous faudra jongler entre les méthodes standards et les méthodes de IE. Généralement, on utilise un code de ce genre pour gérer la compatibilité entre navigateurs :

function addEvent(element, event, func) {

 

    if (element.addEventListener) { // Si notre élément possède la méthode addEventListener()

        element.addEventListener(event, func, false);

    } else { // Si notre élément ne possède pas la méthode addEventListener()

        element.attachEvent('on' + event, func);

    }

 

}

 

addEvent(element, 'click', function() {

    // Votre code

});



Les phases de capture et de bouillonnement
Du côté de la théorie

Vous souvenez-vous que notre méthode addEventListener() prend trois paramètres ? Nous vous avions dit que nous allions revenir sur l'utilisation de son troisième paramètre plus tard. Eh bien ce « plus tard » est arrivé !


Capture ? Bouillonnement ? De quoi parle-t-on ?


Ces deux phases sont deux étapes distinctes de l'exécution d'un événement. La première, la capture(capture en anglais), s'exécute avant le déclenchement de l'événement, tandis que la deuxième, lebouillonnement (bubbling en anglais), s'exécute après que l'événement a été déclenché. Toutes deux permettent de définir le sens de propagation des événements.

Mais qu'est-ce que la propagation d'un événement ? Pour expliquer cela, prenons un exemple avec ces deux éléments HTML :

<div>

  <span>Du texte !</span>

</div>


Si nous attribuons une fonction à l'événement click de chacun de ces deux éléments et que l'on clique sur le texte, quel événement va se déclencher en premier à votre avis ? Bonne question n'est-ce pas ?

Notre réponse se trouve dans les phases de capture et de bouillonnement. Si vous décidez d'utiliser la capture, alors l'événement du <div> se déclenchera en premier puis viendra ensuite l'événement du<span>. En revanche, si vous utilisez le bouillonnement, ce sera d'abord l'événement du <span> qui se déclenchera, puis viendra par la suite celui du <div>.


Voici un petit code qui met en pratique l'utilisation de ces deux phases :

<div id="capt1">

  <span id="capt2">Cliquez-moi pour la phase de capture.</span>

</div>

 

<div id="boul1">

  <span id="boul2">Cliquez-moi pour la phase de bouillonnement.</span>

</div>

 

<script>

    var capt1 = document.getElementById('capt1'),

        capt2 = document.getElementById('capt2'),

        boul1 = document.getElementById('boul1'),

        boul2 = document.getElementById('boul2');

   

    capt1.addEventListener('click', function() {

        alert("L'événement du div vient de se déclencher.");

    }, true);

   

    capt2.addEventListener('click', function() {

        alert("L'événement du span vient de se déclencher.");

    }, true);

   

    boul1.addEventListener('click', function() {

        alert("L'événement du div vient de se déclencher.");

    }, false);

   

    boul2.addEventListener('click', function() {

        alert("L'événement du span vient de se déclencher.");

    }, false);

</script>



Et pour finir, un lien vers la spécification du W3C concernant ces phases si vous avez envie d'aller plus loin. Il est conseillé de regarder ce lien ne serait-ce que pour voir le schéma fourni qui explique bien le concept de ces phases.


Du côté de la pratique


Bien, vous savez maintenant à quoi servent ces deux phases et pourtant, même si en théorie ce système se révèle utile, en pratique vous ne vous en servirez quasiment jamais pour la simple et bonne raison que la méthode attachEvent() d'Internet Explorer ne gère que la phase de bouillonnement, ce qui explique que l'on mette généralement le dernier paramètre de addEventListener() à false.

Autre chose, les événements sans le DOM ou avec le DOM-0 ne gèrent, eux aussi, que la phase de bouillonnement.

Cela dit, ne vous en faites pas, vous n'avez pas appris ça en vain. Il est toujours bon de savoir cela, à la fois pour la connaissance globale du Javascript, mais aussi pour comprendre ce que vous faites quand vous codez.


Créé avec HelpNDoc Personal Edition: Écrire des livres électroniques ePub pour l'iPad

Site à deux balles