jQuery texte () et nouvelles lignes

114

Je veux pouvoir dire

$(someElem).text('this\n has\n newlines);

et il est rendu avec des nouvelles lignes dans le navigateur. La seule solution de contournement que j'ai trouvée est de définir la propriété css 'white-space' sur 'pre' sur someElem. Cela fonctionne presque, mais j'ai alors un remplissage énormément grand entre le texte et le haut de someElem, même lorsque je mets le remplissage à 0. Y a-t-il un moyen de se débarrasser de cela?

Joe Armstrong
la source
2
l'envelopper avec des <pre>balises (et utiliser .html () au lieu de .text ()) est la solution la plus simple et la meilleure pour conserver les sauts de ligne à partir d'un fichier texte ou d'un texte brut à mon avis (cela est suggéré par la réponse de Karim ci-dessous). TOUTEFOIS: La nouvelle alternative à cela est d'utiliser white-space: pre-wrap;comme suggéré dans la réponse de
cleong
1
pourquoi ne pas utiliser à la append()place test()et <br/>au lieu de \n? comme ça -$(someElem).append("this <br/> has <br/> newlines");
Erfan Ahmed

Réponses:

132

C'est l'année 2015. La bonne réponse à cette question à ce stade est d'utiliser CSS white-space: pre-lineou white-space: pre-wrap. Propre et élégant. La version la plus basse d'IE qui prend en charge la paire est 8.

https://css-tricks.com/almanac/properties/w/whitespace/

PS Jusqu'à ce que CSS3 devienne courant, vous devrez probablement couper manuellement les espaces blancs initiaux et / ou de fin.

Cleong
la source
3
Cela devrait être la réponse.
Axel
3
CECI est la réponse. Devrait être plus haut. Bienvenue en 2016.
neoRiley
3
Trouvé ceci en 2017: toujours pertinent, et toujours la réponse à la question.
Troy Harris
6
Il y a une erreur dans ce post. L'année est 2017, pas 2015. Tout le reste semble exact.
JDB se souvient encore de Monica
1
new Date("2016");
Brandito
60

Si vous stockez l'objet jQuery dans une variable, vous pouvez le faire:

var obj = $("#example").text('this\n has\n newlines');
obj.html(obj.html().replace(/\n/g,'<br/>'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="example"></p>

Si vous préférez, vous pouvez également créer une fonction pour le faire avec un simple appel, tout comme le fait jQuery.text ():

$.fn.multiline = function(text){
    this.text(text);
    this.html(this.html().replace(/\n/g,'<br/>'));
    return this;
}

// Now you can do this:
$("#example").multiline('this\n has\n newlines');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="example"></p>

José Roberto Araújo Júnior
la source
Il manque une parenthèse fermée dans la deuxième ligne du premier extrait de code.
Mahmoud Fayez
1
cela répond en fait à la question des OP
Tommy
Le meilleur, a fonctionné comme un charme et a résolu le problème.
ZEESHAN ARSHAD
37

Voici ce que j'utilise:

function htmlForTextWithEmbeddedNewlines(text) {
    var htmls = [];
    var lines = text.split(/\n/);
    // The temporary <div/> is to perform HTML entity encoding reliably.
    //
    // document.createElement() is *much* faster than jQuery('<div></div>')
    // http://stackoverflow.com/questions/268490/
    //
    // You don't need jQuery but then you need to struggle with browser
    // differences in innerText/textContent yourself
    var tmpDiv = jQuery(document.createElement('div'));
    for (var i = 0 ; i < lines.length ; i++) {
        htmls.push(tmpDiv.text(lines[i]).html());
    }
    return htmls.join("<br>");
}
jQuery('#div').html(htmlForTextWithEmbeddedNewlines("hello\nworld"));
Peter V. Mørch
la source
1
En fait, il est supérieur à la suggestion de Mark car il ne risque pas d'attaque XSS.
Andrew B.
Je pense que vous pouvez créer le div (c'est-à-dire: document.createElement ('div')) à partir de la fonction et l'utiliser pour tous les appels, n'est-ce pas?
Fabio Zadrozny
@FabioZadrozny: Oui, vous avez raison! J'ai édité la réponse (presque) en conséquence. Le div est créé à l'intérieur de la fonction mais à l'extérieur de la boucle maintenant. Cela pourrait être complètement en dehors de la fonction, mais cela devient alors compliqué à utiliser.
Peter V.Mørch
1
Je crois que la réponse de @ cleong est la meilleure solution pour cela
minillinim
Si vous avez des caractères de nouvelle ligne explicites dans votre texte, vous souhaiterez peut-être diviser en utilisant text.split(/\\n/), ou même text.split(/\\\\n|\\n|\n/). J'ai rencontré cela en passant du texte au format JSON avec une API qui incorporait \ndes caractères de contrôle littéraux dans des chaînes.
D.Visser
20

Vous pouvez également essayer d'utiliser .html, puis envelopper avec des <pre>balises:

$(someElem).html('this\n has\n newlines').wrap('<pre />');
karim79
la source
13

Vous pouvez utiliser à la htmlplace de textet remplacer chaque occurrence de \npar <br>. Vous devrez cependant bien échapper votre texte.

x = x.replace(/&/g, '&amp;')
     .replace(/>/g, '&gt;')
     .replace(/</g, '&lt;')
     .replace(/\n/g, '<br>');
Mark Byers
la source
@Matthew Flaschen: Merci, corrigé.
Mark Byers
7
Certaines personnes lisant cette réponse ne sauront probablement pas à quel point cela est dangereux. N'utilisez jamais cette solution avec du texte fourni par l'utilisateur. La solution de Peter Mørch est préférable.
Andrew B.
1
La solution de @kulebyashik Peter utilise textalors que cette réponse utilise htmldirectement.
John Xiao
1

Je suggérerais de travailler someElemdirectement avec l' élément, car les remplacements par .html()remplaceraient également d'autres balises HTML dans la chaîne.

Voici ma fonction:

function nl2br(el) {
  var lines = $(el).text().split(/\n/);
  $(el).empty();
  for (var i = 0 ; i < lines.length ; i++) {
    if (i > 0) $(el).append('<br>');
    $(el).append(document.createTextNode(lines[i]));
  }
  return el;
}

Appelez-le par:

someElem = nl2br(someElem);
JochenJung
la source
1
NOTE AU LECTEUR: Cette réponse est particulièrement utile si vous prévoyez de développer un module complémentaire pour Firefox. innerHTML ou (.html () si vous utilisez jQuery) est mal vu par le W3C et Mozilla, et le code ci-dessus est très utile pour effacer le processus de révision. Pour plus d'informations, voir Considérations de sécurité @ developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
Delicia Brummitt
1

Essaye ça:

$(someElem).html('this<br> has<br> newlines);
daCoda
la source
0

L'utilisation de la propriété d'espace blanc CSS est probablement la meilleure solution. Utilisez Firebug ou Chrome Developer Tools pour identifier la source du rembourrage supplémentaire que vous voyiez.

Andrew B.
la source