From 6f461132c00c7f7d557e0b865530bb256c1fe5be Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 19 Oct 2024 21:13:21 +0800 Subject: [PATCH] refactor: improve toc popup module --- _javascript/modules/components/toc.js | 5 +- .../modules/components/toc/toc-mobile.js | 48 ++++++++++--------- _layouts/post.html | 6 +-- _sass/layout/post.scss | 24 ++++++---- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/_javascript/modules/components/toc.js b/_javascript/modules/components/toc.js index 765336a..e9086ee 100644 --- a/_javascript/modules/components/toc.js +++ b/_javascript/modules/components/toc.js @@ -5,7 +5,10 @@ const desktopMode = matchMedia('(min-width: 1200px)'); function refresh(e) { if (e.matches) { - mobile.hidePopup(); + if (mobile.popupOpened) { + mobile.hidePopup(); + } + desktop.refresh(); } else { mobile.refresh(); diff --git a/_javascript/modules/components/toc/toc-mobile.js b/_javascript/modules/components/toc/toc-mobile.js index 8d717dd..20e24a7 100644 --- a/_javascript/modules/components/toc/toc-mobile.js +++ b/_javascript/modules/components/toc/toc-mobile.js @@ -12,8 +12,8 @@ const SCROLL_LOCK = 'overflow-hidden'; const CLOSING = 'closing'; export class TocMobile { - static invisible = true; - static barHeight = 16 * 3; // 3rem + static #invisible = true; + static #barHeight = 16 * 3; // 3rem static options = { tocSelector: '#toc-popup-content', @@ -23,7 +23,7 @@ export class TocMobile { orderedList: false, scrollSmooth: false, collapseDepth: 4, - headingsOffset: this.barHeight + headingsOffset: this.#barHeight }; static initBar() { @@ -33,44 +33,40 @@ export class TocMobile { $tocBar.classList.toggle('invisible', entry.isIntersecting); }); }, - { rootMargin: `-${this.barHeight}px 0px 0px 0px` } + { rootMargin: `-${this.#barHeight}px 0px 0px 0px` } ); observer.observe($soloTrigger); - this.invisible = false; + this.#invisible = false; } static listenAnchors() { const $anchors = document.getElementsByClassName('toc-link'); [...$anchors].forEach((anchor) => { - anchor.onclick = this.hidePopup; + anchor.onclick = () => this.hidePopup(); }); } static refresh() { - if (this.invisible) { + if (this.#invisible) { this.initComponents(); } tocbot.refresh(this.options); this.listenAnchors(); } + static get popupOpened() { + return $popup.open; + } + static showPopup() { - TocMobile.lockScroll(true); + this.lockScroll(true); $popup.showModal(); const activeItem = $popup.querySelector('li.is-active-li'); activeItem.scrollIntoView({ block: 'center' }); } - static hidePopup(event) { - if (event?.type === 'cancel') { - event.preventDefault(); - } - - if (!$popup.open) { - return; - } - + static hidePopup() { $popup.toggleAttribute(CLOSING); $popup.addEventListener( @@ -82,7 +78,7 @@ export class TocMobile { { once: true } ); - TocMobile.lockScroll(false); + this.lockScroll(false); } static lockScroll(enable) { @@ -91,6 +87,10 @@ export class TocMobile { } static clickBackdrop(event) { + if ($popup.hasAttribute(CLOSING)) { + return; + } + const rect = event.target.getBoundingClientRect(); if ( event.clientX < rect.left || @@ -98,7 +98,7 @@ export class TocMobile { event.clientY < rect.top || event.clientY > rect.bottom ) { - TocMobile.hidePopup(); + this.hidePopup(); } } @@ -106,11 +106,15 @@ export class TocMobile { this.initBar(); [...$triggers].forEach((trigger) => { - trigger.onclick = this.showPopup; + trigger.onclick = () => this.showPopup(); }); - $popup.onclick = this.clickBackdrop; - $btnClose.onclick = $popup.oncancel = this.hidePopup; + $popup.onclick = (e) => this.clickBackdrop(e); + $btnClose.onclick = () => this.hidePopup(); + $popup.oncancel = (e) => { + e.preventDefault(); + this.hidePopup(); + }; } static init() { diff --git a/_layouts/post.html b/_layouts/post.html index bcc133f..6a2deff 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -100,7 +100,7 @@ tail_includes: {% if enable_toc %} @@ -113,8 +113,8 @@ tail_includes:
{{- page.title -}}
-
diff --git a/_sass/layout/post.scss b/_sass/layout/post.scss index be72700..01021f3 100644 --- a/_sass/layout/post.scss +++ b/_sass/layout/post.scss @@ -380,12 +380,13 @@ header { $slide-in: slide-in 0.3s ease-out; $slide-out: slide-out 0.3s ease-out; $curtain-height: 2rem; + $backdrop: blur(5px); border-color: var(--toc-popup-border-color); border-width: 1px; border-radius: $radius-lg; color: var(--text-color); - background: var(--main-bg); + background: var(--card-bg); margin-top: $topbar-height; min-width: 20rem; font-size: 1.05rem; @@ -422,8 +423,15 @@ header { } } - button:focus-visible { - box-shadow: none; + button { + > i { + font-size: 1.25rem; + vertical-align: middle; + } + + &:focus-visible { + box-shadow: none; + } } ul { @@ -461,20 +469,20 @@ header { } &::-webkit-backdrop { - -webkit-backdrop-filter: blur(5px); - backdrop-filter: blur(5px); + -webkit-backdrop-filter: $backdrop; + backdrop-filter: $backdrop; } &::backdrop { - -webkit-backdrop-filter: blur(5px); - backdrop-filter: blur(5px); + -webkit-backdrop-filter: $backdrop; + backdrop-filter: $backdrop; } &::after { display: flex; content: ''; position: relative; - background: linear-gradient(transparent, var(--main-bg) 70%); + background: linear-gradient(transparent, var(--card-bg) 70%); height: $curtain-height; }