|
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 | + } |
18 | 20 | } |
19 | | - } |
20 | | - return nav_amounts; |
21 | | -}; |
| 21 | + return nav_amounts; |
| 22 | + }; |
22 | 23 |
|
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 | + }; |
27 | 28 |
|
28 | 29 |
|
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 | + } |
34 | 35 |
|
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); |
42 | 68 | } |
43 | 69 | } |
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 | +} |
0 commit comments