Skip to content

Commit ce36969

Browse files
committed
feat: add anchors
click to copy link to section
1 parent edc596c commit ce36969

2 files changed

Lines changed: 81 additions & 45 deletions

File tree

out/scroll.js

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,76 @@
1-
const nav = document.getElementsByTagName("nav")[0];
2-
const main = document.getElementsByTagName("main")[0]
3-
4-
const calcNavAmounts = (root, root_top, root_bottom, root_min, root_max) => {
5-
let nav_amounts = [];
6-
for (const child of root.children) {
7-
const rect = child.getBoundingClientRect();
8-
const nest_min = (rect.top - root_top) / (root_bottom - root_top);
9-
const nest_max = (rect.bottom - root_top) / (root_bottom - root_top);
10-
const min = root_min + (root_max - root_min) * nest_min;
11-
const max = root_min + (root_max - root_min) * nest_max;
12-
if (child.tagName === "A") {
13-
if (!child.href.includes("#")) continue;
14-
const id = child.href.substring(child.href.lastIndexOf("#") + 1)
15-
nav_amounts.push({ id: id, min: min, max: max });
16-
} else {
17-
nav_amounts = nav_amounts.concat(calcNavAmounts(child, rect.top, rect.bottom, min, max));
1+
{
2+
const nav = document.getElementsByTagName("nav")[0];
3+
const main = document.getElementsByTagName("main")[0]
4+
5+
const calcNavAmounts = (root, root_top, root_bottom, root_min, root_max) => {
6+
let nav_amounts = [];
7+
for (const child of root.children) {
8+
const rect = child.getBoundingClientRect();
9+
const nest_min = (rect.top - root_top) / (root_bottom - root_top);
10+
const nest_max = (rect.bottom - root_top) / (root_bottom - root_top);
11+
const min = root_min + (root_max - root_min) * nest_min;
12+
const max = root_min + (root_max - root_min) * nest_max;
13+
if (child.tagName === "A") {
14+
if (!child.href.includes("#")) continue;
15+
const id = child.href.substring(child.href.lastIndexOf("#") + 1)
16+
nav_amounts.push({ id: id, min: min, max: max });
17+
} else {
18+
nav_amounts = nav_amounts.concat(calcNavAmounts(child, rect.top, rect.bottom, min, max));
19+
}
1820
}
19-
}
20-
return nav_amounts;
21-
};
21+
return nav_amounts;
22+
};
2223

23-
const calcAllNavAmounts = () => {
24-
const rect = nav.getBoundingClientRect();
25-
return calcNavAmounts(nav, rect.top, rect.bottom, 0.0, 1.0);
26-
};
24+
const calcAllNavAmounts = () => {
25+
const rect = nav.getBoundingClientRect();
26+
return calcNavAmounts(nav, rect.top, rect.bottom, 0.0, 1.0);
27+
};
2728

2829

29-
const updateScroll = () => {
30-
// Don't change background color on mobile
31-
if (window.innerWidth < 800) {
32-
return nav.style.removeProperty("background");
33-
}
30+
const updateScroll = () => {
31+
// Don't change background color on mobile
32+
if (window.innerWidth < 800) {
33+
return nav.style.removeProperty("background");
34+
}
3435

35-
let min = 0.0;
36-
let max = 0.0;
37-
for (const section of calcAllNavAmounts()) {
38-
const header = document.getElementById(section.id);
39-
if (main.scrollTop + 1 >= header.offsetTop) {
40-
min = section.min;
41-
max = section.max;
36+
let min = 0.0;
37+
let max = 0.0;
38+
for (const section of calcAllNavAmounts()) {
39+
const header = document.getElementById(section.id);
40+
if (main.scrollTop + 1 >= header.offsetTop) {
41+
min = section.min;
42+
max = section.max;
43+
}
44+
}
45+
const start = min * 100;
46+
const end = max * 100;
47+
nav.style.background = `linear-gradient(180deg, #ffffff10 ${start}%, #0000 ${end}%)`;
48+
};
49+
50+
const addAnchors = () => {
51+
const headers = main.querySelectorAll("h1, h2, h3, h4, h5, h6");
52+
for (const header of headers) {
53+
if (!header.id) continue;
54+
const anchor = document.createElement("a");
55+
anchor.href = `#${header.id}`;
56+
anchor.className = "anchor fa-solid fa-link";
57+
anchor.onclick = (e) => {
58+
e.preventDefault();
59+
navigator.clipboard.writeText(window.location.href.split("#")[0] + `#${header.id}`);
60+
anchor.style.color = "#4cd";
61+
setTimeout(() => {
62+
anchor.style.removeProperty("color");
63+
}, 1000);
64+
65+
}
66+
// append before
67+
header.insertBefore(anchor, header.firstChild);
4268
}
4369
}
44-
const start = min * 100;
45-
const end = max * 100;
46-
nav.style.background = `linear-gradient(180deg, #ffffff10 ${start}%, #0000 ${end}%)`;
47-
};
48-
49-
updateScroll();
50-
main.addEventListener("scroll", updateScroll);
51-
nav.addEventListener("scroll", updateScroll);
52-
window.addEventListener("resize", updateScroll);
70+
71+
addAnchors();
72+
updateScroll();
73+
main.addEventListener("scroll", updateScroll);
74+
nav.addEventListener("scroll", updateScroll);
75+
window.addEventListener("resize", updateScroll);
76+
}

out/style.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,18 @@ h5 {
147147
font-size: 0.9em;
148148
margin: 1.0rem 0 0.1rem 0;
149149
}
150+
h6 {
151+
font-size: 0.8em;
152+
margin: 1.0rem 0 0.1rem 0;
153+
}
154+
.anchor {
155+
vertical-align: middle;
156+
font-size: 1rem;
157+
margin-right: 0.5em;
158+
color: inherit;
159+
transition: color .3s ease;
160+
}
161+
150162
p {
151163
margin: 0.7em 0 0.5em 0;
152164
}

0 commit comments

Comments
 (0)