L’essentiel du DOM pour les frameworks JavaScript

Dans les frameworks comme Angular ou React, vous ne manipulerez jamais le Document Object Model (DOM) directement : vous utiliserez leurs propres systèmes de templating, afin que le framework puisse s’occuper du data binding et d’optimiser les performances.

Mais ces systèmes de templating sont calqués sur le DOM natif. Cela aide donc d’avoir de bons fondamentaux, pour savoir ce qu’il est possible de faire et comprendre ce qu’il se passe.

Vous trouverez d’autres guides et une explication plus générale ici, notamment les essentiels HTML5 CSS3 pour JavaScript que vous devriez lire en premier, étant donné que le DOM consiste à manipuler du HTML et du CSS.

Sélection DOM

La plupart du temps, vous sélectionnerez un élément unique. C’est la solution la plus efficace.


let someElement = document.getElementById('some-id');

view raw

selection.js

hosted with ❤ by GitHub

Pour des sélections multiples ou complexes, vous pouvez utiliser les sélecteurs CSS que vous devriez déjà connaître. Ensuite, vous devrez faire une itération sur chaque élément.


let someElements = document.querySelectorAll('#nav-list>li');
for (let element of someElements) {}

view raw

list.js

hosted with ❤ by GitHub

Parfois vous vous trouverez déjà quelque part dans le DOM, et vous aurez besoin de continuer à naviguer, en remontant ou descendant l’arborescence. N’utilisez pas childNodes, firstChild et lastChild, ils vous causeront des problèmes.


someElement.parentNode;
someElement.children[0];

view raw

tree.js

hosted with ❤ by GitHub

Contenu DOM : manipulation du HTML

La principal chose que vous ferez sera de lire ou modifier le contenu d’un élément. Vous pouvez le changer en tant que texte brut (quand c’est possible, c’est mieux pour les performances et la sécurité) ou comme du contenu HTML.


someElement.textContent; /* Read */
someElement.textContent = `New content`; /* Write */
someElement.innerHTML; /* Read */
someElement.innerHTML = `New content`; /* Write */

view raw

content.js

hosted with ❤ by GitHub

Les éléments DOM sont des objets, leurs attributs sont donc simplement des propriétés en JavaScript, et vous pouvez y accéder directement. Par exemple :


someInputElement.value; /* Read */
someInputElement.value = `New value`; /* Write */

view raw

properties.js

hosted with ❤ by GitHub

En HTML5, vous pouvez stocker des données dans vos propres attributs personnalisés. Ils doivent commencer par data- et JavaScript possède une propriété spéciale pour y accéder. Soyez vigilants avec la différence de convention de nommage.


<p data-custom-name="Some value"></p>

view raw

data.html

hosted with ❤ by GitHub


myParagraphElement.dataset.customName; /* Read */
myParagraphElement.dataset.customName = `New value`; /* Write */

view raw

data.js

hosted with ❤ by GitHub

Styles DOM : manipulation du CSS

La façon la plus directe de modifier le CSS est d’accéder à la propriété style. Soyez vigilants avec la différence de convention de nommage. C’est une solution correcte pour une modification fonctionnelle (par exemple pour déplacer un élément), mais ne faites jamais ça pour une modification graphique : le graphisme est le rôle du CSS.


someElement.style.marginLeft = '100px';

view raw

style.css

hosted with ❤ by GitHub

Pour le graphisme, manipulez les classes. N’utilisez pas class (cela n’existe pas, c’est un mot réservé pour une autre fonctionnalité) ni className qui écraserait les potentielles autres classes déjà présentes.


someElement.classList.add('color-main');
someElement.classList.remove('color-main');
someElement.classList.toggle('color-main');
someElement.classList.contains('color-main');

view raw

classes.js

hosted with ❤ by GitHub

Notez que nous n’avons pas tenté de lire les styles actuels. Ce n’est pas judicieux, sauf pour quelques propriétés spéciales : offsetWidth, offsetHeightoffsetTop, offsetLeft.

Animations DOM

La solution simple : les transitions CSS3, associées à l’événement transitionend pour savoir quand la transition est terminée. Un standard Web Animations est en train d’arriver en JavaScript.


