aboutsummaryrefslogtreecommitdiff
path: root/themes/hugo-theme-stack/assets/ts/smoothAnchors.ts
diff options
context:
space:
mode:
Diffstat (limited to 'themes/hugo-theme-stack/assets/ts/smoothAnchors.ts')
-rw-r--r--themes/hugo-theme-stack/assets/ts/smoothAnchors.ts37
1 files changed, 37 insertions, 0 deletions
diff --git a/themes/hugo-theme-stack/assets/ts/smoothAnchors.ts b/themes/hugo-theme-stack/assets/ts/smoothAnchors.ts
new file mode 100644
index 0000000..16ab6a3
--- /dev/null
+++ b/themes/hugo-theme-stack/assets/ts/smoothAnchors.ts
@@ -0,0 +1,37 @@
+// Implements smooth scrolling when clicking on an anchor link.
+// This is required instead of using modern CSS because Chromium does not currently support scrolling
+// one element with scrollTo while another element is scrolled because of a click on a link. This would
+// thus not work with the ToC scrollspy and e.g. footnotes.
+
+// Here are additional links about this issue:
+// - https://stackoverflow.com/questions/49318497/google-chrome-simultaneously-smooth-scrollintoview-with-more-elements-doesn
+// - https://stackoverflow.com/questions/57214373/scrollintoview-using-smooth-function-on-multiple-elements-in-chrome
+// - https://bugs.chromium.org/p/chromium/issues/detail?id=833617
+// - https://bugs.chromium.org/p/chromium/issues/detail?id=1043933
+// - https://bugs.chromium.org/p/chromium/issues/detail?id=1121151
+
+const anchorLinksQuery = "a[href]";
+
+function setupSmoothAnchors() {
+ document.querySelectorAll(anchorLinksQuery).forEach(aElement => {
+ let href = aElement.getAttribute("href");
+ if (!href.startsWith("#")) {
+ return;
+ }
+ aElement.addEventListener("click", clickEvent => {
+ clickEvent.preventDefault();
+
+ const targetId = decodeURI(aElement.getAttribute("href").substring(1)),
+ target = document.getElementById(targetId) as HTMLElement,
+ offset = target.getBoundingClientRect().top - document.documentElement.getBoundingClientRect().top;
+
+ window.history.pushState({}, "", aElement.getAttribute("href"));
+ scrollTo({
+ top: offset,
+ behavior: "smooth"
+ });
+ });
+ });
+}
+
+export { setupSmoothAnchors }; \ No newline at end of file