web-dev-qa-db-fra.com

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

Aussi bête que cela puisse paraître, je n'ai toujours pas trouvé de réponse appropriée.

Supposons que je souhaite créer dynamiquement un nouvel élément DOM et remplir son textContent/innerText Avec un littéral de chaîne JS.
La chaîne est si longue que je voudrais la scinder en trois morceaux:

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

h1.textContent = "This is a very long string and I would like to insert a carriage return HERE...
moreover, I would like to insert another carriage return HERE... 
so this text will display in a new line";

Le problème est, si j'écris

h1.textContent = "...I would like to insert a carriage return here... \n";

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

Par contre, je pourrais changer h1.innerHTML au lieu de textContent et écrire:

h1.innerHTML = "...I would like to insert a carriage return here...<br />";

Ici, le <br /> ferait l'affaire, mais cela remplacerait non seulement le contenu texte, mais tout le contenu HTML de mon h1, ce qui n'est pas tout à fait ce que je veux.

Existe-t-il un moyen simple de résoudre mon problème?
Je n'aurais pas recours à la création de plusieurs éléments de bloc simplement pour avoir le texte sur différentes lignes. 
Toute idée serait grandement appréciée. 
Merci d'avance.

45
user1236489

Je sais que cette question a posté il y a longtemps.

J'ai eu un problème similaire il y a quelques jours, passant de la valeur du service Web au format json et la plaçant dans tablecellcontentText.

Parce que la valeur est passée au format, par exemple, "text row1\r\ntext row2" et ainsi de suite.

Pour la nouvelle ligne dans textContent Vous devez utiliser \r\n et, finalement, je devais utiliser css white-space: pre-line; (le texte sera renvoyé à la ligne si nécessaire et les sauts de ligne) et tout va bien. 

Ou bien, vous pouvez utiliser uniquement white-space: pre; et le texte ne sera alors appliqué qu'aux sauts de ligne (dans ce cas, \r\n).

Ainsi, voici un exemple comment le résoudre avec un texte enveloppant uniquement sur les sauts de ligne:

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

//setting this css style solving problem with new line in textContent
h1.setAttribute('style', 'white-space: pre;');

//add \r\n in text everywhere You want for line-break (new line)
h1.textContent = "This is a very long string and I would like to insert a carriage return \r\n...";
h1.textContent += "moreover, I would like to insert another carriage return \r\n...";
h1.textContent += "so this text will display in a new line";

document.body.appendChild(h1);

74
nelek

Je suis tombé dessus il y a un moment. J'ai trouvé une bonne solution qui consiste à utiliser la représentation ASCII des retours chariot (CODE 13). JavaScript possède une fonctionnalité pratique appelée String.fromCharCode() qui génère la version sous forme de chaîne d'un code ASCII, ou plusieurs codes séparés par une virgule. Dans mon cas, je devais générer un fichier CSV à partir d'une longue chaîne et l'écrire dans une zone de texte. Je devais être capable de couper le texte de la zone de texte et de l'enregistrer dans le bloc-notes. Lorsque j'ai essayé d'utiliser la méthode <br />, celle-ci ne conservait pas les retours chariots. Cependant, l'utilisation de la méthode fromCharCode conserve les retours. Voir mon code ci-dessous:

h1.innerHTML += "...I would like to insert a carriage return here..." + String.fromCharCode(13);
h1.innerHTML += "Ant the other line here..." + String.fromCharCode(13);
h1.innerHTML += "And so on..." + String.fromCharCode(13);
h1.innerHTML += "This prints hello: " + 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: ASCII Codes

31
JBausmer

Vous pouvez utiliser des expressions régulières pour remplacer les caractères "\ n" ou "\ n\r" par "<br />".

tu as ceci:

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

h1.textContent = "This is a very long string and I would like to insert a carriage return HERE...
moreover, I would like to insert another carriage return HERE... 
so this text will display in a new line";

vous pouvez remplacer vos personnages comme ceci:

h1.innerHTML = h1.innerHTML.replace(/\n\r?/g, '<br />');

vérifiez la référence javascript pour les objets String et Regex:

http://www.w3schools.com/jsref/jsref_replace.asp

