diff --git a/assets/js/highlightHeadline.js b/assets/js/highlightHeadline.js index 9128b2d1..d74c0947 100644 --- a/assets/js/highlightHeadline.js +++ b/assets/js/highlightHeadline.js @@ -1,103 +1,111 @@ -function initHighlightHeadline() { +import * as mq from './mediaqueries'; + +function isAsideActive() { + return window.matchMedia(mq.minLG).matches; +} - // In this site's layout, the table of contents (.content_with_heading) is an element that appears before any other content at the same hierarchy level - const headings = Array.from(document.querySelectorAll('.content_with_heading :is(h1, h2, h3, h4)')); - const asideMobileCurrentHeadline = document.getElementById('aside_mobile_current_headline'); - const windowPath = window.location.pathname; - if (headings.length === 0) { - return; // No headings? No business here - } +function initHighlightHeadline() { - // A few helper functions (.toc is the top-level ordered list) - const markTocItemActive = (a) => {return a.setAttribute('data-current', '');} - const markTocItemInactive = (a) => {return a.removeAttribute('data-current');}; - const getTocLinkFromHeading = (h) => {return document.querySelector(`.toc a[href="${windowPath}#${encodeURIComponent(h.id).replace(/%\w\w/g, match => match.toLowerCase())}"]`);} + // In this site's layout, the table of contents (.content_with_heading) is an element that appears before any other content at the same hierarchy level + const headings = Array.from(document.querySelectorAll('.content_with_heading :is(h1, h2, h3, h4)')); + const windowPath = window.location.pathname; + if (headings.length === 0) { + return; // No headings? No business here + } - const getDocHeight = () => Math.floor(document.body.clientHeight); + // A few helper functions (.toc is the top-level ordered list) + const markTocItemActive = (a) => {return a.setAttribute('data-current', '');} + const markTocItemInactive = (a) => {return a.removeAttribute('data-current');}; + const getTocLinkFromHeading = (h) => {return document.querySelector(`.toc a[href="${windowPath}#${encodeURIComponent(h.id).replace(/%\w\w/g, match => match.toLowerCase())}"]`);} - const visibleHeadings = new Set(); - let resizeDebounce; - let currentObserver; - let height = getDocHeight(); + const getDocHeight = () => Math.floor(document.body.clientHeight); - function beginObservation(docHeight) { - const observer = new IntersectionObserver( - (entries) => { - entries.forEach((entry) => { - // Keep track of visible headings - if (entry.isIntersecting) { - visibleHeadings.add(entry.target); - } else { - visibleHeadings.delete(entry.target); - } - }); + const visibleHeadings = new Set(); + let resizeDebounce; + let currentObserver; + let height = getDocHeight(); - // Sort visible (intersecting) headings by inverted order of appearance, then grab the first item (i.e. last visible heading) - const lastVisible = Array.from(visibleHeadings.values()).sort((a, b) => headings.indexOf(b) - headings.indexOf(a))[0]; - if (!lastVisible) { - return; // If nothing is visible, weird — TOC are opt-in — but let's skip this logic + function beginObservation(docHeight) { + const observer = new IntersectionObserver( + (entries) => { + if (!isAsideActive()) { + return; // Exit if .o-aside is not active } - headings.forEach((heading) => { + entries.forEach((entry) => { + // Keep track of visible headings + if (entry.isIntersecting) { + visibleHeadings.add(entry.target); + } else { + visibleHeadings.delete(entry.target); + } + }); - // If it's the last visible item, mark it to make it stand out, else, revert to the default style - // Find the link in the TOC list matching the heading in this list of hheding elements - const tocLink = getTocLinkFromHeading(heading); - if (heading === lastVisible) { - asideMobileCurrentHeadline.textContent = heading.textContent; - if(tocLink){ - markTocItemActive(tocLink); - } - } else { - if(tocLink){ - markTocItemInactive(tocLink); - } - } - }); - }, - { - //? docHeight: Extend the detection above the heading so it's always considered as intersecting if above the scrollport - //? -33%: The element won't be considered as intersecting until it has gone _above_ the bottom third of the scrollport - rootMargin: `${docHeight}px 0px -80% 0px`, - threshold: 1, // Only considered intersecting if all the pixels are inside the intersection area - } - ); + // Sort visible (intersecting) headings by inverted order of appearance, then grab the first item (i.e. last visible heading) + const lastVisible = Array.from(visibleHeadings.values()).sort((a, b) => headings.indexOf(b) - headings.indexOf(a))[0]; + if (!lastVisible) { + return; // If nothing is visible, weird — TOC are opt-in — but let's skip this logic + } - headings.forEach((heading) => observer.observe(heading)); - - return observer; - } + headings.forEach((heading) => { - // On page load... + // If it's the last visible item, mark it to make it stand out, else, revert to the default style + // Find the link in the TOC list matching the heading in this list of heading elements + const tocLink = getTocLinkFromHeading(heading); + if (heading === lastVisible) { + if(tocLink){ + markTocItemActive(tocLink); + } + } else { + if(tocLink){ + markTocItemInactive(tocLink); + } + } + }); + }, + { + //? docHeight: Extend the detection above the heading so it's always considered as intersecting if above the scrollport + //? -33%: The element won't be considered as intersecting until it has gone _above_ the bottom third of the scrollport + rootMargin: `${docHeight}px 0px -80% 0px`, + threshold: 1, // Only considered intersecting if all the pixels are inside the intersection area + } + ); + + headings.forEach((heading) => observer.observe(heading)); + + return observer; + } + + // On page load... // Let us don't do this /* markTocItemActive(getTocLinkFromHeading(headings[0])); // Mark the first item as active (even if the heading appears a bit further down) */ - currentObserver = beginObservation(height); // Start the intersection observer + currentObserver = beginObservation(height); // Start the intersection observer - // On resize, replace the observer with a new one matching the updated body height, if different - window.addEventListener('resize', () => { - clearTimeout(resizeDebounce); - resizeDebounce = setTimeout(() => { - const heightAfterResize = getDocHeight(); - if (height !== heightAfterResize) { - if (currentObserver) { - currentObserver.disconnect(); - } - currentObserver = beginObservation(heightAfterResize); - } - }, 200); - }); + // On resize, replace the observer with a new one matching the updated body height, if different + window.addEventListener('resize', () => { + clearTimeout(resizeDebounce); + resizeDebounce = setTimeout(() => { + const heightAfterResize = getDocHeight(); + if (height !== heightAfterResize) { + if (currentObserver) { + currentObserver.disconnect(); + } + currentObserver = beginObservation(heightAfterResize); + } + }, 200); + }); } if (document.readyState === "interactive") { - if (document.getElementById('aside')) { - initHighlightHeadline(); - } + if (document.getElementById('aside')) { + initHighlightHeadline(); + } } else { - window.addEventListener("DOMContentLoaded", () => { - if (document.getElementById('aside')) { - initHighlightHeadline(); - } - }); + window.addEventListener("DOMContentLoaded", () => { + if (document.getElementById('aside')) { + initHighlightHeadline(); + } + }); } \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index 800b6bd0..09dcb987 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -4,4 +4,3 @@ import './resizeObserver.js'; import './mediaqueries.js'; import './highlightHeadline.js'; import './anchorlinks.js'; -//import './aside.js'; \ No newline at end of file diff --git a/assets/js/mobileMenu.js b/assets/js/mobileMenu.js index d86076db..46a9107e 100644 --- a/assets/js/mobileMenu.js +++ b/assets/js/mobileMenu.js @@ -13,9 +13,6 @@ function initMobileMenu() { closeMobileMenu() }); - //TODO: window.onClick in mobileMenu.js und aside.js konsollidieren; momentan funktioniert es nicht gemeinsam. - //const target = initWindowOnClick(); - window.onclick = e => { //console.log(e.target); if (e.target.classList.contains('o-header__curtain')) { diff --git a/assets/js/windowOnClickHandling.js b/assets/js/windowOnClickHandling.js deleted file mode 100644 index af2e7114..00000000 --- a/assets/js/windowOnClickHandling.js +++ /dev/null @@ -1,5 +0,0 @@ -export function initWindowOnClick() { - window.onclick = e => { - return e.target; - } -} \ No newline at end of file diff --git a/assets/sass/sidemenu.scss b/assets/sass/sidemenu.scss index ee14c009..3587a5d2 100644 --- a/assets/sass/sidemenu.scss +++ b/assets/sass/sidemenu.scss @@ -23,30 +23,6 @@ margin-bottom: 1.6rem; } - //TODO: Bessere Benamung - .o-aside__mobile-container1 { - display: none; - - button { - display: flex; - border: 0; - width: 100%; - border-radius: var(--border-radius-m); - align-items: center; - justify-content: space-between; - } - } - - //TODO: Bessere Benamung - .o-aside__mobile-container2 { - display: block; - - @include media-breakpoint-down(lg) { - display: none; - justify-content: space-between; - } - } - .o-aside__mobile-container--open { @include media-breakpoint-down(lg) { display: block; diff --git a/layouts/partials/sidemenu.html b/layouts/partials/sidemenu.html index 644e9e12..9eb7f8ac 100644 --- a/layouts/partials/sidemenu.html +++ b/layouts/partials/sidemenu.html @@ -1,11 +1,5 @@