innerHTML vs textContent
innerHTML lit et définit le code HTML d’un élément en l’analysant pour créer de nouveaux éléments, tandis que textContent lit et définit du texte brut, sans balises.
Comparaison point par point
#Ce qu’elle renvoie à la lecture
- Element.innerHTML
- Le code HTML du contenu comme chaîne, avec les balises
- Node.textContent
- Le texte brut du contenu et de ses descendants, sans balises
Affectation d’une chaîne avec des balises
- Element.innerHTML
- En crée de vrais éléments HTML
- Node.textContent
- Affiche les balises comme du texte brut
Sécurité avec des données venant de l’utilisateur
- Element.innerHTML
- Risque d’attaque XSS, les données doivent être nettoyées
- Node.textContent
- Sûr, le texte ne devient jamais une balise
Performance
- Element.innerHTML
- Plus lent, nécessite d’analyser le HTML
- Node.textContent
- Plus rapide, sans analyse des balises
Impact sur les éléments descendants existants
- Element.innerHTML
- Les détruit avec leurs gestionnaires d’événements
- Node.textContent
- Les détruit avec leurs gestionnaires d’événements
Usage typique
- Element.innerHTML
- Insertion d’un fragment HTML plus grand et connu à l’avance
- Node.textContent
- Affichage de texte quelconque, y compris venant de l’utilisateur
Exemple
#const box = document.querySelector('#box')
console.log(box.innerHTML)
console.log(box.textContent)
box.textContent = 'Toutes les tâches sont faites'
console.log(box.innerHTML)Définition et utilisation
#Les deux propriétés lisent et remplacent le contenu d’un élément, et affecter une nouvelle valeur supprime toujours les enfants existants. Ce qui les distingue, c’est la façon dont elles traitent la chaîne. innerHTML renvoie les balises HTML comme du texte et analyse la chaîne affectée comme du HTML, en créant de vrais éléments. textContent renvoie seulement le texte de l’élément et de ses descendants, et insère la chaîne affectée littéralement, comme un seul nœud de texte.
Cette différence entraîne un risque. Insérer avec innerHTML une chaîne venant de l’utilisateur ou d’une API ouvre la voie à une attaque XSS, car les caractères < et > se transforment en balises actives. textContent est sûr : les mêmes caractères apparaîtront à l’écran comme du texte. innerHTML est aussi plus lent, car il nécessite d’analyser le HTML, et il détruit les gestionnaires d’événements attachés aux anciens éléments à chaque affectation.
Pour afficher du texte, surtout des données venant de l’utilisateur, utilisez textContent. Réservez innerHTML à l’insertion de fragments HTML plus grands et connus à l’avance, par exemple une liste construite dans un template literal, en pensant à nettoyer chaque valeur venant de l’utilisateur.
Syntaxe
#const html = element.innerHTML
element.innerHTML = htmlString
const text = element.textContent
element.textContent = newTextPlus d’exemples
#const list = document.querySelector('#list')
const firstItem = document.querySelector('#first')
list.innerHTML += '<li>Étape suivante</li>'
console.log(document.querySelector('#first') === firstItem)
console.log(firstItem.isConnected)innerHTML += lit tout le code HTML, y ajoute le nouveau fragment et analyse tout à nouveau. Le nouvel élément #first a la même apparence, mais c’est un objet différent, et l’ancien est détaché du document.
const comment = document.querySelector('#comment')
comment.textContent = 'Utilisez <strong> pour mettre le texte en gras'
console.log(comment.children.length)
console.log(comment.textContent)La chaîne arrive dans l’élément littéralement, comme un seul nœud de texte. Les caractères < et > ne créent pas de balise, donc children.length reste égal à 0.
Bonnes pratiques
#- Pour afficher du texte venant de l’utilisateur, utilisez toujours
textContent.innerHTMLavec des données non nettoyées est une porte ouverte à une attaque XSS. - Évitez
innerHTML +=dans une boucle : chaque étape reconstruit tout le contenu depuis le début. Construisez d’abord la chaîne entière, ou utilisezinsertAdjacentHTML(). - Pour vider un élément,
element.textContent = ""suffit, sans risque lié à l’analyse du HTML.
Entrées associées
#- Element.innerHTMLLit ou remplace le contenu d’un élément sous forme de code HTML.
- Node.textContentLit ou définit tout le texte d’un élément, sans les balises HTML.
- document.querySelector()Renvoie le premier élément qui correspond à un sélecteur CSS, ou null si rien ne correspond.
- document.createElement()Crée un nouvel élément HTML avec le nom de balise donné, prêt à être inséré dans la page.
Vous voyez une erreur ou il manque un exemple ? Écrivez-nous.