La modification DOM est la clé pour créer des pages âliveâ.
Ici, nous verrons comment créer de nouveaux éléments âà la voléeâ et modifier le contenu de la page existante.
Exemple : afficher un message
Démontrons en utilisant un exemple. Nous allons ajouter un message sur la page qui est plus joli que alert.
Voici à quoi cela ressemblera :
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<div class="alert">
<strong>Hi there!</strong> You've read an important message.
</div>
Câétait un exemple HTML. Créons maintenant la même div avec JavaScript (en supposant que les styles sont déjà dans le HTML ou un fichier CSS externe).
Création dâun élément
Pour créer des nÅuds DOM, il existe deux méthodes :
document.createElement(tag)-
Crée un nouveau noeud élément avec la balise donnée :
let div = document.createElement('div'); document.createTextNode(text)-
Crée un nouveau nÅud texte avec le texte donné :
let textNode = document.createTextNode('Here I am');
La plupart du temps, nous devons créer des nÅuds dâélément, tels que le div pour le message.
Création du message
La création du message div prend 3 étapes :
// 1. Create <div> element
let div = document.createElement('div');
// 2. Set its class to "alert"
div.className = "alert";
// 3. Fill it with the content
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
Nous avons créé lâélément. Mais pour le moment, ce nâest que dans une variable nommée div, pas encore dans la page. Nous ne pouvons donc pas le voir.
Méthodes dâinsertion
Pour faire apparaître la div, nous devons lâinsérer quelque part dans document. Par exemple, dans lâélément <body>, référencé par document.body.
Il existe une méthode spéciale append pour cela : document.body.append(div).
Voici le code complet :
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<script>
let div = document.createElement('div');
div.className = "alert";
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
document.body.append(div);
</script>
Ici, nous avons appelé append sur document.body, mais nous pouvons appeler la méthode append sur nâimporte quel autre élément, pour y mettre un autre élément. Par exemple, nous pouvons ajouter quelque chose à <div> en appelant div.append(anotherElement).
Voici plus de méthodes dâinsertion, elles spécifient différents endroits où insérer :
node.append(...nodes or strings)â ajouter des nÅuds ou des chaînes de caractères à la fin denode,node.prepend(...nodes or strings)â insérer des nÅuds ou des chaînes de caractères au début denode,node.before(...nodes or strings)â- insérer des nÅuds ou des chaînes de caractères avantnode,node.after(...nodes or strings)â- insérer des nÅuds ou des chaînes de caractères aprèsnode,node.replaceWith(...nodes or strings)â- remplacenodeavec les nÅuds ou chaînes de caractères donnés.
Les arguments de ces méthodes sont une liste arbitraire de nÅuds DOM à insérer ou des chaînes de texte (qui deviennent automatiquement des nÅuds de texte).
Voyons-les en action.
Voici un exemple dâutilisation de ces méthodes pour ajouter des éléments à une liste et le texte avant/après :
<ol id="ol">
<li>0</li>
<li>1</li>
<li>2</li>
</ol>
<script>
ol.before('before'); // insère la chaîne de caractères "before" avant <ol>
ol.after('after'); // insère la chaîne de caractères "after" après <ol>
let liFirst = document.createElement('li');
liFirst.innerHTML = 'prepend';
ol.prepend(liFirst); // insère liFirst au début de <ol>
let liLast = document.createElement('li');
liLast.innerHTML = 'append';
ol.append(liLast); // insère liLast à la fin de <ol>
</script>
Voici une image visuelle de ce que font les méthodes :
La liste finale sera donc :
before
<ol id="ol">
<li>prepend</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>append</li>
</ol>
after
Comme indiqué, ces méthodes peuvent insérer plusieurs nÅuds et morceaux de texte en un seul appel.
Par exemple, ici une chaîne de caractères et un élément sont insérés :
<div id="div"></div>
<script>
div.before('<p>Hello</p>', document.createElement('hr'));
</script>
Remarque: le texte est inséré âen tant que texteâ, pas âen tant que HTMLâ, avec un échappement approprié des caractères tels que <, >.
Le HTML final est donc :
<p>Hello</p>
<hr>
<div id="div"></div>
En dâautres termes, les chaînes de caractères sont insérées de manière sûre, comme le fait elem.textContent.
Ainsi, ces méthodes ne peuvent être utilisées que pour insérer des nÅuds DOM ou des morceaux de texte.
Mais que se passe-t-il si nous voulons insérer du HTML âen tant que htmlâ, avec toutes les balises et les trucs qui fonctionnent, comme elem.innerHTML le fait ?
insertAdjacentHTML/Text/Element
Pour cela, nous pouvons utiliser une autre méthode assez polyvalente : elem.insertAdjacentHTML(where, html).
Le premier paramètre est un mot de code, spécifiant où insérer par rapport à elem. Doit être lâun des suivants :
"beforebegin"â insèrehtmlimmédiatement avantelem,"afterbegin"â insèrehtmldanselem, au début,"beforeend"â insèrehtmldanselem, à la fin,"afterend"â insèrehtmlimmédiatement aprèselem.
Le second paramètre est une chaîne HTML insérée âau format HTMLâ.
Par exemple :
<div id="div"></div>
<script>
div.insertAdjacentHTML('beforebegin', '<p>Hello</p>');
div.insertAdjacentHTML('afterend', '<p>Bye</p>');
</script>
â¦Conduirait à :
<p>Hello</p>
<div id="div"></div>
<p>Bye</p>
Voilà comment nous pouvons ajouter du code HTML arbitraire à la page.
Voici lâimage des variantes dâinsertion :
Nous pouvons facilement remarquer des similitudes entre cette image et lâimage précédente. Les points dâinsertion sont en fait les mêmes, mais cette méthode insère du HTML.
La méthode a deux sÅurs :
elem.insertAdjacentText(where, text)â la même syntaxe, mais une chaîne de caractèrestextest inséréeen tant que texteau lieu de HTML,elem.insertAdjacentElement(where, elem)â la même syntaxe, mais insère un élément.
Elles existent principalement pour rendre la syntaxe âuniformeâ. En pratique, seule insertAdjacentHTML est utilisée la plupart du temps. Parce que pour les éléments et le texte, nous avons des méthodes append/prepend/before/after â elles sont plus courtes à écrire et peuvent insérer des nÅuds/morceaux de texte.
Voici donc une variante alternative pour afficher un message :
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<script>
document.body.insertAdjacentHTML("afterbegin", `<div class="alert">
<strong>Hi there!</strong> You've read an important message.
</div>`);
</script>
Suppression de noeuds
Pour supprimer un nÅud, il existe une méthode node.remove().
Faisons disparaître notre message après une seconde :
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<script>
let div = document.createElement('div');
div.className = "alert";
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
document.body.append(div);
setTimeout(() => div.remove(), 1000);
</script>
Veuillez noter : si nous voulons déplacer un élément vers un autre endroit â il nâest pas nécessaire de le supprimer de lâancien.
Toutes les méthodes dâinsertion suppriment automatiquement le nÅud de lâancien emplacement.
Par exemple, permutons les éléments :
<div id="first">First</div>
<div id="second">Second</div>
<script>
// pas besoin d'appeler remove
second.after(first); // prend #second et après insère #first
</script>
Clonage de Noeuds : cloneNode
Comment insérer un autre message similaire ?
Nous pourrions créer une fonction et y mettre le code. Mais lâalternative serait de cloner la div existant et de modifier le texte à lâintérieur (si nécessaire).
Parfois, lorsque nous avons un gros élément, cela peut être plus rapide et plus simple.
- Lâappel
elem.cloneNode(true)crée un clone âprofondâ de lâélément â avec tous les attributs et sous-éléments. Si nous appelonselem.cloneNode(false), alors le clone est fait sans éléments enfants.
Un exemple de copie du message :
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<div class="alert" id="div">
<strong>Hi there!</strong> You've read an important message.
</div>
<script>
let div2 = div.cloneNode(true); // clone the message
div2.querySelector('strong').innerHTML = 'Bye there!'; // change le clone
div.after(div2); // affiche le clone après le div existant
</script>
DocumentFragment
DocumentFragment est un nÅud DOM spécial qui sert de wrapper pour passer autour des listes de nÅuds.
Nous pouvons y ajouter dâautres nÅuds, mais lorsque nous lâinsérons quelque part, son contenu est inséré à la place.
Par exemple, getListContent ci-dessous génère un fragment avec des éléments <li>, qui sont ensuite insérés dans <ul> :
<ul id="ul"></ul>
<script>
function getListContent() {
let fragment = new DocumentFragment();
for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
fragment.append(li);
}
return fragment;
}
ul.append(getListContent()); // (*)
</script>
Veuillez noter quâà la dernière ligne (*) nous ajoutons DocumentFragment, mais il âsâadapteâ, donc la structure résultante sera :
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
DocumentFragment est rarement utilisé explicitement. Pourquoi ajouter à un type spécial de nÅud, si nous pouvons renvoyer un tableau de nÅuds à la place ? Exemple réécrit :
<ul id="ul"></ul>
<script>
function getListContent() {
let result = [];
for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
result.push(li);
}
return result;
}
ul.append(...getListContent()); // append + "..." operator = friends!
</script>
Nous mentionnons DocumentFragment principalement parce quâil y a quelques concepts dessus, comme lâélément template, que nous couvrirons beaucoup plus tard.
Méthodes dâinsertion/suppression à lâancienne
Il existe également des méthodes de manipulation du DOM âà lâancienneâ, qui existent pour des raisons historiques.
Ces méthodes viennent dâune époque très ancienne. De nos jours, il nây a aucune raison de les utiliser, depuis quâil existe des méthodes modernes, telles que append, prepend, before, after, remove, replaceWith, qui sont plus flexibles.
La seule raison pour laquelle nous listons ces méthodes ici est que vous pouvez les trouver dans de nombreux anciens scripts :
parentElem.appendChild(node)-
Appends
nodeas the last child ofparentElem.The following example adds a new
<li>to the end of<ol>:<ol id="list"> <li>0</li> <li>1</li> <li>2</li> </ol> <script> let newLi = document.createElement('li'); newLi.innerHTML = 'Hello, world!'; list.appendChild(newLi); </script> parentElem.insertBefore(node, nextSibling)-
Insère
nodeavantnextSiblingdansparentElem.Le code suivant insère un nouvel élément de liste avant le second
<li>:<ol id="list"> <li>0</li> <li>1</li> <li>2</li> </ol> <script> let newLi = document.createElement('li'); newLi.innerHTML = 'Hello, world!'; list.insertBefore(newLi, list.children[1]); </script>Pour insérer
newLicomme premier élément, nous pouvons le faire comme ceci :list.insertBefore(newLi, list.firstChild); parentElem.replaceChild(node, oldChild)-
Remplace
oldChildavecnodechez les enfants deparentElem. parentElem.removeChild(node)-
Supprime
nodedeparentElem(en supposant quenodeest son enfant).Lâexemple suivant supprime dâabord
<li>de<ol>:<ol id="list"> <li>0</li> <li>1</li> <li>2</li> </ol> <script> let li = list.firstElementChild; list.removeChild(li); </script>
Toutes ces méthodes renvoient le nÅud inséré/supprimé. En dâautres termes, parentElem.appendChild(node) renvoie node. Mais généralement, la valeur retournée nâest pas utilisée, nous exécutons simplement la méthode.
Un mot sur âdocument.writeâ
Il existe une autre méthode très ancienne pour ajouter quelque chose à une page Web : document.write.
La syntaxe :
<p>Somewhere in the page...</p>
<script>
document.write('<b>Hello from JS</b>');
</script>
<p>The end</p>
Lâappel à document.write(html) écrit le html dans la page âici et maintenantâ. La chaîne de caractères html peut être générée dynamiquement, donc câest un peu flexible. Nous pouvons utiliser JavaScript pour créer une page Web à part entière et lâécrire.
La méthode vient de lâépoque où il nây avait pas de DOM, pas de standards ⦠Des temps vraiment anciens. Il vit toujours, car il existe des scripts qui lâutilisent.
Dans les scripts modernes, nous le voyons rarement, en raison de la limitation importante suivante :
Lâappel à document.write ne fonctionne que pendant le chargement de la page.
Si nous lâappelons ensuite, le contenu du document existant est effacé.
Par exemple :
<p>After one second the contents of this page will be replaced...</p>
<script>
// document.write après 1 seconde
// cela après que la page soit chargée, donc il efface le contenu existant
setTimeout(() => document.write('<b>...By this.</b>'), 1000);
</script>
Câest donc un peu inutilisable au stade âpost chargementâ, contrairement aux autres méthodes DOM que nous avons couvertes ci-dessus.
Voilà lâinconvénient.
Il y a aussi un avantage. Techniquement, lorsque document.write est appelé pendant que le navigateur lit (âanalyseâ) le HTML entrant, et quâil écrit quelque chose, le navigateur le consomme comme sâil était initialement là , dans le texte HTML.
Cela fonctionne donc très rapidement, car il nây a aucune modification du DOM impliquée. Il écrit directement dans le texte de la page, tandis que le DOM nâest pas encore construit.
Donc, si nous devons ajouter beaucoup de texte en HTML de manière dynamique, et que nous sommes en phase de chargement de page, et que la vitesse compte, cela peut aider. Mais dans la pratique, ces exigences se rencontrent rarement. Et généralement, nous pouvons voir cette méthode dans les scripts simplement parce quâils sont anciens.
Résumé
-
Méthodes pour créer de nouveaux nÅuds :
document.createElement(tag)â crée un élément avec la balise donnée,document.createTextNode(value)â crée un nÅud texte (rarement utilisé),elem.cloneNode(deep)â clone lâélément, sideep==truetous les descendants viennent avec.
-
Insertion et suppression :
node.append(...nodes or strings)â insère dansnode, à la fin,node.prepend(...nodes or strings)â insère dansnode, au début,node.before(...nodes or strings)â- insère juste avantnode,node.after(...nodes or strings)â- insère juste aprèsnode,node.replaceWith(...nodes or strings)â- remplacenode.node.remove()â- supprime lenode.
Les chaînes de caractères texte sont insérées âsous forme de texteâ.
-
Il existe également des méthodes âold schoolâ :
parent.appendChild(node)parent.insertBefore(node, nextSibling)parent.removeChild(node)parent.replaceChild(newElem, node)
Toutes ces méthodes retournent le
node. -
Ãtant donné un peu de HTML dans
html,elem.insertAdjacentHTML(where, html)lâinsère en fonction de la valeur dewhere:"beforebegin"â insèrehtmljuste avantelem,"afterbegin"â insèrehtmldanselem, au début,"beforeend"â insèrehtmldanselem, à la fin,"afterend"â insèrehtmljuste aprèselem.
Il existe également des méthodes similaires,
elem.insertAdjacentTextetelem.insertAdjacentElement, qui insèrent des chaînes de caractères texte et des éléments, mais ils sont rarement utilisés. -
Pour ajouter du HTML Ã la page avant la fin du chargement :
document.write(html)
Une fois la page chargée, un tel appel efface le document. Surtout vu dans les anciens scripts.
Commentaires
<code>, pour plusieurs lignes â enveloppez-les avec la balise<pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepenâ¦)