html解析器在dom构建阶段即合并空白:所有连续空白字符( 、 、 、空格等)统一转为单个u+0020空格并压缩,该过程不可逆;textcontent返回的是已压缩结果,仅、等特殊标签内保留原始空白。

HTML解析器在DOM构建阶段就合并了所有空白
浏览器解析HTML时,
、 、
、连续空格等都会被统一转成单个U+0020空格,并压缩掉多余部分——这个过程发生在DOM树生成之前,不可逆。你用JavaScript读到的textContent或innerText已经是压缩后的结果,不是原始源码。
这意味着:<p>Hello
World</p> 解析后,textContent 是 "Hello World",不是 "Hello
World"。如果你依赖原始换行做文本提取或格式还原,必须在解析前处理源码,而不是等DOM建好再操作。
-
<pre class="brush:php;toolbar:false;"></pre>、<textarea></textarea>、<script></script>、<style></style>内部不参与该合并,空白保留 - 标签之间的空白(如
<div> <p>A</p> </div>)通常不会生成文本节点,DOM里根本不存在 - 属性值中的换行(如
@@##@@)会被当作空格解析,但不影响实际取值
用get_text()提取文本时,换行控制靠参数和标签类型
像BeautifulSoup这类解析库的get_text()方法,默认把所有空白压成一个空格,且忽略<br>、<p></p>等语义换行。要让输出带可读段落,得手动干预。
关键参数:separator 控制子节点间连接符,strip 决定是否修剪首尾空白,types 可限制只取特定标签文本。
- 对
<p></p>或<h2></h2>这类块级元素,建议在调用get_text()前先遍历其子节点,遇到<br>就插入" ",遇到<p></p>就前后加" " -
<pre class="brush:php;toolbar:false;"></pre>内容必须单独提取,不能走通用get_text()流程,否则换行和缩进全丢 - 若传入
separator=' ',内联元素(如<span></span>)之间也会强行换行,容易破坏语义,慎用
正则替换HTML空白极易破坏内容结构
直接用preg_replace('/\s+/', ' ', $html)或str.replace(/s+/g, ' ')清理HTML源码,是常见但高危操作。它不识别标签边界,会误伤关键位置。
- 删掉
<pre class="brush:php;toolbar:false;">console.log("a b");</pre>里的,JS代码直接变console.log("a b"),逻辑错误 - 把
value=" x "里的空格压成一个,虽多数情况无感,但若后端校验严格或data-*属性含空格分隔值,就会出问题 - 匹配
<p> </p>时没考虑嵌套,可能连带删掉<img src="a.jpg">旁边的换行,影响CSSdisplay: inline-block的布局逻辑
white-space只影响渲染,改不了DOM中已压缩的文本
CSS的white-space是在渲染阶段起作用,它不能恢复DOM里已被解析器吃掉的换行和空格。比如设了white-space: pre-line,但源文本本身没
,页面照样不换行。
真正起效的前提是:文本内容里得有原始换行符。这通常出现在三种情况:<pre class="brush:php;toolbar:false;"></pre>内部、JS动态写入textContent或innerHTML、服务端模板拼接时保留了
。
-
white-space: pre-wrap是最安全的“兼顾格式与自适应”的选择:保留换行和空格,又允许自动折行 -
white-space: pre会禁用自动换行,长内容可能横向溢出容器,需配合overflow-wrap: break-word - 别指望用CSS把
<p>第一行第二行</p>变成两行——没有也没有<br>,它永远是一行
解析引擎对换行和空格的处理,核心分歧不在“怎么显示”,而在“什么时候压缩”。DOM构建阶段那一次不可逆的合并,决定了后续所有操作的起点——绕过它,就只能在解析前或渲染后找补。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











