Accueil

Traduction

Tutoriel sur Javascript

Recherche dans ce tuto

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Manipuler le DOM avec JavaScript

Deux chapitres de ce tuto sont consacrés à la modification du DOM initial via un script.
Dans ce premier chapitre on verra comment récupérer les caractéristiques d'un élément du DOM et comment les modifier (contenu, attributs, propriétés de style).
Dans le chapitre suivant on ira plus loin : insérer, supprimer, cloner, déplacer des noeuds du DOM.

le DOM

Le DOM est une interface de programmation qui nous permet de manipuler le code HTML & CSS d’une page web de façon dynamique en utilisant le langage JavaScript.
Le DOM est créé automatiquement lors du chargement d’une page web par le navigateur.
Désormais tous les navigateurs génèrent le même DOM, ce qui n'était pas le cas à l'origine (d'où l'invention du framework jQuery qui proposait un script unique valable pour tous les navigateurs.)

On peut donc manipuler désormais le DOM en JS natif (sans recourir à jQuery). C'est ce que nous faisons dans ce chapitre.

Les noeuds du DOM

Tout dans une page web doit être considéré comme un noeud ("node" en anglais).
Le document HTML est un noeud, chaque élément HTML est un noeud, les attributs des balises sont des noeuds, le texte de chaque balise est aussi un noeud.

La structure DOM d'une page

Le code d'une page

Le DOM de cette page

Le DOM de cette page va être construit comme une hiérarchie de nœuds. On peut le représenter sous forme d'un arbre.
Sachez que la page HTML est le noeud le plus haut hiérarchiquement et appelé : DOCUMENT.
Toutes les balises doubles ou simples de la page constituent des noeuds de type ELEMENT ou plus simplement des élements.

Le noeud HTML comprend deux "enfants" : HEAD et BODY. Pour ces deux "enfants" HTML est l'élément "parent".
L'élément HEAD contient à son tour deux enfants : TITLE et META. On peut dire aussi que TITLE et META ont pour "parent" HEAD.
L'élément BODY contient quatre enfants : H1 et trois balises P.

La structure DOM d'une page apparait dans l'onglet "éléments" de la console du navigateur.

Cibler un noeud de type élément

Pour manipuler en JavaScript un noeud de type élément il faut d'abord le cibler.
Il existe plusieurs méthodes pour accéder à un élément HTML mais toutes ont un point commun : elles retournent un objet !
Donc la syntaxe générique est : variable = méthode de ciblage d'un élément HTML
Après cette instruction la variable créée référence l'élément ciblé.

Méthodes de sélection d'un élément ou d'une collection d'éléments

Il faut utiliser des méthodes de l'objet document. Il faut distinguer les anciennes méthodes et les nouvelles introduites par l'API selectors de HTML5.

Pour les deux dernières méthodes, notez bien que le mot "Elements" est au pluriel puisqu'elles retournent un "array" d'éléments.

Ces deux nouvelles méthodes ont pour argument un sélecteur CSS.
Attention la première méthode retourne le premier élément correspondant au sélecteur CSS passé en paramètre. alors que la deuxième méthode retourne un "array".

La méthode querySelector()

La méthode querySelectorAll()

Si vous voulez cibler la troisième balise P de la page et que cet élément n'a ni l'attribut ID ni l'attribut class comment faire ?
Il suffit d'écrire : document.querySelectorAll('p')[2] . En effet le premier élément du tableau a l'indice 0, le second l'indice 2, etc.

Comment cibler une collection d'éléments ?

Exemple : nous voulons cibler toutes les balises P de la page puis tous les éléments affectés de la classe "rem".

Le code HTML de la page web

Le script associé

function f1()
{
	var paragraphes = document.querySelectorAll('p'); 
	// ou paragraphes = document.getElementsByTagName('p')
	for (element of paragraphes) {element.style.color ="red"; } 
}
function f2()
{
	var remarques = document.querySelectorAll('.rem'); 
	//ou remarques = document.getElementsByClassName('rem')
	for (element of remarques) {element.style.color ="green"; } 
}

Pour cibler une collection d'éléments de la page j'utilise la méthode querySelectorAll('sélecteur CSS') de l'objet document.
Grâce à querySelectorAll() les variables paragraphes & remarques sont des tableaux ("arrays").
Un objet array (tableau) peut être parcouru par la boucle for ... of ... .
Notez aussi la syntaxe pour modifier la valeur d'une propriété CSS : élément.style.propriété = "nouvelle valeur"

Le rendu de ce document

Récupérer des informations sur les éléments

Un élément se caractérise par différents paramètres : un contenu (texte et balisage), des attributs (src, class, alt, title, style, etc.), des propriétés CSS.

La récupération d'un paramètre d'un élément est souvent un préalable à sa modification.
Un seul exemple, si vous voulez augmenter l'opacité d'une image, il faut récupérer la valeur initiale de la propriété opacity puis incrémenter cette valeur.

Récupération du contenu d'un élément (texte et balisage)

Code HTML d'un document HTML

Le script

