最简单的解决方案是使用以下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>
顺便提一句,如果你真的想做到这一点而不使用CSS的 white-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渲染器折叠连续的空白。可以通过在文本中用非断行空格替换一些空格来(有点)模拟它,但说实话,对于可以轻松解决的事情,这变得相当复杂。
getElementById
函数从哪里来?我猜你要么在别处定义了它,要么忘记加上document
了。 - trysis