From 84cb7f1058d6dfec360ff1c7dbcd4a6753051bd5 Mon Sep 17 00:00:00 2001 From: Luffy <52o@qq52o.cn> Date: Fri, 3 Jan 2025 13:38:51 +0800 Subject: [PATCH 1/3] fix: Prevent initial unnecessary IntersectionObserver callback execution --- src/core/event/index.js | 30 +++++++++++++++++------------- src/core/render/compiler.js | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/core/event/index.js b/src/core/event/index.js index ef8a39b4c..c76430534 100644 --- a/src/core/event/index.js +++ b/src/core/event/index.js @@ -45,7 +45,7 @@ export function Events(Base) { // ========================================================================= /** * Initialize cover observer - * Toggles sticky behavior when when cover is not in view + * Toggles sticky behavior when cover is not in view * @void */ #initCover() { @@ -74,11 +74,17 @@ export function Events(Base) { #initHeadings() { const headingElms = dom.findAll('#main :where(h1, h2, h3, h4, h5)'); const headingsInView = new Set(); + let isInitialLoad = true; // Mark sidebar active item on heading intersection this.#intersectionObserver?.disconnect(); this.#intersectionObserver = new IntersectionObserver( entries => { + if (isInitialLoad) { + isInitialLoad = false; + return; + } + if (this.#isScrolling) { return; } @@ -89,18 +95,16 @@ export function Events(Base) { headingsInView[op](entry.target); } - const activeHeading = - headingsInView.size > 1 - ? // Sort headings by proximity to viewport top and select first - Array.from(headingsInView).sort((a, b) => - a.compareDocumentPosition(b) & - Node.DOCUMENT_POSITION_FOLLOWING - ? -1 - : 1, - )[0] - : // Get first and only item in set. - // May be undefined if no headings are in view. - headingsInView.values().next().value; + let activeHeading = undefined; + if (headingsInView.size === 1) { + activeHeading = headingsInView.values().next().value; + } else if (headingsInView.size > 1) { + activeHeading = Array.from(headingsInView).reduce((closest, current) => { + return !closest || (closest.compareDocumentPosition(current) & Node.DOCUMENT_POSITION_FOLLOWING) + ? current + : closest; + }, null); + } if (activeHeading) { const id = activeHeading.getAttribute('id'); diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index b86166301..124be9b7f 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -181,7 +181,7 @@ export class Compiler { } /** - * Compile sidebar, it uses _sidebar.md ( or specific file) or the content's headings toc to render sidebar. + * Compile sidebar, it uses _sidebar.md (or specific file) or the content's headings toc to render sidebar. * @param {String} text Text content from the sidebar file, maybe empty * @param {Number} level Type of heading (h tag) * @returns {String} Sidebar element From d0d438330fdb786d21e05283c15b8b431fc85e09 Mon Sep 17 00:00:00 2001 From: Luffy <52o@qq52o.cn> Date: Fri, 3 Jan 2025 13:45:03 +0800 Subject: [PATCH 2/3] chore: format code --- src/core/event/index.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/core/event/index.js b/src/core/event/index.js index c76430534..2bdacfcc8 100644 --- a/src/core/event/index.js +++ b/src/core/event/index.js @@ -99,11 +99,16 @@ export function Events(Base) { if (headingsInView.size === 1) { activeHeading = headingsInView.values().next().value; } else if (headingsInView.size > 1) { - activeHeading = Array.from(headingsInView).reduce((closest, current) => { - return !closest || (closest.compareDocumentPosition(current) & Node.DOCUMENT_POSITION_FOLLOWING) - ? current - : closest; - }, null); + activeHeading = Array.from(headingsInView).reduce( + (closest, current) => { + return !closest || + closest.compareDocumentPosition(current) & + Node.DOCUMENT_POSITION_FOLLOWING + ? current + : closest; + }, + null, + ); } if (activeHeading) { From 95f9098fcefc1af9702f586d0ec5c614e8615c37 Mon Sep 17 00:00:00 2001 From: sy-records <52o@qq52o.cn> Date: Sun, 5 Jan 2025 19:20:42 +0800 Subject: [PATCH 3/3] fix: add comments --- src/core/event/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/event/index.js b/src/core/event/index.js index 2bdacfcc8..fe4076f05 100644 --- a/src/core/event/index.js +++ b/src/core/event/index.js @@ -95,10 +95,14 @@ export function Events(Base) { headingsInView[op](entry.target); } - let activeHeading = undefined; + let activeHeading; if (headingsInView.size === 1) { + // Get first and only item in set. + // May be undefined if no headings are in view. activeHeading = headingsInView.values().next().value; } else if (headingsInView.size > 1) { + // Find the closest heading to the top of the viewport + // Reduce over the Set of headings currently in view (headingsInView) to determine the closest heading. activeHeading = Array.from(headingsInView).reduce( (closest, current) => { return !closest ||