document.querySelector('button').onclick = function()
{
	titre = document.querySelector('h3') ; 
	para = document.querySelector('p') ; 
	
	alert("Contenu et balisage du titre : " + titre.outerHTML);
	alert("Contenu et balisage interne du titre : " + titre.innerHTML);
	alert("Texte de titre  : " +  titre.textContent); 
	
	alert("Contenu et balisage du paragraphe : " + para.outerHTML); 
	alert("Contenu et balisage interne du paragraphe : " + para.innerHTML); 
	alert("Texte de paragraphe : " + para.textContent); 
	
	image = document.querySelector('img');
	alert("Attribut alt de l'image existe ? " +  image.hasAttribute('alt')); 
	alert("Attribut src de l'image existe ? " + image.hasAttribute('src')); 
	alert("Attribut title de l'image existe ? " + image.hasAttribute('title')); 
}

titre référence la première balise H1 de la page.
para référence la première (et unique) balise P de la page.
image référence l'image unique de la page.

Pour savoir si l'image dispose de certains attributs j'ai utilisé une instruction basée sur la méthode élément.hasAttribute('attribut'). Cette méthode retourne true / false.

Le rendu du code dans un Iframe

Observez bien la différence entre les propriétés outerHTML, innerHTML & textContent.

Récupération des valeurs des attributs

On veut récupérer les valeurs des différents attributs d'une image (élément IMG).

Le code du document(extraits)

Le rendu dans un Iframe

Récupération des propriétés de style d'un élément

Dans certains manuels on peut lire que pour récupérer la valeur d'une propriété CSS d'un élément on peut utiliser la syntaxe : élément.style.propriété

