修复:增加回到顶部功能,优化博客性能

This commit is contained in:
2026-09-21 09:37:31 +08:00
parent b0e7d40faf
commit 219cb712a6
27 changed files with 845 additions and 373 deletions
-92
View File
@@ -37,98 +37,6 @@ const isEnabled = Boolean(envId)
data-lang={commentConfig.lang}
data-strip-trailing-slash={commentConfig.stripTrailingSlash ? "true" : "false"}
/>
<script is:inline>
;(() => {
const SCRIPT_SRC = "/assets/js/twikoo.min.js"
/**
* 注意:容器是 <div id="twikoo">,而浏览器会把带 id 的元素暴露成
* window 上的同名全局变量 —— 所以脚本加载前 window.twikoo 就已经
* 是那个 DOM 元素了。这里必须检查真正的 API 是否存在,
* 不能只判断 `if (window.twikoo)`,否则会误以为已加载而跳过。
*/
const isLoaded = () =>
typeof window.twikoo === "object" && typeof window.twikoo?.init === "function"
const loadScript = () => {
if (isLoaded()) return Promise.resolve()
const existing = document.querySelector("script[data-twikoo]")
if (existing) {
if (existing.dataset.loaded === "true") return Promise.resolve()
return new Promise((resolve, reject) => {
existing.addEventListener("load", () => resolve(), { once: true })
existing.addEventListener(
"error",
() => reject(new Error("twikoo 脚本加载失败")),
{ once: true },
)
})
}
return new Promise((resolve, reject) => {
const script = document.createElement("script")
script.src = SCRIPT_SRC
script.async = true
script.dataset.twikoo = "true"
script.onload = () => {
script.dataset.loaded = "true"
resolve()
}
script.onerror = () => reject(new Error("twikoo 脚本加载失败: " + SCRIPT_SRC))
document.head.appendChild(script)
})
}
/**
* 评论归属路径。本站 trailingSlash 为 "always",但评论 key 统一去掉
* 结尾斜杠(/posts/xxx),与历史数据保持一致。
*/
const getCommentPath = (strip) => {
const pathname = window.location.pathname
if (strip && pathname.length > 1 && pathname.endsWith("/")) {
return pathname.slice(0, -1)
}
return pathname
}
const mount = async () => {
const container = document.getElementById("twikoo")
if (!container) return
// astro:page-load 在首屏也会触发,用标记避免重复初始化;
// 切页时容器是新节点,没有这个标记,所以会正常重新挂载。
if (container.dataset.mounted === "true") return
const envId = container.dataset.envId
if (!envId) return
container.dataset.mounted = "true"
try {
await loadScript()
await window.twikoo.init({
envId,
el: "#twikoo",
lang: container.dataset.lang || "zh-CN",
path: getCommentPath(container.dataset.stripTrailingSlash === "true"),
})
} catch (error) {
// 失败时解除标记,允许下次切页重试
container.dataset.mounted = "false"
console.error("[twikoo] 初始化失败:", error)
}
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", mount)
} else {
mount()
}
document.addEventListener("astro:page-load", mount)
})()
</script>
</div>
</div>
</section>