Événements

Gestionnaire d’événement

Le navigateur déclenche des événements que l’on peut écouter lorsqu’une action se produit dans la page ou sur un élément spécifique: un clic, le passage de la souris sur l’élément, du texte écrit, un élément qui se charge, etc.

Ces événements peuvent être écoutés et gérés grâce à des gestionnaires d’événement ajoutés via la méthode addEventListener. Les versions inférieures à IE9 utilisent la méthode attachEvent.

Par exemple, pour écouter l’événement clic, déclenché lorsque l’utilisateur clique sur un élément:

element.addEventListener('click', function(){
  alert("Clic sur l'élément !");
});

Attributs on…

On peut obtenir le même résultat que addEventListener() en définissant l’attribut on + (nom de l'événement) sur l’élément. Cette manière de faire n’est pas conseillé et ne devrait être utilisée que sur les éléments inaccessibles au DOM, notamment window.
En HTML:

<p onclick="alert('Clic')">Mon contenu</p>

Ou en JavaScript:

element.onclick = function(){
   alert("Clic");
}

Diffusion des événements

Lorsqu’un événement se déclenche il se propage dans l’arborescence. Par exemple, un clic sur une image déclenchera également un clic sur le div qui l’englobe. L’ordre dans lequel l’événement est déclenché peut être choisit en passant un booléen en 3ème argument de addEventListener:

Certains événements, lorsqu’ils sont spécifiques à un seul élément, ne se propagent pas. Par exemple, l’événement load des éléments image.

Informations sur l’événement

À l’intérieur du gestionnaire d’événement, on reçoit un objet qui hérite de Event en paramètre, contenant des informations sur l’événement. Le contenu de cet objet diffère selon le type d’événement en cours. Par exemple, pour le clic:

document.addEventListener('click', function(e){
  console.log(e);
});
altKey: false
bubbles: true
button: 0
buttons: 0
cancelBubble: false
cancelable: true
clientX: 693
clientY: 460
composed: true
ctrlKey: false
currentTarget: null
defaultPrevented: false
detail: 1
eventPhase: 0
explicitOriginalTarget: <div>
isTrusted: true
layerX: 693
layerY: 6901
metaKey: false
movementX: 0
movementY: 0
mozInputSource: 1
mozPressure: 0
offsetX: 0
offsetY: 0
originalTarget: <div>
pageX: 693
pageY: 6901
rangeOffset: 0
rangeParent: null
region: ""
relatedTarget: null
screenX: 695
screenY: 580
shiftKey: false
target: <div>
timeStamp: 131834
type: "click"
view: Window https://localhost
which: 1
x: 693
y: 460

Deux valeurs sont particulièrement utiles:

À moins d’avoir définit la valeur de this avec bind(), elle est égale à currentTarget.
Plus d’infos sur les cibles des événements

Stopper la propagation

Verticale

Pour empêcher que l’événement se propage, de l’enfant aux parents ou du parent aux enfants selon le mode choisit (canceling ou bubbling), on utilise la méthode stopPropagation() de l’objet Event reçu en paramètre.

<div class="element1">
  <div class="element2 elem">Mon contenu</div>
</div>
document.querySelector(".element1").addEventListener('click', function(e){
  console.log("element1");
});

document.querySelector(".element2").addEventListener('click', function(e){
  e.stopPropagation();
  console.log("element2");
});

document.querySelector(".elem").addEventListener('click', function(e){
  console.log("elem");
});

// Affiche element2 elem

Pour IE<9, il faut définir la propriété cancelBubble à vrai et non appeler la propriété stopPropagation().

Horizontale

Pour empêcher que l’événement ne déclenche d’autres gestionnaires d’événement, pour les parents/enfants mais aussi pour l’élément en cours, on utilise la méthode stopImmediatePropagation().

<div class="element1">
  <div class="element2 elem">Mon contenu</div>
</div>
document.querySelector(".element1").addEventListener('click', function(e){
  console.log("element1");
});

document.querySelector(".element2").addEventListener('click', function(e){
  e.stopImmediatePropagation();
  console.log("element2");
});

document.querySelector(".elem").addEventListener('click', function(e){
  console.log("elem");
});

// Affiche element2

Si plusieurs gestionnaires d’événements sont définis sur un même élément, il sont appelés dans l’ordre dans lequel ils ont été ajoutés.

Bloquer l’action par défaut

La méthode preventDefault() de l’objet Event permet de bloquer l’action exécutée par défaut.

Par exemple, à l’intérieur d’un gestionnaire d’événement submit (déclenché lorsqu’un formulaire est soumis), la méthode preventDefault() empêche la soumission du formulaire vers le serveur - ce qui peut permettre par exemple d’envoyer le formulaire par AJAX au lieu de rafraichir la page.

form.addEventListener("submit", function(e){
    e.preventDefault();

    console.log(this.values);
});

Déclencher un événement

Il est possible de déclencher manuellement certains événements. Par exemple, pour déclencher un clic:

element.click()

On peut autrement créer un événement de toute pièce et le propager:

var event = new Event('submit');
element.dispatchEvent(event);

Pour un événement non valide (qui n’est pas reconnu par le navigateur), on doit créer un événement personnalisé:

var event = new CustomEvent('myevent');
element.dispatchEvent(event);