Files
halo-theme-whitespace/src/js/post.ts
T
nxxy335 8e6dccbd09 feat: 插件适配页面与系统完善(v0.1.0)
- 修复 /categories、/tags 因变量为 List 误用 .items 导致的 500
- 新增 layout.html 布局契约,消除插件页面 fallback 警告
- 适配 plugin-moments / plugin-photos / plugin-links(含友链申请表单与 RSS 订阅页)
- 适配 halo-weread-plugin(书架页)、留言板单页模板
- 适配 plugin-extra-api 的代码高亮与暗色样式
- 修复暗黑模式评论区不可见(补充 color-scheme 与兜底样式)
- 更新元数据:作者暖心向阳335、版本 0.1.0、requires >=2.26.0
2026-09-28 16:50:09 +08:00

83 lines
2.2 KiB
TypeScript

/**
* whitespace 留白主题 - 文章页脚本
* 代码块复制 + 阅读进度条
*/
// ========================================
// 代码块复制
// ========================================
function initCodeCopy(): void {
const codeBlocks = document.querySelectorAll<HTMLElement>(
".article-content pre",
);
codeBlocks.forEach((pre) => {
const copyBtn = document.createElement("button");
copyBtn.className = "code-copy-btn";
copyBtn.type = "button";
copyBtn.textContent = "复制";
pre.style.position = "relative";
pre.appendChild(copyBtn);
copyBtn.addEventListener("click", async () => {
const code = pre.querySelector("code");
const text = code ? (code.textContent ?? "") : (pre.textContent ?? "");
try {
await navigator.clipboard.writeText(text);
copyBtn.textContent = "已复制";
copyBtn.classList.add("copied");
setTimeout(() => {
copyBtn.textContent = "复制";
copyBtn.classList.remove("copied");
}, 2000);
} catch {
console.error("复制失败");
}
});
});
}
// ========================================
// 阅读进度条
// ========================================
function initReadingProgress(): void {
const article = document.querySelector<HTMLElement>(".article-content");
if (!article) return;
const progressBar = document.createElement("div");
progressBar.className = "reading-progress";
document.body.appendChild(progressBar);
const updateProgress = () => {
const articleTop = article.offsetTop;
const articleHeight = article.offsetHeight;
const windowHeight = window.innerHeight;
const scrollY = window.scrollY;
const start = articleTop - windowHeight;
const end = articleTop + articleHeight;
const current = scrollY;
let progress = ((current - start) / (end - start)) * 100;
progress = Math.max(0, Math.min(100, progress));
progressBar.style.width = `${progress}%`;
};
window.addEventListener("scroll", updateProgress, { passive: true });
updateProgress();
}
function init(): void {
initCodeCopy();
initReadingProgress();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}