texto jQuery () e novas linhas

114

Eu quero ser capaz de dizer

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

e é renderizado com novas linhas no navegador. A única solução alternativa que encontrei é definir a propriedade css 'espaço em branco' como 'pre' em someElem. Isso quase funciona, mas eu tenho um padding irritantemente grande entre o texto e o topo de algumElem, mesmo quando eu defino o padding como 0. Existe uma maneira de me livrar disso?

Joe Armstrong
fonte
2
envolvê-lo com <pre>tags (e usar .html () em vez de .text ()) é a melhor e mais fácil solução para manter quebras de linha de um arquivo de texto ou de texto simples em minha opinião (isso é sugerido pela resposta de Karim abaixo). NO ENTANTO: A alternativa mais recente é usar white-space: pre-wrap;como sugerido na resposta de
cleong
1
por que não usar em append()vez de test()e em <br/>vez de \n? assim -$(someElem).append("this <br/> has <br/> newlines");
Erfan Ahmed

Respostas:

132

É o ano de 2015. A resposta correta para essa pergunta neste momento é usar CSS white-space: pre-lineou white-space: pre-wrap. Limpo e elegante. A versão mais baixa do IE compatível com o par é a 8.

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

PS Até que o CSS3 se torne comum, você provavelmente precisará cortar manualmente os espaços em branco iniciais e / ou finais.

Cleong
fonte
3
Esta deve ser a resposta.
Axel
3
ESTA é a resposta. Deveria ser mais alto. Bem-vindo a 2016.
neoRiley
3
Achei isso em 2017: ainda relevante, e ainda a resposta para a pergunta.
Troy Harris
6
Há um erro nesta postagem. O ano é 2017, não 2015. Todo o resto parece correto.
JDB ainda se lembra de Monica
1
new Date("2016");
Brandito
60

Se você armazenar o objeto jQuery em uma variável, poderá fazer isso:

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>

Se preferir, você também pode criar uma função para fazer isso com uma chamada simples, assim como 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
fonte
Há um parêntese de fechamento ausente na segunda linha do primeiro trecho de código.
Mahmoud Fayez
1
na verdade, isso responde à pergunta de OPs
Tommy
O melhor, funcionou perfeitamente e resolveu o problema.
ZEESHAN ARSHAD
37

Aqui está o que eu uso:

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
fonte
1
Na verdade, é superior à sugestão de Mark porque não corre o risco de um ataque XSS.
Andrew B.
Eu acho que você poderia criar o div (ou seja: document.createElement ('div')) fora da função e apenas usá-lo para todas as chamadas, certo?
Fabio Zadrozny
@FabioZadrozny: Sim, você está certo! Eu editei a resposta (quase) de acordo. O div é criado dentro da função, mas fora do loop agora. Pode estar totalmente fora da função, mas torna-se complicado de usar.
Peter V. Mørch
1
Acredito que a resposta de @cleong seja a melhor solução para isso
minillinim
Se você tiver caracteres de nova linha explícitos em seu texto, poderá dividir usando text.split(/\\n/), ou mesmo text.split(/\\\\n|\\n|\n/). Eu encontrei isso ao passar texto em formato JSON com uma API que incorporava \ncaracteres de controle literais em strings.
D. Visser
20

Como alternativa, tente usar .htmle envolver com <pre>tags:

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

Você pode usar em htmlvez de texte substituir cada ocorrência de \npor <br>. Você terá que escapar corretamente do seu texto.

x = x.replace(/&/g, '&amp;')
     .replace(/>/g, '&gt;')
     .replace(/</g, '&lt;')
     .replace(/\n/g, '<br>');
Mark Byers
fonte
@Matthew Flaschen: Obrigado, corrigido.
Mark Byers
7
É provável que algumas pessoas que estejam lendo esta resposta não saibam como isso é perigoso. Nunca use esta solução com texto fornecido pelo usuário. A solução de Peter Mørch é preferível.
Andrew B.
1
A solução de @kulebyashik Peter usa textenquanto esta resposta usa htmldiretamente.
John Xiao
1

Eu sugeriria trabalhar com o someElemelemento diretamente, como substitutos com.html() substituiriam outras tags HTML na string também.

Aqui está minha função:

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;
}

Ligue para:

someElem = nl2br(someElem);
JochenJung
fonte
1
NOTA PARA O LEITOR: Esta resposta é especialmente útil se você planeja desenvolver um complemento do Firefox. innerHTML ou (.html () se estiver usando jQuery) é desaprovado pelo W3C e pelo Mozilla, e o código acima é muito útil para limpar o processo de revisão. Para obter mais informações, consulte Considerações de segurança em @ developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
Delicia Brummitt
1

Experimente isto:

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

Usar a propriedade de espaço em branco do CSS é provavelmente a melhor solução. Use o Firebug ou as Ferramentas do desenvolvedor do Chrome para identificar a origem do preenchimento extra que você estava vendo.

Andrew B.
fonte