Pregunta ¿Cómo puedo preservar los saltos de línea cuando obtengo texto de un área de texto?


Obtengo el valor en un área de texto cuando el usuario acierta enviar. Luego tomo este valor y lo coloco en otro lugar de la página. Sin embargo, cuando hago esto, pierde caracteres de nueva línea que hacen que la salida sea bastante fea.

Aquí está el área de texto al que estoy accediendo:

<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required></textarea>

Aquí está el código JavaScript que accede a la publicación y la transcribe.

var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.append(postText);
var card = document.createElement('div');
card.append(post);
var cardStack = document.getElementById('#card-stack');
cardStack.prepend(card);

Cuando la entrada es algo así como:

Horario grupal:

Práctica martes @ 5 ° piso (8 p.m. - 11 p.m.)

Práctica del jueves en el 5 ° piso (8 p.m. - 11 p.m.)

Práctica dominical @ (9 p.m. - 12 a.m.)

El resultado es:

Horario grupal: martes de práctica @ 5 ° piso (8 p.m. - 11 p.m.) Práctica jueves @ 5 ° piso (8 p.m. - 11 p.m.) Práctica dominical @ (9 p.m. - 12 a.m.)

Entonces, ¿hay alguna forma de preservar los saltos de línea?


37
2017-11-04 07:40


origen


Respuestas:


La solución más sencilla es simplemente asignarle un estilo al elemento con el que está insertando el texto con la siguiente propiedad de CSS:

white-space: pre-wrap;

Esta propiedad hace que los espacios en blanco y las nuevas líneas dentro de los elementos coincidentes sean tratados de la misma manera que dentro de un <textarea>. Es decir, los espacios en blanco consecutivos no se colapsan y las líneas se rompen en líneas nuevas explícitas (pero también se envuelven automáticamente si exceden el ancho del elemento).

Dado que varias de las respuestas publicadas hasta ahora han sido vulnerables a Inyección de HTML (por ejemplo, porque asignan una entrada de usuario no guardada a innerHTML) o con errores, déjeme dar un ejemplo de cómo hacerlo de manera segura y correcta, en función de su código original:

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.append(postText);
  var card = document.createElement('div');
  card.append(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.prepend(card);
});
#card-stack p {
  background: #ddd;
  white-space: pre-wrap;  /* <-- THIS PRESERVES THE LINE BREAKS */
}
textarea {
  width: 100%;
}
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>


Tenga en cuenta que, al igual que su código original, el fragmento anterior usa append() y prepend(). Al escribir estas líneas, esas funciones todavía se consideran experimentales y no son totalmente compatibles con todos los navegadores. Si quiere estar seguro y seguir siendo compatible con los navegadores más antiguos, puede sustituirlos con bastante facilidad de la siguiente manera:

  • element.append(otherElement) puede ser reemplazado por element.appendChild(otherElement);
  • element.prepend(otherElement) puede ser reemplazado por element.insertBefore(otherElement, element.firstChild);
  • element.append(stringOfText) puede ser reemplazado por element.appendChild(document.createTextNode(stringOfText));
  • element.prepend(stringOfText) puede ser reemplazado por element.insertBefore(document.createTextNode(stringOfText), element.firstChild);
  • como un caso especial, si element está vacío, ambos element.append(stringOfText) y element.prepend(stringOfText) simplemente puede ser reemplazado con element.textContent = stringOfText.

Aquí está el mismo fragmento que el anterior, pero sin usar append() o prepend():

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.textContent = postText;
  var card = document.createElement('div');
  card.appendChild(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.insertBefore(card, cardStack.firstChild);
});
#card-stack p {
  background: #ddd;
  white-space: pre-wrap;  /* <-- THIS PRESERVES THE LINE BREAKS */
}
textarea {
  width: 100%;
}
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>


PD. Si realmente quieres hacer esto sin usando el CSS white-space propiedad, una solución alternativa sería reemplazar explícitamente cualquier carácter de nueva línea en el texto con <br> Etiquetas HTML La parte difícil es que, para evitar la introducción de errores sutiles y potenciales agujeros de seguridad, primero debe escapar cualquier metacaracteres HTML (como mínimo, & y <) en el texto antes de haces este reemplazo.

Probablemente, la manera más simple y segura de hacerlo es dejar que el navegador maneje el código HTML que se escapa para ti, así:

var post = document.createElement('p');
post.textContent = postText;
post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.textContent = postText;
  post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');  // <-- THIS FIXES THE LINE BREAKS
  var card = document.createElement('div');
  card.appendChild(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.insertBefore(card, cardStack.firstChild);
});
#card-stack p {
  background: #ddd;
}
textarea {
  width: 100%;
}
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>

