102 votes

Comment puis-je insérer une nouvelle ligne ou un retour à la ligne dans element.textContent ?

Supposons que je veuille créer dynamiquement un nouvel élément DOM et remplir son texte avec un littéral de chaîne JS.
La chaîne est si longue que je voudrais la diviser en trois morceaux :

var h1 = document.createElement("h1");

h1.textContent = "Ceci est une chaîne très longue et je voudrais insérer un retour à la ligne ICI...
de plus, je voudrais insérer un autre retour à la ligne ICI... 
ainsi ce texte s'affichera sur une nouvelle ligne";

Le problème, c'est que si j'écris

h1.textContent = "...Je voudrais insérer un retour à la ligne ici... \n";

cela ne fonctionne pas, probablement parce que le navigateur considère le '\n' comme un simple texte et l'affiche en tant que tel (le \r ne fonctionne pas non plus).

En revanche, je pourrais changer h1.innerHTML au lieu du textContent et écrire :

h1.innerHTML = "...Je voudrais insérer un retour à la ligne ici...";

Ici, le
ferait le travail, mais ce faisant, cela remplacerait non seulement le contenu textuel mais tout le contenu HTML de mon h1, ce qui n'est pas tout à fait ce que je veux
.

Y a-t-il un moyen simple de résoudre mon problème?
Je ne voudrais pas créer plusieurs blocs d'éléments juste pour avoir le texte sur différentes lignes.

194voto

nelek Points 2896

Je sais que cette question a été posée il y a longtemps.

J'ai eu un problème similaire il y a quelques jours, en passant une valeur du service web au format json et en la plaçant dans une cellule de tableau contentText.

Parce que la valeur est passée au format, par exemple, "texte ligne1\r\ntexte ligne2" et ainsi de suite.

Pour un saut de ligne dans textContent, vous devez utiliser \r\n et, enfin, j'ai dû utiliser du css white-space: pre-line; (Le texte se cassera lorsque nécessaire, et lors des sauts de ligne) et tout ira bien.

Ou, vous pouvez utiliser seulement white-space: pre; et ensuite le texte se cassera seulement sur les sauts de ligne (dans ce cas, \r\n).

Donc, voici un exemple de comment le résoudre en enveloppant le texte seulement sur les sauts de ligne:

var h1 = document.createElement("h1");

// en définissant ce style css, vous résolvez le problème du saut de ligne dans textContent
h1.setAttribute('style', 'white-space: pre;');

// ajoutez \r\n dans le texte partout où vous voulez un saut de ligne (nouvelle ligne)
h1.textContent = "Ceci est une très longue chaîne et je voudrais insérer un saut de ligne \r\n...";
h1.textContent += "de plus, je voudrais insérer un autre saut de ligne \r\n...";
h1.textContent += "donc ce texte s'affichera sur une nouvelle ligne";

document.body.appendChild(h1);

32voto

JBausmer Points 818

J'ai rencontré ce problème il y a quelque temps. J'ai trouvé qu'une bonne solution était d'utiliser la représentation ASCII des retours chariots (CODE 13). JavaScript a une fonction pratique appelée String.fromCharCode() qui génère la version en chaîne de caractères d'un code ASCII, ou de plusieurs codes séparés par une virgule. Dans mon cas, j'avais besoin de générer un fichier CSV à partir d'une longue chaîne et de l'écrire dans une zone de texte. Je devais être capable de copier le texte de la zone de texte et de le sauvegarder dans le bloc-notes. Lorsque j'ai essayé d'utiliser la méthode, cela ne préservait pas les retours chariots, cependant, en utilisant la méthode fromCharCode, cela conserve les retours. Voici mon code ci-dessous :

h1.innerHTML += "...Je voudrais insérer un retour chariot ici..." + String.fromCharCode(13);
h1.innerHTML += "Et l'autre ligne ici..." + String.fromCharCode(13);
h1.innerHTML += "Et ainsi de suite..." + String.fromCharCode(13);
h1.innerHTML += "Ceci affiche bonjour : " + String.fromCharCode(72,69,76,76,79);

Voir ici pour plus de détails sur cette méthode : w3Schools-fromCharCode()

