From 9f9a5d6aa541437a2459de1bf12f7bd9e8ef37ab Mon Sep 17 00:00:00 2001 From: tdro Date: Fri, 2 Sep 2022 04:15:06 -0400 Subject: static/js/pager: Add fragment intersection observer To release URL fragments --- assets/js/index.js | 35 +++++++++++++++++++++++++++++------ static/js/pager.ts | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/assets/js/index.js b/assets/js/index.js index a0c608f..b4f0bcb 100644 --- a/assets/js/index.js +++ b/assets/js/index.js @@ -12,18 +12,20 @@ const settings1 = { pager: {} }; - const url1 = self.location.href.split("#")[0]; + const url1 = self.location.href.split("#")[0].split("?")[0]; const scrollRestore = (settings, url)=>{ if (history.scrollRestoration) history.scrollRestoration = "manual"; if (localStorage["settings"]) { settings = JSON.parse(localStorage["settings"]); } - if (self.location.hash.length > 0) { + const fragment = document.getElementById(location.hash.slice(1)); + const fragmentInURL = self.location.hash.length > 0; + if (fragmentInURL && document.body.contains(fragment)) { settings["pager"][url] = self.pageYOffset; localStorage["settings"] = JSON.stringify(settings); - document.getElementById(location.hash.slice(1)).scrollIntoView(); + fragment.scrollIntoView(); self.addEventListener("load", function() { - document.getElementById(location.hash.slice(1)).scrollIntoView(); + fragment.scrollIntoView(); }); return; } @@ -50,8 +52,29 @@ history.go(-1); } }; + const fragmentClear = (entries)=>{ + for(let entry = 0; entry < entries.length; entry++){ + if (self.location.hash) { + self.history.pushState(null, "", url1); + } + } + }; + const fragmentRelease = (fragmentCallback)=>{ + try { + const fragmentObserver = new IntersectionObserver(fragmentCallback, { + threshold: 1.0 + }); + const fragments = document.querySelectorAll("[id]"); + for(let fragment = 0; fragment < fragments.length; fragment++){ + fragmentObserver.observe(fragments[fragment]); + } + } catch (error) { + console.log("The intersection observer is not supported", error); + } + }; self.addEventListener("DOMContentLoaded", function() { scrollRestore(settings1, url1); + fragmentRelease(fragmentClear); self.addEventListener("click", function(event) { const up = document.getElementById("top"); const back = document.getElementById("back"); @@ -498,8 +521,8 @@ if (days <= 60) { return element.textContent = relative.format(-1 * days, "day"); } - } catch (err) { - console.error("Error: Unable to resolve relative time format!", err); + } catch (error) { + console.error("Error: Unable to resolve relative time format!", error); } }); }; diff --git a/static/js/pager.ts b/static/js/pager.ts index 0de2ec1..68708cc 100644 --- a/static/js/pager.ts +++ b/static/js/pager.ts @@ -9,19 +9,21 @@ const settings = { pager: {} }; - const url = self.location.href.split("#")[0]; + const url = self.location.href.split("#")[0].split("?")[0]; const scrollRestore = (settings, url) => { if (history.scrollRestoration) history.scrollRestoration = "manual"; if (localStorage["settings"]) { settings = JSON.parse(localStorage["settings"]); } - if (self.location.hash.length > 0) { + const fragment = document.getElementById(location.hash.slice(1)); + const fragmentInURL = self.location.hash.length > 0; + if (fragmentInURL && document.body.contains(fragment)) { settings["pager"][url] = self.pageYOffset; localStorage["settings"] = JSON.stringify(settings); - document.getElementById(location.hash.slice(1)).scrollIntoView(); + fragment.scrollIntoView(); self.addEventListener("load", function () { - document.getElementById(location.hash.slice(1)).scrollIntoView(); + fragment.scrollIntoView(); }); return; } @@ -51,8 +53,32 @@ } }; + const fragmentClear = (entries) => { + for (let entry = 0; entry < entries.length; entry++) { + if (self.location.hash) { + self.history.pushState(null, "", url); + } + } + }; + + const fragmentRelease = (fragmentCallback) => { + try { + const fragmentObserver = new IntersectionObserver(fragmentCallback, { + threshold: 1.0, + }); + const fragments = document.querySelectorAll("[id]"); + + for (let fragment = 0; fragment < fragments.length; fragment++) { + fragmentObserver.observe(fragments[fragment]); + } + } catch (error) { + console.log("The intersection observer is not supported", error); + } + }; + self.addEventListener("DOMContentLoaded", function () { scrollRestore(settings, url); + fragmentRelease(fragmentClear); self.addEventListener("click", function (event) { const up = document.getElementById("top"); const back = document.getElementById("back"); -- cgit v1.2.3