jQuery text () y nuevas líneas

114

Quiero poder decir

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

y se renderiza con nuevas líneas en el navegador. La única solución que he encontrado es establecer la propiedad css 'espacio en blanco' en 'pre' en someElem. Esto casi funciona, pero luego tengo un relleno molestamente grande entre el texto y la parte superior de someElem, incluso cuando configuro el relleno en 0. ¿Hay alguna manera de deshacerme de esto?

Joe Armstrong
fuente
2
envolverlo con <pre>etiquetas (y usar .html () en lugar de .text ()) es la solución más fácil y mejor para mantener los saltos de línea de un archivo de texto o de texto sin formato en mi opinión (esto se sugiere en la respuesta de Karim a continuación). SIN EMBARGO: La alternativa más nueva a esto es usar white-space: pre-wrap;como se sugiere en la respuesta de
cleong
1
¿por qué no usar en append()lugar de test()y en <br/>lugar de \n? así -$(someElem).append("this <br/> has <br/> newlines");
Erfan Ahmed

Respuestas:

132

Es el año 2015. La respuesta correcta a esta pregunta en este momento es usar CSS white-space: pre-lineo white-space: pre-wrap. Limpio y elegante. La versión más baja de IE que admite el par es 8.

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

PD Hasta que CSS3 se vuelva común , probablemente necesitará recortar manualmente los espacios en blanco iniciales y / o finales.

Cleong
fuente
3
Esta debería ser la respuesta.
Axel
3
Esta es la respuesta. Deberia ser mas alto. Bienvenido a 2016.
neoRiley
3
Encontré esto en 2017: sigue siendo relevante y sigue siendo la respuesta a la pregunta.
Troy Harris
6
Hay un error en esta publicación. El año es 2017, no 2015. Todo lo demás parece correcto.
JDB todavía recuerda a Monica
1
new Date("2016");
Brandito
60

Si almacena el objeto jQuery en una variable, puede hacer esto:

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 lo prefiere, también puede crear una función para hacer esto con una simple llamada, como lo hace 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
fuente
Falta un paréntesis cerrado en la segunda línea del primer fragmento de código.
Mahmoud Fayez
1
esto en realidad responde a la pregunta de OP
Tommy
El mejor, funcionó como un encanto y resolvió el problema.
ZEESHAN ARSHAD
37

Esto es lo que 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
fuente
1
De hecho, es superior a la sugerencia de Mark porque no corre el riesgo de un ataque XSS.
Andrew B.
Creo que podrías crear el div (es decir: document.createElement ('div')) fuera de la función y usarlo para todas las llamadas, ¿verdad?
Fabio Zadrozny
@FabioZadrozny: ¡Sí, tienes razón! He editado la respuesta (casi) en consecuencia. El div se crea dentro de la función pero ahora fuera del bucle. Podría estar completamente fuera de la función, pero luego se vuelve complicado de usar.
Peter V. Mørch
1
Creo que la respuesta de @ cleong es la mejor solución para esto
minillinim
Si tiene caracteres de nueva línea explícitos en su texto, es posible que desee dividir usando text.split(/\\n/), o incluso text.split(/\\\\n|\\n|\n/). Encontré esto al pasar texto en formato JSON con una API que incrustaba \ncaracteres de control literal en cadenas.
D. Visser
20

Alternativamente, intente usar .htmly luego envuelva con <pre>etiquetas:

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

Puede usar en htmllugar de texty reemplazar cada aparición de \ncon <br>. Sin embargo, tendrá que escapar correctamente de su texto.

x = x.replace(/&/g, '&amp;')
     .replace(/>/g, '&gt;')
     .replace(/</g, '&lt;')
     .replace(/\n/g, '<br>');
Mark Byers
fuente
@Matthew Flaschen: Gracias, arreglado.
Mark Byers
7
Es probable que algunas personas que lean esta respuesta no sepan lo peligroso que es. Nunca use esta solución con texto proporcionado por el usuario. Es preferible la solución de Peter Mørch.
Andrew B.
1
El uso de la solución de @kulebyashik Peter textmientras que esta respuesta usa htmldirectamente.
John Xiao
1

Sugeriría trabajar con el someElemelemento directamente, ya que los reemplazos con .html()reemplazarían también otras etiquetas HTML dentro de la cadena.

Aquí está mi función:

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

Llámalo por:

someElem = nl2br(someElem);
JochenJung
fuente
1
NOTA PARA EL LECTOR: Esta respuesta es especialmente útil si planea desarrollar un complemento de Firefox. innerHTML o (.html () si se usa jQuery) está mal visto por el W3C y Mozilla, y el código anterior es muy útil para aclarar el proceso de revisión. Para obtener más información, consulte Consideraciones de seguridad @ developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
Delicia Brummitt
1

Prueba esto:

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

Usar la propiedad de espacio en blanco de CSS es probablemente la mejor solución. Utilice Firebug o Chrome Developer Tools para identificar la fuente del relleno adicional que estaba viendo.

Andrew B.
fuente