
























TIP修改前必读:
- 本帖基于
Astro框架的Fuwari主题进行修改方案编写,因此请读者优先掌握 Astro Docs 的内容后再来进行魔改。- 由于修改内容较多,以及可能会导致意料之外的事情,推荐使用
Github配合VSCode进行修改,方便随时备份恢复
之前在用 Hexo 的 anzhiyu 主题时,就搞过一次友链状态显示的功能(详见安知鱼主题实现友链状态前端显示),当时用的是 LiuShen 大佬 的 check-flink 方案,效果还不错。
后来博客迁移到了 Astro 框架的 Fuwari 主题,之前那些 Hexo 的东西自然是用不了了。一直惦记着这个功能,趁着有空就把它给搞上了。
实现来自:LiuShen 大佬的友链状态检测方案
先简单说一下这个功能的原理,其实和之前 anzhiyu 主题那篇是一样的套路:
result.json 文件,部署在 Vercel / Zeabur 等平台状态颜色分级如下:
后端检测部分直接使用 LiuShen 大佬的 check-flink 项目,具体部署教程可以参考他的文章,这里就不重复了。你需要做的就是:
result.json 的 URL拿到 URL 后,记下来,后面要用。
首先需要修改 src/pages/link.astro,给每个友链卡片加上 data-url 属性和状态标签的容器。
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
{friends.map((friend) => (
<a href={friend.url} target="_blank" class="friend-card">
<a href={friend.url} target="_blank" class="friend-card" data-url={friend.url}>
<span class="friend-status"></span>
<div class="flex items-center gap-2">
然后在 <style> 部分添加状态标签的样式。注意 .friend-card 需要加上 relative 定位,这样状态标签才能相对卡片定位。
// src/pages/link.astro <style>
.friend-card {
@apply flex flex-col gap-1 p-4 rounded-lg bg-[var(--card-bg)] border border-black/10 dark:border-white/10 hover:border-black/20 dark:hover:border-white/20 hover:bg-black/5 dark:hover:bg-white/5;
@apply relative flex flex-col gap-1 p-4 rounded-lg bg-[var(--card-bg)] border border-black/10 dark:border-white/10 hover:border-black/20 dark:hover:border-white/20 hover:bg-black/5 dark:hover:bg-white/5;
transition-property: background-color, border-color, scale;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 0.15s;
transform: translateZ(0);
}
.friend-status {
position: absolute;
top: 8px;
right: 8px;
font-size: 0.7rem;
padding: 2px 6px;
border-radius: 4px;
color: #fff;
line-height: 1.2;
white-space: nowrap;
display: none;
}
.friend-card:active {
最关键的一步,在 src/layouts/Layout.astro 的 </style> 标签后面添加内联脚本。这里用 is:inline 让脚本直接在客户端执行,不经过 Astro 的打包处理。
</style>
<script is:inline>
function renderLinkStatus() {
if (!document.querySelector(".friend-status")) return;
fetch("https://check-flink.mcxiaochen.top/result.json") // 改成你自己的 URL
.then(res => res.json())
.then(data => {
if (!data.link_status) return;
const statusMap = {};
data.link_status.forEach(item => {
statusMap[item.link] = item;
});
document.querySelectorAll(".friend-status").forEach(el => {
const card = el.closest("[data-url]");
if (!card) return;
const url = card.getAttribute("data-url");
const info = statusMap[url];
if (!info) return;
el.style.display = "inline-block";
if (info.latency === -1) {
el.style.backgroundColor = "#ef4444";
el.textContent = "超时";
} else if (info.latency < 1) {
el.style.backgroundColor = "#22c55e";
el.textContent = info.latency + "s";
} else if (info.latency < 2) {
el.style.backgroundColor = "#f59e0b";
el.textContent = info.latency + "s";
} else {
el.style.backgroundColor = "#f97316";
el.textContent = info.latency + "s";
}
});
})
.catch(err => console.error("friend link status error:", err));
}
function setupLinkStatus() {
renderLinkStatus();
if (window.swup) {
window.swup.hooks.on("page:view", renderLinkStatus);
}
}
if (window?.swup?.hooks) {
setupLinkStatus();
} else {
document.addEventListener("swup:enable", setupLinkStatus);
}
</script>
<script>
这里有一个小细节:Fuwari 主题使用了 swup 做页面过渡动画,所以需要监听 swup 的 page:view 事件,在页面切换后重新渲染状态标签。如果不做这个处理,在友链页和其他页面之间切换时,状态标签就不会刷新。
在改的过程中发现 src/layouts/Layout.astro 里的 keywords meta 标签有个小问题 —— 当 siteConfig.keywords 是数组时,直接塞进 content 属性会变成逗号分隔的奇怪字符串。顺手修了一下:
<meta name="keywords" content={siteConfig.keywords}>
<meta name="keywords" content={Array.isArray(siteConfig.keywords) ? siteConfig.keywords.join(', ') : siteConfig.keywords}>
到这里就大功告成了,效果就是在友链卡片的右上角会显示一个小标签,颜色根据延迟自动变化。
好处:
代码是 AI 辅助修改的,如果有问题欢迎评论区指出~
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。