La solución más fácil es simplemente diseñar el elemento en el que está insertando el texto con la siguiente propiedad CSS:
white-space: pre-wrap;
Esta propiedad hace que los espacios en blanco y las nuevas líneas dentro de los elementos coincidentes se traten de la misma manera que dentro de a <textarea>. Es decir, los espacios en blanco consecutivos no se contraen y las líneas se rompen en nuevas líneas explícitas (pero también se ajustan automáticamente si exceden el ancho del elemento).
Dado que varias de las respuestas publicadas aquí hasta ahora han sido vulnerables a la inyección de HTML (por ejemplo, porque asignan una entrada de usuario sin escape innerHTML) o tienen errores, permítanme dar un ejemplo de cómo hacer esto de manera segura y correcta, según 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;
}
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(). En el momento de escribir este artículo, esas funciones todavía se consideran experimentales y no son totalmente compatibles con todos los navegadores. Si desea estar seguro y seguir siendo compatible con navegadores más antiguos, puede sustituirlos con bastante facilidad de la siguiente manera:
element.append(otherElement)se puede reemplazar con element.appendChild(otherElement);
element.prepend(otherElement)se puede reemplazar con element.insertBefore(otherElement, element.firstChild);
element.append(stringOfText)se puede reemplazar con element.appendChild(document.createTextNode(stringOfText));
element.prepend(stringOfText)se puede reemplazar con element.insertBefore(document.createTextNode(stringOfText), element.firstChild);
- como caso especial, si
elementestá vacío, ambos element.append(stringOfText)y element.prepend(stringOfText)simplemente se pueden reemplazar con element.textContent = stringOfText.
Este es 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;
}
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 desea hacer esto sin usar la white-spacepropiedad CSS , 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 agujeros de seguridad potenciales, usted tiene que escapar primero cualquier meta HTML (como mínimo, &y <) en el texto antes de hacer esto reemplazo.
Probablemente la forma más sencilla y segura de hacerlo es dejar que el navegador maneje el escape HTML por usted, 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');
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 evitará que el renderizador HTML colapse espacios en blanco consecutivos. Es posible (más o menos) emular eso reemplazando algunos de los espacios en blanco en el texto con espacios que no se rompan, pero honestamente, eso se está volviendo bastante complicado para algo que se puede resolver trivialmente con una sola línea de CSS.