N'utilisez surtout pas cette syntaxe !
En effet ça fonctionne uniquement pour les propriétés CSS en ligne (valeur de l'attribut style). Donc il n'est donc pas possible de récupérer une propriété de l'élément définie au niveau d'une feuille de style (interne ou externe).

Le code HTML d'une page web

Lien vers une feuille de style externe qui formate les balises H1 et définit la classe "centre".
Pour info extrait de cette feuille de style externe :

...
img.centre {display : block ; margin : 10px auto ; width : 60%; }
...

Le script

	var image = document.querySelector('img'); 
	
	image.onclick = function() 
	{
		alert("infos sur les propriétés de l'image"); 
		alert("valeur de opacity : " + getComputedStyle(image).opacity); 
		alert("valeur de width : " + getComputedStyle(image).width); 
		alert("valeur de height : " + getComputedStyle(image).height);
		alert("valeur de display : " + getComputedStyle(image).display); 
		alert("valeur de margin : " + getComputedStyle(image).margin); 	
		alert("valeur de margin : "+ image.style.margin)
	}

Le rendu dans un Iframe de ce document

La dernière instruction ne retourne aucune information (car la propriété margin n'est pas définie en ligne) alors que l'avant dernière instruction fonctionne !
Il faut donc utiliser systématiquement la méthode getComputed(élément).propriété qui fonctionne quelque soit l'emplacement de la règle de style (feuille de style externe, feuille de style interne, en ligne).

À la question quelle largeur ? le script ne retourne pas 60% mais une largeur en pixels en fonction de la largeur de la fenêtre ; même remarque pour les marges gauche et droite.

Attention, pour les noms des propriétés de style, vous devez utiliser la syntaxe JavaScript. En effet en JavaScript le tiret milieu est un opérateur (soustraction) et ne peut être utilisé pour désigner une variable, une propriété, etc.
Donc pour passer du nom CSS de la propriété au nom JS, il suffit de supprimer le tiret et de remplacer la lettre qui suit par son équivalent en majuscule.

Prenons quelques exemples :

propriéténom en CSSnom en JS
couleur de fondbackground-colorbackgroundColor
bordure (méga propriété)borderborder
hauteur de ligneline-heightlineHeight
marge externe gauchemargin-leftmarginLeft

On appelle cette technique de nommage : "camelCase".

Modifier les noeuds de type élément

Vous savez donc désormais récupérer les caractéristiques d'un élément : contenu d'un élément, valeurs des attributs, valeurs des propriétés CSS.
Mais pour obtenir des pages dynamiques (dont l'apparence évolue suite à d'événements déclenchés par l'utilisateur) il faut savoir modifier les valeurs de ces paramètres, rajouter / retrancher des paramètres.

Modifier le contenu de certains éléments du DOM

Thème : Un clic sur la drapeau tricolore et la page est en français ; un clic sur l'Union Jack, alors la page est en anglais.

Code CSS & HTML du document

Les éléments H2, FIGCAPTION et P ont un contenu provisoire.

Le script

Les propriétés innerHTML et textContent sont accessibles non seulement en lecture mais aussi en écriture.
Une fonction anonyme génère la page en français et une autre génère la page en anglais.
Attention les miniatures ont respectivement les indices 1 et 2 dans la collection des images du document.
Grâce à la propriété innerHTML on peut insérer du balisage interne. Ainsi le texte de l'élément P sera en italique et la légende de la grande image est en gras italique.
On ne peut pas utiliser la propriété outerHTML en écriture.

Le rendu dans un Iframe

Modifier la valeur d'un attribut

Thème : sur beaucoup de sites les caractères que vous saisissez dans un champ "mot de passe" peuvent être affichés en cliquant sur une icône (un oeil) puis de nouveau masqué en recliquant.
Il suffit qu'un script transforme le type de l'élément INPUT correspondant : de type "password" à type "text" ou l'inverse.

Le code HTML

Une image représentant un oeil (facile à trouver sur la toile) est affichée à côté du champ de type "password".
Une légende est associée à l'image : 'afficher le mot de passe'.
Si clic sur cette image : appel d'une fonction.

Le script

function f_oeil()
{
	if (f.motdepasse.getAttribute('type')=='password') 
		{f.motdepasse.setAttribute('type','text'); }
	else
		{f.motdepasse.setAttribute('type','password'); }
}

Si le champ "motdepasse" est de type "password" alors il devient de type "text" sinon c'est l'inverse.

Le script peut être encore plus simple en utilisant la notation simplifiée pour récupérer / modifier la valeur d'un atribut.

 
function f_oeil()
{
	if (f.motdepasse.type=='password') 
		{f.motdepasse.type = 'text' }
	else
		{f.motdepasse.type ='password' }
}

Le rendu dans un Iframe

Supprimer un attribut

Avec la méthode removeAttribute() il est possible de supprimer un attribut.
La syntaxe : élément.removeAttribute('attribut').

Thématique : une page commprend plusieurs images ; un clic sur une image provoque son effacement.

Le code du document

Pas de script !

Notez l'astuce : en supprimant l'attribut SRC de l'image on efface celle-ci.
Ici programmation JS à "l'ancienne" : instructions JS comme valeur de l'attribut évènementiel. Solution tolérable puisqu'il n'y a qu'une instruction.

Le rendu dans un Iframe

Cliquez successivement sur chaque image.

Ajouter un nouvel attribut

La méthode setAttribute() permet non seulement de changer la valeur d'un attribut mais aussi de rajouter un attribut à un élément.

Le rendu dans un Iframe

Cliquez sur le bouton et aux trois questions posées, répondez successivement par "bikini", "trikini et "burkini".
Puis survolez doucement chaque image pour afficher l'infobulle.

Le code de ce document HTML

Remarquez la boule for ... of ... pour parcourir l'array images.

Modifier les propriétés de style

Ci-dessous un document HTML les images ont été chargées mais sont masquées (display : none).
En cliquant sur un bouton le visiteur les affiche ; en cliquant sur un autre bouton le visiteur les masque de nouveau.

Le rendu dans un Iframe

Le code CSS & HTML du document

Via la règle de style, les images sont masquées (display : none) par défaut.
Donc pour les démasquer il faut que la valeur de la propriété display passe à "inline" (ou "block").
Pour les masquer de nouveau la propriété display doit repasser à "none".

Le script - extrait

Je ne vous communique qu'une fonction anonyme sur les deux ; à vous de trouver le code de la seconde.

var images_page = document.querySelectorAll('img'); 
	
	// fonction pour afficher les images 
	document.querySelector('button').onclick = function()
	{
		for(image of images_page)	{ image.style.display = 'inline' ; 	}
	} 
	
	// fonction pour masquer les images 
	...

Ajouter, supprimer des classes

Pour modifier rapidement la mise en forme d'éléments, le plus simple est de jouer sur les classes : ajout / suppression / basculement d'une classe.
Basculement ("toogle" en anglais) : supprimer la classe si elle est appliquée OU ajouter si elle n'est pas appliquée.

Ci-dessous un document HTML dans un Iframe

Après avoir cliqué sur les deux boutons de commande, affichez la console du navigateur puis onglet "éléments".
Vous lisez alors que trois classes sont désormais appliquées à chaque élément IMG.

Le code CSS & HTML de ce document

La classe "base" est déjà attribuée aux images. C'est elle qui redimensionne et positionne les images.
Deux autres classes sont définies dans la feuille de style : .cadre & .ombre mais ne sont pas encore appliquées par défaut.

L'objet classList

Une version récente de JavaScript a ajouté l'objet classList qui comprend plusieurs méthodes pour manipuler les classes.

"Toggle" signifie : basculer.

Le script correspondant

Utilisons les méthodes de l'objet classList pour styliser les images.

var images = document.querySelectorAll('img'); 
// images est un 'array'
document.querySelector('button').onclick = function()
{
	for (image of images)
		{image.classList.toggle('cadre'); }
} 
document.querySelectorAll('button')[1].onclick = function()
{
	for (image of images)
		{mage.classList.toggle('ombre'); }
}

La méthode toggle() doit être priviligiée.

Aller plus loin dans la modification du DOM

Dans le chapitre suivant vous verrez que non seulement on peut modifier les caractéristiques des noeuds de type élément mais on peut insérer, cloner, supprimer, déplacer des éléments.