jQuery convierte saltos de línea a br (equivalente a nl2br)

109

Estoy haciendo que jQuery tome un contenido de área de texto y lo inserte en un li.

Quiero que conserve visualmente los saltos de línea.

Debe haber una forma realmente sencilla de hacer esto ...

gbhall
fuente
Nota XSS: si está haciendo esto, parece que está mezclando directamente la entrada del usuario y la <br/>, lo que significa que está mostrando nuevas líneas o <br/s> y, por lo tanto, puede estar abierto al ataque XSS , es decir, si su entrada proviene de cualquier otro usuario del sitio.
user420667

Respuestas:

163

demostración: 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
fuente
5
Gracias, esto funciona perfectamente. Es curioso cómo esta no es una función oficial de jQuery.
gbhall
4
porque jQuery no está destinado a reemplazar la función nativa de JavaScript como reemplazar, se centra en el encadenamiento de selectores CSS y el fácil acceso. quizás en una versión futura ;-)
Luca Filosofi
Increíble. Me ayudó a superar el problema de que IE7 no admite espacios en blanco: preenvío
Kevin Pauli
¿No significaría esa expresión regular que si una línea termina con ">" no agregaría el BR? Sé que en mi HTML utilizo & gt; pero el contenido generado por el usuario no funciona tan bien con eso ...
Dave Stein
@DaveStein no, he probado esto con '>' y '& gt;' y en ambas ocasiones se agregan los saltos de línea. Creo que este código de función es básicamente perfecto :)
Jake
91

simplemente puedes hacer:

textAreaContent=textAreaContent.replace(/\n/g,"<br>");
mck89
fuente
Saludos, esto funcionó, excepto que trataría múltiples saltos de línea como un solo salto de línea.
gbhall
4
Lo actualicé y ahora usa una expresión regular, por lo que si desea tratar varios saltos de línea como un solo br, cambie la
expresión regular
Gracias. Con suerte, alguien encontrará útil su respuesta, pero la función a continuación también funciona. Me siento un poco mal porque estás haciendo más esfuerzo, pero una función es más deseable.
gbhall
si obtiene el error "x.replace no es una función", utilice x.toString (). replace
Vörös Amadea
29

Ponga esto en su código (preferiblemente en una biblioteca de funciones js general):

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

Uso:

var myString = "test\ntest2";

myString.nl2br();

La creación de una función de prototipo de cadena le permite utilizarla en cualquier cadena.

jnl
fuente
29

Con el espíritu de cambiar la representación en lugar de cambiar el contenido , el siguiente CSS hace que cada nueva línea se comporte como<br> :

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

Por qué dos reglas: pre-linesolo afecta a las nuevas líneas (gracias por la pista, @KevinPauli). IE6-7 y otros navegadores antiguos recurren a los más extremos, preque también incluyen nowrapy renderizan múltiples espacios. Detalles sobre estas y otras configuraciones ( pre-wrap) en mozilla y css-tricks (gracias @Sablefoste).

Si bien en general soy reacio a la predilección de SO por adivinar la pregunta en lugar de responderla, en este caso, reemplazar las líneas nuevas con <br>marcas puede aumentar la vulnerabilidad al ataque de inyección con la entrada sin lavar del usuario. Está cruzando una línea roja brillante cada vez que se encuentra cambiando las .text()llamadas a las .html()que la pregunta literal implica que debería hacerse. (Gracias @AlexS por destacar este punto). Incluso si descarta un riesgo de seguridad en ese momento, los cambios futuros podrían introducirlo sin saberlo. En cambio, este CSS le permite obtener saltos de línea duros sin marcado utilizando el más seguro .text().

Bob Stein
fuente
1
Dependiendo del caso, esta es la solución más simple y realmente responde mejor a la pregunta. También puede considerar cualquiera de las otras white-space:opciones, como pre-wrap. Ver css-tricks.com/almanac/properties/w/whitespace
Sablefoste
Esta es realmente la mejor respuesta: las soluciones de reemplazo de cadenas significarían la necesidad de usar .html()para configurar el contenido, lo que a su vez permitiría al usuario insertar HTML arbitrario a menos que lo filtre por adelantado.
Alex S
Buen punto sobre el .html()peligro @AlexS, trató de incorporar.
Bob Stein
2

Solución

Usa este código

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

Esta función de JavaScript considera si usar insertar o reemplazar para manejar el intercambio.

(Insertar o reemplazar saltos de línea 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);
}

Demostración - JSFiddle

Funciones JavaScript nl2br y br2nl

Nick Tsai
fuente
1

Escribí una pequeña extensión de jQuery para esto:

$.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
fuente
0

para mejorar la respuesta aceptada de @Luca Filosofi,

si es necesario, cambiar la cláusula inicial de esta expresión regular para que sea /([^>[\s]?\r\n]?)también ignorará los casos en los que la nueva línea viene después de una etiqueta Y algunos espacios en blanco, en lugar de solo una etiqueta seguida inmediatamente por una nueva línea

phlare
fuente
0

Otra forma de insertar texto de un área de texto en el DOM manteniendo los saltos de línea es usar la propiedad Node.innerText que representa el contenido de texto renderizado de un nodo y sus descendientes.

Como captador, se aproxima al texto que obtendría el usuario si resaltara el contenido del elemento con el cursor y luego lo copiara en el portapapeles.

La propiedad se convirtió en estándar en 2016 y es compatible con los navegadores modernos. ¿Puedo usar : cobertura global del 97% cuando publiqué esta respuesta?

Volo
fuente