-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
92 lines (78 loc) · 2.44 KB
/
script.js
File metadata and controls
92 lines (78 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
const root = document.documentElement;
const themeToggle = document.querySelector(".theme-toggle");
const searchButton = document.querySelector(".search-button");
const navLinks = [...document.querySelectorAll(".main-nav a")];
const homeLinks = [...document.querySelectorAll('a[href="#home"]')];
const sectionLinks = navLinks.filter((link) => link.getAttribute("href") !== "#home");
const sections = sectionLinks
.map((link) => document.querySelector(link.getAttribute("href")))
.filter(Boolean);
const darkQuery = window.matchMedia("(prefers-color-scheme: dark)");
function setActiveNav(hash) {
navLinks.forEach((link) => {
link.classList.toggle("active", link.getAttribute("href") === hash);
});
}
function resolveTheme(choice) {
if (choice === "auto") {
return darkQuery.matches ? "dark" : "light";
}
return choice;
}
function applyTheme(choice) {
root.dataset.theme = choice;
root.dataset.resolvedTheme = resolveTheme(choice);
themeToggle?.classList.toggle("active", root.dataset.resolvedTheme === "dark");
}
const savedTheme = localStorage.getItem("academic-site-theme") || "auto";
applyTheme(savedTheme);
themeToggle?.addEventListener("click", () => {
const nextTheme = root.dataset.resolvedTheme === "dark" ? "light" : "dark";
localStorage.setItem("academic-site-theme", nextTheme);
applyTheme(nextTheme);
});
searchButton?.addEventListener("click", () => {
const query = window.prompt("Search this page");
if (query) {
window.find(query);
}
});
darkQuery.addEventListener("change", () => {
if (root.dataset.theme === "auto") {
applyTheme("auto");
}
});
homeLinks.forEach((link) => {
link.addEventListener("click", (event) => {
event.preventDefault();
window.scrollTo({ top: 0, behavior: "smooth" });
history.replaceState(null, "", window.location.pathname);
setActiveNav("#home");
});
});
window.addEventListener(
"scroll",
() => {
if (window.scrollY < 90) {
setActiveNav("#home");
}
},
{ passive: true },
);
const observer = new IntersectionObserver(
(entries) => {
const visible = entries
.filter((entry) => entry.isIntersecting)
.sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0];
if (!visible) return;
setActiveNav(`#${visible.target.id}`);
},
{
rootMargin: "-22% 0px -62% 0px",
threshold: [0.1, 0.25, 0.5],
},
);
sections.forEach((section) => observer.observe(section));
if (window.scrollY < 90) {
setActiveNav("#home");
}