113 lines
3.7 KiB
JavaScript
113 lines
3.7 KiB
JavaScript
(() => {
|
||
const navLinks = Array.from(document.querySelectorAll(".side-nav a"));
|
||
const sections = Array.from(document.querySelectorAll("[data-section]"));
|
||
const filterButtons = Array.from(document.querySelectorAll("[data-filter]"));
|
||
const clearButton = document.querySelector("[data-clear-filter]");
|
||
const filterStatus = document.querySelector("[data-filter-status]");
|
||
const diagnosticRows = Array.from(document.querySelectorAll(".diagnostic-row"));
|
||
|
||
const setActiveLink = (id) => {
|
||
navLinks.forEach((link) => {
|
||
const isActive = link.getAttribute("href") === `#${id}`;
|
||
link.classList.toggle("is-active", isActive);
|
||
});
|
||
};
|
||
|
||
// 导航高亮只读当前滚动位置,不改变 URL,避免干扰文档分享。
|
||
if ("IntersectionObserver" in window) {
|
||
const observer = new IntersectionObserver(
|
||
(entries) => {
|
||
const visible = entries
|
||
.filter((entry) => entry.isIntersecting)
|
||
.sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0];
|
||
if (visible) {
|
||
setActiveLink(visible.target.id);
|
||
}
|
||
},
|
||
{ rootMargin: "-20% 0px -65% 0px", threshold: [0.1, 0.35, 0.6] }
|
||
);
|
||
|
||
sections.forEach((section) => observer.observe(section));
|
||
} else if (sections[0]) {
|
||
setActiveLink(sections[0].id);
|
||
}
|
||
|
||
const resetCopyButton = (button, label) => {
|
||
window.setTimeout(() => {
|
||
button.textContent = label;
|
||
button.removeAttribute("aria-label");
|
||
}, 2200);
|
||
};
|
||
|
||
// 复制失败时直接把值显示在按钮上,现场排障仍能手动选中。
|
||
document.querySelectorAll("[data-copy]").forEach((button) => {
|
||
const defaultLabel = button.textContent;
|
||
button.addEventListener("click", async () => {
|
||
const value = button.getAttribute("data-copy") || "";
|
||
try {
|
||
if (!navigator.clipboard || !navigator.clipboard.writeText) {
|
||
throw new Error("clipboard unavailable");
|
||
}
|
||
await navigator.clipboard.writeText(value);
|
||
button.textContent = "已复制";
|
||
button.setAttribute("aria-label", `已复制 ${value}`);
|
||
} catch (error) {
|
||
button.textContent = value;
|
||
button.setAttribute("aria-label", `复制失败,值为 ${value}`);
|
||
}
|
||
resetCopyButton(button, defaultLabel);
|
||
});
|
||
});
|
||
|
||
const symptomLabel = {
|
||
"404": "404",
|
||
"400": "400",
|
||
"401-403": "401/403",
|
||
"409": "409",
|
||
"empty-list": "空列表但应有数据",
|
||
accepted: "accepted 但不终态",
|
||
"adapter-failure": "外部服务失败",
|
||
"response-shape": "响应字段不对",
|
||
};
|
||
|
||
const applyFilter = (symptom) => {
|
||
diagnosticRows.forEach((row) => {
|
||
row.classList.toggle("is-hidden", row.getAttribute("data-symptom") !== symptom);
|
||
});
|
||
|
||
filterButtons.forEach((button) => {
|
||
button.classList.toggle("is-selected", button.getAttribute("data-filter") === symptom);
|
||
});
|
||
|
||
if (filterStatus) {
|
||
filterStatus.textContent = `当前只显示:${symptomLabel[symptom] || symptom}。`;
|
||
}
|
||
|
||
const troubleshooting = document.querySelector("#troubleshooting");
|
||
if (troubleshooting) {
|
||
troubleshooting.scrollIntoView({ behavior: "smooth", block: "start" });
|
||
}
|
||
};
|
||
|
||
const clearFilter = () => {
|
||
diagnosticRows.forEach((row) => row.classList.remove("is-hidden"));
|
||
filterButtons.forEach((button) => button.classList.remove("is-selected"));
|
||
if (filterStatus) {
|
||
filterStatus.textContent = "当前显示全部诊断项。";
|
||
}
|
||
};
|
||
|
||
filterButtons.forEach((button) => {
|
||
button.addEventListener("click", () => {
|
||
const symptom = button.getAttribute("data-filter");
|
||
if (symptom) {
|
||
applyFilter(symptom);
|
||
}
|
||
});
|
||
});
|
||
|
||
if (clearButton) {
|
||
clearButton.addEventListener("click", clearFilter);
|
||
}
|
||
})();
|