jQuery converter quebras de linha para br (equivalente em nl2br)

109

Estou fazendo jQuery pegar algum conteúdo textarea e inseri-lo em um li.

Quero reter visualmente as quebras de linha.

Deve haver uma maneira realmente simples de fazer isso ...

gbhall
fonte
Nota XSS: se você estiver fazendo isso, parece que você está misturando diretamente a entrada do usuário e <br/>, o que significa que você está exibindo novas linhas ou <br/s> e, portanto, pode estar aberto a ataques XSS , isto é, se sua entrada vier de qualquer outro usuário do site.
user420667

Respostas:

163

demonstração: http://so.devilmaycode.it/jquery-convert-line-breaks-to-br-nl2br-equivalent

function nl2br (str, is_xhtml) {   
    var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';    
    return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
}
Luca Filosofi
fonte
5
Obrigado, isso funciona perfeitamente. Estranho como essa não é uma função oficial do jQuery.
gbhall
4
porque o jQuery não se destina a substituir a função javascript nativa, como substituir, é focado no encadeamento do seletor CSS e fácil acesso! talvez na versão futura ;-)
Luca Filosofi
Impressionante. Ajudou-me a superar o problema de o IE7 não suportar espaços em branco: pre-wrap
Kevin Pauli
Essa regex não significaria que se uma linha terminar com ">", ela não adicionaria o BR? Eu sei que no meu HTML uso & gt; mas o conteúdo gerado pelo usuário não funciona tão bem com isso ...
Dave Stein
@DaveStein não, tentei fazer isso com '>' e '& gt;' e nas duas vezes as quebras de linha são adicionadas. Acho que este código de função é basicamente perfeito :)
Jake
91

você pode simplesmente fazer:

textAreaContent=textAreaContent.replace(/\n/g,"<br>");
mck89
fonte
Saúde, isso meio que funcionou, exceto que trataria várias quebras de linha como uma única quebra de linha.
gbhall
4
Eu o atualizei e agora ele usa um regexp, então se você quiser tratar várias quebras de linha como um único br, altere o regexp com: / \ n + / g
mck89
Obrigado. Esperançosamente, alguém achará sua resposta útil, mas a função abaixo também funciona. Eu me sinto meio mal por você estar fazendo mais esforço, mas uma função é mais desejável.
gbhall
se obtiver o erro "x.replace não é uma função", use x.toString (). replace
Vörös Amadea
29

Coloque isso em seu código (de preferência em uma biblioteca de funções js geral):

String.prototype.nl2br = function()
{
    return this.replace(/\n/g, "<br />");
}

Uso:

var myString = "test\ntest2";

myString.nl2br();

criar uma função de protótipo de string permite que você use isso em qualquer string.

jnl
fonte
29

No espírito de alterar a renderização em vez de alterar o conteúdo , o seguinte CSS faz com que cada nova linha se comporte como um<br> :

white-space: pre;
white-space: pre-line;

Por que duas regras: pre-lineafeta apenas novas linhas (obrigado pela dica, @KevinPauli). O IE6-7 e outros navegadores antigos voltam ao mais extremo, preque também inclui nowrape renderiza vários espaços. Detalhes sobre essas e outras configurações ( pre-wrap) em mozilla e css-tricks (obrigado @Sablefoste).

Embora eu geralmente seja avesso à predileção do SO por adivinhar a questão em vez de respondê-la, neste caso substituindo novas linhas por<br> marcação pode aumentar a vulnerabilidade a ataques de injeção com entrada de usuário não lavada. Você está cruzando uma linha vermelha brilhante sempre que está mudando as .text()ligações .html()que a pergunta literal implica que teriam que ser feitas. (Obrigado @AlexS por destacar este ponto.) Mesmo se você descartar um risco de segurança no momento, alterações futuras podem introduzi-lo inadvertidamente. Em vez disso, este CSS permite que você obtenha quebras de linha rígidas sem marcação usando o mais seguro .text().

Bob Stein
fonte
1
Dependendo do caso, esta é a solução mais simples e realmente responde melhor à pergunta. Você também pode considerar qualquer uma das outras white-space:opções, como pre-wrap. Consulte css-tricks.com/almanac/properties/w/whitespace
Sablefoste
Esta é realmente a melhor resposta - soluções de substituição de string significariam a necessidade de usar .html()para definir o conteúdo, o que, por sua vez, permitiria ao usuário inserir HTML arbitrário, a menos que você o filtrasse com antecedência.
Alex S
Bom ponto sobre o .html()perigo @AlexS, tentei incorporar.
Bob Stein
2

Solução

Use este código

jQuery.nl2br = function(varTest){
  return varTest.replace(/(\r\n|\n\r|\r|\n)/g, "<br>");
};
Ata ul Mustafa
fonte
1

Esta função JavaScript considera se deve usar inserir ou substituir para lidar com a troca.

(Insira ou substitua quebras de linha HTML)

/**
 * This function is same as PHP's nl2br() with default parameters.
 *
 * @param {string} str Input text
 * @param {boolean} replaceMode Use replace instead of insert
 * @param {boolean} isXhtml Use XHTML 
 * @return {string} Filtered text
 */
function nl2br (str, replaceMode, isXhtml) {

  var breakTag = (isXhtml) ? '<br />' : '<br>';
  var replaceStr = (replaceMode) ? '$1'+ breakTag : '$1'+ breakTag +'$2';
  return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, replaceStr);
}

Demo - JSFiddle

Funções JavaScript nl2br e br2nl

Nick Tsai
fonte
1

Eu escrevi uma pequena extensão jQuery para isso:

$.fn.nl2brText = function (sText) {
    var bReturnValue = 'undefined' == typeof sText;
    if(bReturnValue) {
        sText = $('<pre>').html(this.html().replace(/<br[^>]*>/i, '\n')).text();
    }
    var aElms = [];
    sText.split(/\r\n|\r|\n/).forEach(function(sSubstring) {
        if(aElms.length) {
            aElms.push(document.createElement('br'));
        }
        aElms.push(document.createTextNode(sSubstring));
    });
    var $aElms = $(aElms);
    if(bReturnValue) {
        return $aElms;
    }
    return this.empty().append($aElms);
};
Andreas Otto
fonte
0

para melhorar a resposta aceita de @Luca Filosofi,

se necessário, alterar a cláusula inicial desta regex para ser /([^>[\s]?\r\n]?)também ingore os casos em que a nova linha vem após uma tag E alguns espaços em branco, em vez de apenas uma tag imediatamente seguida por uma nova linha

flare
fonte
0

Outra maneira de inserir texto de uma área de texto no DOM mantendo as quebras de linha é usar a propriedade Node.innerText que representa o conteúdo de texto renderizado de um nó e seus descendentes.

Como getter, ele se aproxima do texto que o usuário obteria se destacasse o conteúdo do elemento com o cursor e, em seguida, copiasse para a área de transferência.

A propriedade se tornou padrão em 2016 e é bem suportada por navegadores modernos. Posso usar : cobertura global de 97% quando postei esta resposta.

Volo
fonte