A solução mais fácil é simplesmente estilizar o elemento no qual você está inserindo o texto com a seguinte propriedade CSS:
white-space: pre-wrap;
Esta propriedade faz com que os espaços em branco e as novas linhas nos elementos correspondentes sejam tratados da mesma maneira que dentro de um <textarea>. Ou seja, espaços em branco consecutivos não são recolhidos e as linhas são quebradas em novas linhas explícitas (mas também são quebradas automaticamente se excederem a largura do elemento).
Dado que várias das respostas postadas aqui até agora são vulneráveis à injeção de HTML (por exemplo, porque atribuem entrada de usuário sem escape innerHTML) ou de outra forma com erros, deixe-me dar um exemplo de como fazer isso com segurança e corretamente, com base em seu 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>
Observe que, como seu código original, o snippet acima usa append()e prepend(). No momento em que este livro foi escrito, essas funções ainda são consideradas experimentais e não são totalmente compatíveis com todos os navegadores. Se você deseja estar seguro e permanecer compatível com navegadores mais antigos, pode substituí-los facilmente da seguinte maneira:
element.append(otherElement)pode ser substituído por element.appendChild(otherElement);
element.prepend(otherElement)pode ser substituído por element.insertBefore(otherElement, element.firstChild);
element.append(stringOfText)pode ser substituído por element.appendChild(document.createTextNode(stringOfText));
element.prepend(stringOfText)pode ser substituído por element.insertBefore(document.createTextNode(stringOfText), element.firstChild);
- como um caso especial, se
elementestiver vazio, ambos element.append(stringOfText)e element.prepend(stringOfText)podem ser simplesmente substituídos por element.textContent = stringOfText.
Aqui está o mesmo snippet acima, mas sem usar append()ou 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>
Ps. Se você realmente deseja fazer isso sem usar a white-spacepropriedade CSS , uma solução alternativa seria substituir explicitamente quaisquer caracteres de nova linha no texto por <br>tags HTML. A parte complicada é que, para evitar a introdução de bugs sutis e brechas de segurança em potencial, você deve primeiro escapar de quaisquer metacaracteres HTML (no mínimo, &e <) no texto antes de fazer essa substituição.
Provavelmente, a maneira mais simples e segura de fazer isso é deixar o navegador lidar com o escape de HTML para você, assim:
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>
Observe que, embora isso conserte as quebras de linha, não impedirá que espaços em branco consecutivos sejam recolhidos pelo renderizador de HTML. É possível (meio que) emular isso, substituindo alguns dos espaços em branco no texto por espaços não quebráveis, mas, honestamente, isso está ficando bastante complicado para algo que pode ser resolvido trivialmente com uma única linha de CSS.