http://www.w3schools.com/jsref/jsref_obj_regexp.asp

5
Rodrigo

Vous pouvez concaténer les cordes ...

h1.innerHTML += "...I would like to insert a carriage return here...<br />";
h1.innerHTML += "Ant the other line here... <br />";
h1.innerHTML += "And so on...<br />";

jsFiddle.

4
Icarus

Utilisez element.innerHTML="some \\\\n some";.

3
martin

Aucune des solutions ci-dessus n'a fonctionné pour moi. J'essayais d'ajouter un saut de ligne et du texte supplémentaire à un élément <p>. J'utilise généralement Firefox, mais j'ai besoin de la compatibilité du navigateur. J'ai lu que seul Firefox prend en charge la propriété textContent, seul Internet Explorer prend en charge la propriété innerText, mais les deux prennent en charge la propriété innerHTML. Toutefois, ni l'ajout de <br />, ni \n ni \r\n à aucune de ces propriétés n'a entraîné une nouvelle ligne. Ce qui suit a cependant fonctionné:

<html>
<body>
<script type="text/javascript">
  function modifyParagraph() {

  var p;
  p=document.getElementById("paragraphID");
  p.appendChild(document.createElement("br"));
  p.appendChild(document.createTextNode("Additional text."));
}    
</script>

<p id="paragraphID">Original text.</p>

<input type="button" id="pbutton" value="Modify Paragraph" onClick="modifyParagraph()" />
</body>
</html>

J'ai trouvé que l'insertion de \\n fonctionnait. C'est-à-dire que vous échappez au caractère de nouvelle ligne échappé

2
Elendurwen

Le code suivant fonctionne bien (sur FireFox, IE et Chrome):

var display_out = "This is line 1" + "<br>" + "This is line 2";

document.getElementById("demo").innerHTML = display_out;
0
Apprentice

la réponse de nelek est la meilleure publiée à ce jour, mais elle repose sur la définition de la valeur css: white-space: pre, ce qui pourrait être indésirable.

J'aimerais proposer 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 approuvé 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, '<br>');

devrait être suffisant pour tous les cas raisonnables.

Si vous avez décidé que vous devriez 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, vous disposez d'un formulaire dans lequel l'utilisateur peut créer une publication. Après l'avoir publié, le texte de la publication est stocké dans votre base de données, puis ajouté aux pages chaque fois que d'autres utilisateurs visitent la page correspondante.

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

[script]alert(1);[/script]

(essayez d'imaginer que [] sont <>, apparemment, le débordement de pile ajoute du texte de manière non sécurisée!)

qui ne déclenchera pas une alerte si vous utilisez innerHTML, mais cela devrait vous donner une idée des raisons pour lesquelles l’utilisation de innerHTML peut poser problème. un utilisateur plus intelligent posterait 

[img src="invalid_src" onerror="alert(1)"]

ce qui déclencherait une alerte pour chaque autre utilisateur visitant la page. Maintenant nous avons un problème. Un utilisateur encore plus intelligent mettrait l'affichage: aucun sur ce style d'img, et le ferait poster les cookies de l'utilisateur actuel sur un site interdomaine. Félicitations, toutes vos informations de connexion utilisateur sont maintenant exposées sur Internet.

Il est donc important de comprendre que l'utilisation de innerHTML n'est pas une mauvaise chose, elle est parfaite si vous l'utilisez simplement pour créer des modèles en utilisant uniquement votre propre code de développeur approuvé. La vraie question aurait dû être "comment puis-je ajouter du texte utilisateur non approuvé qui a des lignes nouvelles dans mon document HTML".

Cela soulève une question: quelle stratégie utilisons-nous pour les nouvelles lignes? utilisons-nous des éléments [br]? [p] s ou [div] s?

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 en principe jeter cela quelque part dans votre fichier common_functions.js, puis simplement déclencher et oublier chaque fois que vous devez ajouter un utilisateur/api/etc -> du texte non approuvé (c'est-à-dire non rédigé 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 les balises d'élément dom valides, donc si vous voulez [br] newlines, passez 'br', si vous voulez chaque ligne d'un élément [p], passez 'p', etc.

0
Aqo