本站效果展示:链接

通过 JSONP + 动态创建 <script> 标签的方式请求数据,设置 async,不阻塞页面渲染,避免白屏。
2.分段请求以突破 API 数量限制
将最多 1500 篇文章拆成 3 次请求(每次 500 篇),并用回调顺序拼接,保证时间线不乱。
3.按年月自动分组归档
解析每篇文章的发布日期,自动生成“X年X月”的标题,并按日显示文章链接,形成清晰的归档目录。
4.无刷新动态渲染
先用占位容器显示加载提示,数据返回后直接通过 innerHTML 替换,避免使用 document.write 导致的页面卡顿和重写问题。
5.兼容老式浏览器
对 window.addEventListener、attachEvent 做了兼容处理,支持旧版 IE。
6.轻量无依赖
纯原生 JavaScript 实现,不依赖任何第三方库,直接嵌入 Blogger 模板或页面即可使用。
代码如下:
代码展示
<!--1. 新增一个容器,用于无延迟加载和显示数据-->
<div id="blogger-archive-container">
<span style="color: #999999; font-size: 14px;">文章归档加载中...</span>
</div>
<!--2. 优化后的 CSS 样式-->
<style type="text/css">
.dayStyle {
color: #757575;
display: inline-block;
width: 4em;
text-align: right;
}
.dateStyle {
font-weight: bold;
margin-top: 10px;
font-size: 1.1em;
}
</style>
<!--3. 异步非阻塞的 JavaScript 逻辑-->
<script type="text/javascript">
// 全局变量,用于按顺序拼接多段 API 返回的数据
var archiveCurrentYear = "";
var archiveCurrentMonth = "";
var archiveTotalHTML = "";
var archiveTotalPosts = 0;
// API 请求列表(分成三次请求以获取最多1500篇文章)
var feedUrls = [
"/feeds/posts/default?start-index=1&max-results=500&alt=json-in-script&callback=LoadTheArchive",
"/feeds/posts/default?start-index=501&max-results=500&alt=json-in-script&callback=LoadTheArchive",
"/feeds/posts/default?start-index=1001&max-results=500&alt=json-in-script&callback=LoadTheArchive"
];
var currentFeedIndex = 0;
// 解析并渲染数据
function LoadTheArchive(TotalFeed) {
// 检查是否有数据返回
if (!TotalFeed || !TotalFeed.feed || !TotalFeed.feed.entry) {
currentFeedIndex++;
loadNextFeed(); // 数据为空也继续尝试加载下一个
return;
}
var entries = TotalFeed.feed.entry;
archiveTotalPosts += entries.length;
var MonthNames = ["一","二","三","四","五","六","七","八","九","十","十一","十二"];
var tempHTML = "";
// 遍历当前请求获取到的文章
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
var title = entry.title.$t;
var pubDate = entry.published.$t;
var year = pubDate.substring(0, 4);
var month = pubDate.substring(5, 7);
var day = pubDate.substring(8, 10);
var url = "";
// 寻找文章的 URL
for (var j = 0; j < entry.link.length; j++) {
if (entry.link[j].rel == "alternate") {
url = entry.link[j].href;
break;
}
}
var monthName = MonthNames[parseInt(month, 10) - 1];
// 判断是否需要输出年月标题
if (archiveCurrentMonth != monthName || archiveCurrentYear != year) {
archiveCurrentMonth = monthName;
archiveCurrentYear = year;
tempHTML += "<div class='dateStyle'><br />" + year + " 年 " + monthName + "月</div>";
}
// 拼接文章行
tempHTML += "<a href='" + url + "'><div class='dayStyle'>" + parseInt(day, 10) + " 日 </div>" + title + "</a><br />";
}
archiveTotalHTML += tempHTML;
// 将生成好的 HTML 写入容器 (代替会导致卡顿的 document.write)
var container = document.getElementById('blogger-archive-container');
if (container) {
container.innerHTML = "<div>共计发布了 <b>" + archiveTotalPosts + "</b> 篇博文<br /><br /></div>" + archiveTotalHTML;
}
// 当前数据渲染完毕后,继续请求下一批数据,确保时间顺序不错乱
currentFeedIndex++;
loadNextFeed();
}
// 动态创建 script 标签进行异步加载
function loadNextFeed() {
if (currentFeedIndex < feedUrls.length) {
var script = document.createElement('script');
script.src = feedUrls[currentFeedIndex];
script.async = true; // 强制异步,不阻塞浏览器页面渲染
document.body.appendChild(script);
}
}
// 确保网页的 DOM 完全加载后再开始拉取 Blogger 数据
if (window.addEventListener) {
window.addEventListener('load', loadNextFeed, false);
} else if (window.attachEvent) {
window.attachEvent('onload', loadNextFeed); // 兼容旧版 IE
} else {
window.onload = loadNextFeed;
}
</script>