实现思路:
1. 后端返回整篇文章。
2. JavaScript 分段处理:将文章按一定的字符或段落长度分割,然后逐步将这些段落追加到页面上。
3. 定时器或递归调用:使用 setInterval 或 setTimeout 来控制段落的逐步渲染。
代码实现示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>流体文章渲染 - 狂人日记</title>
<style>
* {
box-sizing: border-box;
}
body {
font-family: "Microsoft YaHei", Arial, sans-serif;
padding: 20px;
background-color: #f4f4f4;
}
.article-container {
width: 100%;
max-width: 600px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
}
.loading {
font-style: italic;
color: gray;
}
/* 防止自动换行,保证连续渲染的文字不强制换行 */
.no-break {
white-space: pre-wrap; /* 保留文本中的换行和空格 */
word-wrap: break-word; /* 超出宽度时自动换行 */
}
</style>
</head>
<body>
<div class="article-container" id="articleContainer">
<div id="content" class="no-break"></div>
<div id="loadingIndicator" class="loading">正在加载更多内容...</div>
</div>
<script>
// 鲁迅《狂人日记》较长片段
const longArticle = `
《狂人日记》
鲁迅
今天晚上,很好的月光。我不见他已经有三十多年;我知道我本来是病了。
今天看见他的眼睛,又让我害怕起来。我知道,他在害我。
他的眼睛……今天真不对,和平时不一样。
我想,他一定是早已预备下手,今天晚上便要动手的了。我的心跳得很厉害;不过我早已知道他会这样预备。
他们都是这样,想法,害我。
今天晚上,我忽然想起二十多年前,他对我说的一句话:“吃人。”
吃人!这真叫我吓了一跳。我没有想到。他说得这么直截了当,这么认真。
以前,我看见书上说“吃人”,总以为是瞎说。今天晚上,我才知道,书上说的竟是真的。
我躺在床上,睁着眼睛,仔细想了想,越想越觉得害怕;因为我忽然想到,他们害人,还不只是今天,从古以来,他们就是这样。吃人!
我想了半夜,差不多明白了:我自己也有过吃人的念头,我也有过要吃人的时候。这种想法,是从古代传下来的,如今我才懂得。
过去的历史,处处是吃人的记载。至于他们怎么吃,我全都知道了……
但是,我绝对不愿再去吃人了!
我想着,想着,忽然感到无比的悲哀,因为,我觉得自己完全陷在了这个吃人的大陷阱里,摆脱不开。我真想大叫几声:“不要吃人!不要再吃人!”可是喊不出来。我心里越发沉重,好像被无数的锁链绑住一般。
昨天晚上,我又梦见他们了,他们全都聚在一起,脸上带着一种恶毒的笑容,像狼群一样盯着我。
今天我终于明白了,他们早已准备好了,等着我入圈套呢。
他们不是要吃我的肉,而是要夺走我的灵魂。
我的心里越来越沉重,几乎要崩溃了……
天哪,我究竟该怎么办?
`;
const contentElement = document.getElementById('content');
const loadingIndicator = document.getElementById('loadingIndicator');
let currentIndex = 0;
const CHUNK_SIZE = 150; // 每次渲染的字符数调整为150,显示更多内容
// 分段渲染文章内容
function renderNextChunk() {
if (currentIndex < longArticle.length) {
const nextChunk = longArticle.slice(currentIndex, currentIndex + CHUNK_SIZE);
contentElement.textContent += nextChunk; // 追加文本,不创建新段落
currentIndex += CHUNK_SIZE;
// 如果文章未加载完,继续调用下一个 chunk
setTimeout(renderNextChunk, 1000); // 每1秒渲染下一段
} else {
loadingIndicator.style.display = 'none'; // 隐藏加载提示
}
}
// 启动渲染
renderNextChunk();
</script>
</body>
</html>