Voir ici pour les codes ASCII : Codes ASCII

12voto

Aqo Points 91

La réponse de nelek est la meilleure publiée jusqu'à présent, mais elle repose sur le réglage de la valeur css : white-space: pre, ce qui peut être indésirable.

J'aimerais offrir une solution différente, qui tente de répondre à la vraie question qui aurait dû être posée ici :

"Comment insérer du texte non fiable dans un élément DOM ?"

Si vous faites confiance au texte, pourquoi ne pas simplement utiliser innerHTML ?

domElement.innerHTML = trustedText.replace(/\r/g, '').replace(/\n/g, '');

devrait être suffisant pour tous les cas raisonnables.

Si vous avez décidé d'utiliser .textContent au lieu de .innerHTML, cela signifie que vous ne faites pas confiance au texte que vous êtes sur le point d'insérer, n'est-ce pas ? C'est une préoccupation raisonnable.

Par exemple, si vous avez un formulaire où l'utilisateur peut créer un message, et après l'avoir publié, le texte du message est stocké dans votre base de données, puis ajouté aux pages chaque fois que d'autres utilisateurs visitent la page concernée.

Si vous utilisez innerHTML ici, vous créez une faille de sécurité. c'est-à-dire, un utilisateur peut publier quelque chose comme

alert(1);

ce qui ne déclenchera pas d'alerte si vous utilisez innerHTML, mais cela devrait vous donner une idée des problèmes que l'utilisation de innerHTML peut poser. Un utilisateur plus malin pourrait publier

ce qui déclencherait une alerte pour chaque autre utilisateur qui visite la page. Maintenant, nous avons un problème. Un utilisateur encore plus malin pourrait mettre display: none sur ce style d'image, et faire en sorte qu'il envoie les cookies de l'utilisateur actuel vers un site cross-domain. Félicitations, tous les détails de connexion de vos utilisateurs sont désormais exposés sur internet.

Donc, la chose importante à comprendre est que l'utilisation de innerHTML n'est pas mauvaise, c'est parfait si vous l'utilisez simplement pour construire des modèles en n'utilisant que votre propre code de développeur de confiance. La vraie question aurait dû être "comment ajouter du texte utilisateur non fiable qui contient des sauts de ligne à mon document HTML".

Cela soulève une question : quelle stratégie utilisons-nous pour les sauts de ligne ? utilisons-nous des éléments
? des

s ou des ?

~~

Voici une courte fonction qui résout le problème :

function insertUntrustedText(domElement, untrustedText, newlineStrategy) {
    domElement.innerHTML = '';
    var lines = untrustedText.replace(/\r/g, '').split('\n');
    var linesLength = lines.length;
    if(newlineStrategy === 'br') {
        for(var i = 0; i < linesLength; i++) {
            domElement.appendChild(document.createTextNode(lines[i]));
            domElement.appendChild(document.createElement('br'));
        }
    }
    else {
        for(var i = 0; i < linesLength; i++) {
            var lineElement = document.createElement(newlineStrategy);
            lineElement.textContent = lines[i];
            domElement.appendChild(lineElement);
        }
    }
}

Vous pouvez essentiellement placer cela quelque part dans votre fichier common_functions.js et simplement l'utiliser à chaque fois que vous devez ajouter un texte non fiable d'un utilisateur/api/etc (c'est-à-dire non écrit par votre propre équipe de développeurs) à vos pages html.

exemple d'utilisation :

insertUntrustedText(document.querySelector('.myTextParent'), 'line1\nline2\r\nline3', 'br');

le paramètre newlineStrategy n'accepte que des balises d'élément dom valides, donc si vous voulez des sauts de ligne [br], passez 'br', si vous voulez que chaque ligne soit dans un élément [p], passez 'p', etc.

~~

5voto

atrgn Points 11

Changer le h1.textContent en h1.innerHTML et utiliserpour passer à la nouvelle ligne.

4voto

Icarus Points 36951

Vous pouvez concaténer les chaînes...

h1.innerHTML += "...Je voudrais insérer un saut de ligne ici...";
h1.innerHTML += "Et l'autre ligne ici... ";
h1.innerHTML += "Et ainsi de suite...";

jsFiddle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X