element.style.transition = 'margin-left 2s';
element.addEventListener('transitionend', (event) => { /* Animation finished */ });
element.style.marginLeft = '100px';

view raw

transition.js

hosted with ❤ by GitHub

Parfois vous aurez besoin de gérer une partie des animations manuellement, avec des décomptesUtilisez la nouvelle syntaxe ES6 des arrow functions, ou vous rencontrerez des problèmes. Les temps s’expriment toujours en millisecondes en JavaScript.


let differed = setTimeout(() => {
// Do something
}, 2000);

view raw

timer.js

hosted with ❤ by GitHub

Si nécessaire, vous pouvez arrêter un décompte avec clearTimeout(differed).

Notez que ce code est asynchrone, comme presque tout en JavaScript. Cela signifie que le JS n’attend pas 2 secondes pour continuer le script. Faites donc attention à l’emplacement de votre instruction suivante.

Evénements DOM

N’utilisez pas les vieilles propriétés comme onclickonmouseover, etc., qui ne permettent qu’un seul listener à la fois. Et en JavaScript natif, ne faites jamais d’événements en ligne dans le HTML, cela peut être interdit par une nouvelle option de sécurité en HTML5, Content Security Policy (les frameworks vous autoriserons à faire cela mais seulement car cela fait partie de leur système de templating, et donc que le code est ensuite transformé de façon sécurisée).


someElement.addEventListener('click', (event) => {
// Do something
});

view raw

event.js

hosted with ❤ by GitHub

Les principaux événements sont : click, mouseentermouseleave, input, keyupsubmit, focus, blur. Vous n’avez pas besoin des événements tactiles en situation classique, toucher un lien déclenche aussi automatiquement l’événement click.

Soyez conscients que toute manipulation du DOM n’est possible que si les éléments ont été chargés. Vous devriez donc toujours attendre que le DOM soit prêt. N’utilisez pas l’événement load, étant donné qu’il attend le chargement complet de toutes les ressources, ce qui est bien trop tard. Soyez vigilants avec la casse du nom de l’événement.


document.addEventListener('DOMContentLoaded', (event) => {
// Launch your features
});

view raw

domloaded.js

hosted with ❤ by GitHub

Vous recevrez un objet event en paramètre, avec des informations qui dépendent de ce qui est en train de se passer (la position de la souris, la touche de clavier pressée, etc.). Vous saurez toujours de quel élément est parti l’événement avec :


someElement.addEventListener('click', (event) => {
event.target;
});

view raw

event.js

hosted with ❤ by GitHub

Et le plus important pour la fin : vous pouvez annuler le comportement par défaut d’un événement. Par exemple, empêcher un clic sur un lien de rediriger vers la page cible. C’est très important pour 2 raisons : sur un site web classique, les fonctionnalités essentielles (comme la navigation) doivent garder des comportements par défaut qui ne nécessitent pas JavaScript pour fonctionner, pour de nombreux cas (le référencement, l’accessibilité, un bas débit, si le serveur est surchargé, s’il y a un bug que vous n’avez pas anticipé, etc.) ; et dans une application, la page ne doit jamais être rechargée.


someElement.addEventListener('click', (event) => {
event.preventDefault();
});

view raw

event.js

hosted with ❤ by GitHub

Requêtes HTTP(S) : AJAX

Une nouvelle API permet de simplifier les requêtes HTTP(S). Première étape : formatter le résultat, puis vous pouvez ensuite l’utiliser.


/* Get HTML content */
fetch('/api')
.then((response) => response.text())
.then((responseText) => {});
/* Get JSON data */
fetch('/api')
.then((response) => response.json())
.then((responseJson) => {});
/* Post */
fetch('/api', { method: 'post' });

view raw

fetch.js

hosted with ❤ by GitHub

Elle repose sur les Promises, une nouveauté importante de l’ES6, qui permettent de simplifier l’asynchronicité, avec une syntaxe linéaire, qui reste dans l’ordre de ce qui se produit, et sans imbrication infernale de callbacks.

Revenir au sommaire des guides JavaScript