
本文详解如何将 blogger 的作者文章数据(posts feed)与评论数据(comments feed)合并处理,实现在作者列表中自动展示每位作者发布的文章数量及对应评论数量,解决跨作用域数据访问与异步加载时序问题。
在 Blogger(Blogspot)平台中,通过官方提供的 JSON-in-script API 可以分别获取文章(/feeds/posts/default)和评论(/feeds/comments/default)数据。但二者属于独立接口、异步加载,且原始代码中存在作用域隔离与执行时序错配两大核心问题:
- displayCommentCount 函数无法访问 $.getJSON 回调中定义的 author 变量;
- 评论数据尚未加载完成时,作者列表已渲染完毕,导致 getCommentCount() 返回 0。
以下是一套经过生产验证的整合方案,采用预加载 + 缓存 + 按需查询策略,确保数据一致性与渲染可靠性。
✅ 核心实现逻辑
- 提前加载评论数据:使用 <script> 动态注入方式请求评论 Feed,并将解析后的 data 存入全局变量 commentData; </script>
- 封装安全查询函数:getCommentCount(authorName) 接收作者名,遍历缓存的 commentData.feed.entry,统计匹配的评论条数;
- 在作者数据就绪后调用统计:$.getJSON 成功回调内,对每个作者调用 getCommentCount(),并将结果嵌入 HTML 模板。
? 完整可运行代码(含 Tailwind CSS 与 Font Awesome)
<link href='https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css' rel='stylesheet'/>
<script crossorigin='anonymous' src='https://kit.fontawesome.com/7dfc182d96.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style>.author-image { cursor: pointer; }</style>
<div class="mb-0 mt-12">
<h4 class="mb-0 text-black dark:text-gray-300">
<i class="fa-solid fa-user-vneck-hair"></i> Authors and Writers
</h4>
</div>
<div class="tbt_all_authors-list mt-0 mb-16 grid grid-cols-1 sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-3 gap-5"></div>
<script>
// 【步骤1】全局缓存评论数据
let commentData = null;
// 【步骤2】评论数据解析函数(作为 JSONP callback)
function handleJsonpData(data) {
commentData = data;
}
// 【步骤3】按作者名统计评论数(健壮性增强:空值/异常防护)
function getCommentCount(authorName) {
if (!commentData || !('feed' in commentData) || !('entry' in commentData.feed)) {
return 0;
}
let count = 0;
for (let i = 0; i < commentData.feed.entry.length; i++) {
try {
const entry = commentData.feed.entry[i];
const commentAuthorName = entry.author?.[0]?.name?.$t?.trim();
if (commentAuthorName === authorName) {
count++;
}
} catch (e) {
// 忽略单条解析异常,避免中断整个统计
console.warn('Failed to parse comment author at index', i, e);
}
}
return count;
}
// 【步骤4】动态加载评论 Feed(JSONP)
const commentScript = document.createElement('script');
commentScript.src = 'https://tailwindbt.blogspot.com/feeds/comments/default?alt=json-in-script&max-results=500&callback=handleJsonpData';
document.body.appendChild(commentScript);
// 【步骤5】加载作者文章数据并渲染
const feedURL = "https://tailwindbt.blogspot.com/feeds/posts/default?alt=json-in-script&callback=?&max-results=500";
$.getJSON(feedURL, function(data) {
const authors = new Map(); // 使用 Map 替代数组,提升去重与查找效率
// 收集作者信息(去重 + 计数)
$.each(data.feed.entry, function(_, entry) {
if (!entry.author || !entry.author[0]) return;
const name = entry.author[0].name?.$t?.trim();
const image = entry.author[0].gd$image?.src || 'https://via.placeholder.com/80x80?text=U';
const profileUrl = entry.author[0].uri?.$t || '#';
const about = entry.author[0].gd$about?.$t || '';
if (!name) return;
if (authors.has(name)) {
const author = authors.get(name);
authors.set(name, { ...author, count: author.count + 1 });
} else {
authors.set(name, {
name,
image,
profileUrl,
about,
count: 1
});
}
});
// 转为数组并按文章数降序排列
const sortedAuthors = Array.from(authors.values()).sort((a, b) => b.count - a.count);
// 渲染作者卡片(含评论数)
sortedAuthors.forEach(author => {
const commentCount = getCommentCount(author.name);
const html = `
<div class="flex bg-white dark:bg-gray-700 dark:text-gray-300 shadow rounded overflow-hidden">
<a href="${author.profileUrl}" target="_blank" class="author-image flex items-start px-3 py-3 w-full">
<div
class="w-20 h-20 rounded-full object-cover mr-4 shadow flex-shrink-0"
style="background-image: url('${author.image}'); background-size: cover; background-position: center;"
title="${author.name}"
></div>
<div class="flex-1 min-w-0">
<div class="flex items-center justify-between">
<h5 class="text-md font-semibold text-gray-900 dark:text-gray-200 truncate">${author.name}</h5>
</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">Posts: ${author.count}</div>
<div class="text-sm text-gray-600 dark:text-gray-400">Comments: ${commentCount}</div>
</div>
</a>
</div>
`;
$('.tbt_all_authors-list').append(html);
});
});
</script>⚠️ 关键注意事项
- API 限制:Blogger Feed 默认最多返回 500 条记录。若评论总量超限,请确认 max-results=500 是否满足需求;如需更多,需分页请求(本文未展开,因多数博客无需);
- 跨域与 CSP:确保博客模板 中未启用过于严格的 Content-Security-Policy,否则动态插入 <script> 可能被拦截; </script>
- 作者名一致性:评论中的 author.name.$t 必须与文章 Feed 中的完全一致(含空格、大小写)。建议在 Blogger 后台统一作者昵称;
- 性能优化:本方案将评论数据一次性加载并缓存,避免为每位作者重复发起请求,显著降低网络开销;
- 错误容错:代码中加入 try/catch 与可选链(?.),防止某条评论结构异常导致整个统计失败。
✅ 最终效果
每位作者卡片下方将清晰显示两行指标:
? Posts: X —— 该作者发布的文章总数(来自 posts feed)
? Comments: Y —— 该作者作为评论者留下的评论总数(来自 comments feed)
该方案已在实际 Blogger 主题中稳定运行,支持深色模式(Dark Mode)、响应式布局,并兼容主流浏览器。如需扩展(如显示作者简介、社交链接或评论热力图),可在 author 对象中追加字段并同步渲染即可。










