最简单的解决方案是使用以下CSS属性简单地设置要插入文本的元素的样式:
white-space: pre-wrap;
此属性导致匹配元素内的空白和换行符与内的处理方式相同<textarea>
。也就是说,连续的空格不会折叠,并且在显式的换行符处折断了行(但如果行超出了元素的宽度,也将自动换行)。
鉴于到目前为止,此处发布的几个答案都容易受到HTML注入的影响(例如,因为它们将未转义的用户输入分配给innerHTML
)或其他错误,让我基于您的原始代码给出一个如何安全正确地执行此操作的示例:
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>
请注意,就像您的原始代码一样,上面的代码段使用append()
和prepend()
。在撰写本文时,这些功能仍被认为是实验性的,并非所有浏览器都完全支持。如果您想安全并保持与旧版浏览器的兼容性,可以按如下所示轻松替换它们:
element.append(otherElement)
可以替换为element.appendChild(otherElement)
;
element.prepend(otherElement)
可以替换为element.insertBefore(otherElement, element.firstChild)
;
element.append(stringOfText)
可以替换为element.appendChild(document.createTextNode(stringOfText))
;
element.prepend(stringOfText)
可以替换为element.insertBefore(document.createTextNode(stringOfText), element.firstChild)
;
- 在特殊情况下,如果
element
为空,则可以将element.append(stringOfText)
和element.prepend(stringOfText)
都替换为element.textContent = stringOfText
。
这是与上述相同的代码段,但没有使用append()
或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>
附言 如果您确实想在不使用CSSwhite-space
属性的情况下执行此操作,则另一种解决方案是用<br>
HTML标签显式替换文本中的所有换行符。棘手的部分是,为了避免引入细微的错误和潜在的安全漏洞,在执行此替换操作之前,必须首先转义文本中的所有HTML元字符(至少为&
和<
)。
可能最简单,最安全的方法是让浏览器为您处理HTML转义,例如:
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>
请注意,尽管这将解决换行符问题,但不会阻止连续的空格被HTML渲染器折叠。可以通过用不间断的空格替换文本中的某些空格来模拟这种情况,但是老实说,对于那些可以用单行CSS轻松解决的问题来说,它变得相当复杂。