Tenga en cuenta que, aunque esto arreglará los saltos de línea, no impedirá que los espacios consecutivos en blanco se colapsen con el renderizador HTML. Es posible (emularlo) emular eso reemplazando algunos de los espacios en blanco en el texto con espacios sin interrupciones, pero sinceramente, eso se está volviendo algo complicado para algo que se puede resolver trivialmente con una sola línea de CSS.


38
2017-11-04 15:32



El contenedor de destino debe tener el white-space:pre estilo. Pruébalo a continuación.

<script>
function copycontent(){
 var content = document.getElementById('ta').value;
 document.getElementById('target').innerText = content;
}
</script>
<textarea id='ta' rows='3'>
  line 1
  line 2
  line 3
</textarea>
<button id='btn' onclick='copycontent();'>
Copy
</button>
<p id='target' style='white-space:pre'>

</p>


17
2017-11-04 08:23



function get() {
  var arrayOfRows = document.getElementById("ta").value.split("\n");
  var docfrag = document.createDocumentFragment();
  
  var p = document.getElementById("result");
  while (p.firstChild) {
    p.removeChild(p.firstChild);
  }
  
  arrayOfRows.forEach(function(row, index, array) {
    var span = document.createElement("span");
    span.textContent = row;
    docfrag.appendChild(span);
    if(index < array.length - 1) {
      docfrag.appendChild(document.createElement("br"));
    }
  });

  p.appendChild(docfrag);
}
<textarea id="ta" rows=3></textarea><br>
<button onclick="get()">get</button>
<p id="result"></p>

Puede dividir filas textarea en matriz:

var arrayOfRows = postText.value.split("\n");

Luego úsela para generar, tal vez, más etiquetas p ...


6
2017-11-04 07:54



Usted podría establecer width de div usando Javascript y agrega white-space:pre-wrap a p tag, esto rompe el contenido de tu texto al final de cada línea.

document.querySelector("button").onclick = function gt(){
var card = document.createElement('div');
card.style.width = "160px";
card.style.background = "#eee";
var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.style.whiteSpace = "pre-wrap";
card.append(post);
post.append(postText);
document.body.append(card);
}
<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required>
Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea>
<br><br>
<button>Copy!!</button>


3
2017-11-04 09:31



Supongo que no quieres que tu contenido de texto de texto se analice como HTML. En este caso, puede configurarlo como texto sin formato para que el navegador no lo trate como HTML y no elimine las nuevas líneas. No se requiere CSS o preprocesamiento.

<script>
function copycontent(){
 var content = document.getElementById('ta').value;
 document.getElementById('target').innerText = content;
}
</script>
<textarea id='ta' rows='3'>
  line 1
  line 2
  line 3
</textarea>
<button id='btn' onclick='copycontent();'>
Copy
</button>
<p id='target'></p>


3
2017-11-04 17:21



Aquí hay una idea, ya que puede tener múltiples líneas nuevas en un cuadro de texto:

 var text=document.getElementById('post-text').value.split('\n');
 var html = text.join('<br />');

Este valor HTML conservará la nueva línea. Espero que esto ayude.


2
2017-11-04 08:13



Preguntas similares están aquí

detectar saltos de línea en una entrada de área de texto

detectar salto de línea en textarea

Puedes intentar esto:

var submit = document.getElementById('submit');

submit.addEventListener('click', function(){
var textContent = document.querySelector('textarea').value;
  
document.getElementById('output').innerHTML = textContent.replace(/\n/g, '<br/>');
  

});
<textarea cols=30 rows=10 >This is some text
this is another text

Another text again and again</textarea>
<input type='submit' id='submit'>


<p id='output'></p>

document.querySelector('textarea').value; obtendrá el contenido de texto de la textarea y textContent.replace(/\n/g, '<br/>') encontrará todo el carácter de nueva línea en el código fuente /\n/g en el contenido y reemplazarlo por html line-break <br/>.


Otra opción es usar el html  <pre> etiqueta. Vea la demostración a continuación

var submit = document.getElementById('submit');

submit.addEventListener('click', function(){

  var content = '<pre>';
  
  var textContent = document.querySelector('textarea').value;
  
  content += textContent;
  
  content += '</pre>';

  document.getElementById('output').innerHTML = content;

});
<textarea cols=30 rows=10>This is some text
this is another text

Another text again and again </textarea>
<input type='submit' id='submit'>

<div id='output'> </div>


0
2017-11-04 07:55