From 162cbf1da6656a55d9e7f2cca5e883a57a356eac Mon Sep 17 00:00:00 2001 From: Nguyen Huu Kim Date: Wed, 18 Sep 2024 21:48:11 +0700 Subject: [PATCH] fix: v2.5.0 breaks implementation with headings Ref: #59 --- demo/dist/simple-scrollspy.min.js | 2 +- demo/toc.html | 46 ++++++--- src/scrollspy.ts | 155 ++++++++++++++++++------------ 3 files changed, 128 insertions(+), 75 deletions(-) diff --git a/demo/dist/simple-scrollspy.min.js b/demo/dist/simple-scrollspy.min.js index 019f1fd..8effd89 100644 --- a/demo/dist/simple-scrollspy.min.js +++ b/demo/dist/simple-scrollspy.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.scrollSpy=e():t.scrollSpy=e()}(self,(()=>(()=>{"use strict";var t={37:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.ScrollSpy=void 0;e.ScrollSpy=class{menuList;options;scroller;sections;activeItem=null;constructor(t,e={}){if(!t)throw new Error("Your navigation query selector is the first argument.");if("object"!=typeof e)throw new Error("The second argument must be an instance of an Object.");e.smoothScroll=!0===e.smoothScroll&&{}||e.smoothScroll,this.menuList=t instanceof HTMLElement?t:document.querySelector(t),this.options=Object.assign({},{sectionClass:".scrollspy",menuActiveTarget:"li > a",offset:0,hrefAttribute:"href",activeClass:"active",scrollContainer:"",smoothScroll:{}},e),this.options.scrollContainer?this.scroller=this.options.scrollContainer instanceof HTMLElement?this.options.scrollContainer:document.querySelector(this.options.scrollContainer):this.scroller=window,this.sections=document.querySelectorAll(this.options.sectionClass),this.attachEventListeners()}attachEventListeners(){if(this.scroller&&(this.scroller.addEventListener("scroll",(()=>this.onScroll())),this.options.smoothScroll&&this.menuList)){this.menuList.querySelectorAll(this.options.menuActiveTarget).forEach((t=>t.addEventListener("click",this.onClick.bind(this))))}}onClick(t){if(t.target){const e=t.target.getAttribute(this.options.hrefAttribute);if(e){const o=document.querySelector(e);o&&this.options.smoothScroll&&(t.preventDefault(),this.scrollTo(o))}}}onScroll(){const t=this.getSectionInView(),e=this.getMenuItemBySection(t);if(!t||!e)return this.removeCurrentActive();const o=e?.getAttribute(this.options.hrefAttribute),s=this.activeItem?.getAttribute(this.options.hrefAttribute);e&&o&&o!==s&&(this.removeCurrentActive({ignore:e}),this.setActive(e))}scrollTo(t){const e="function"==typeof this.options.smoothScrollBehavior&&this.options.smoothScrollBehavior;e?e(t,this.options.smoothScroll):t.scrollIntoView({...!0===this.options.smoothScroll?{}:this.options.smoothScroll,behavior:"smooth"})}getMenuItemBySection(t){if(!t||!this.menuList)return;const e=t.getAttribute("id");return this.menuList.querySelector(`[${this.options.hrefAttribute}="#${e}"]`)}getSectionInView(){for(let t=0;te&&s<=o)return this.sections[t]}}setActive(t){this.activeItem=t;this.activeItem.classList.contains(this.options.activeClass)||(this.activeItem.classList.add(this.options.activeClass),"function"==typeof this.options.onActive&&this.options.onActive(this.activeItem))}removeCurrentActive({ignore:t}={}){if(this.activeItem)this.activeItem.classList.remove(this.options.activeClass),this.activeItem=null;else if(this.menuList){const{hrefAttribute:e,menuActiveTarget:o,activeClass:s}=this.options,i=t?`${o}.${s}:not([${e}="${t.getAttribute(e)}"])`:`${o}.${s}`;this.menuList.querySelectorAll(i).forEach((t=>t.classList.remove(this.options.activeClass)))}}}}},e={};function o(s){var i=e[s];if(void 0!==i)return i.exports;var r=e[s]={exports:{}};return t[s](r,r.exports,o),r.exports}var s={};return(()=>{var t=s;const e=o(37);t.default=(t,o={})=>{const s=new e.ScrollSpy(t,o);return s.onScroll(),window.addEventListener("scroll",(()=>s.onScroll())),s}})(),s=s.default})())); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.scrollSpy=e():t.scrollSpy=e()}(self,(()=>(()=>{"use strict";var t={37:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.ScrollSpy=void 0;e.ScrollSpy=class{menuList;options;scroller;sections;activeItem=null;constructor(t,e={}){if(!t)throw new Error("Your navigation query selector is the first argument.");if("object"!=typeof e)throw new Error("The second argument must be an instance of an Object.");e.smoothScroll=!0===e.smoothScroll&&{}||e.smoothScroll,this.menuList=t instanceof HTMLElement?t:document.querySelector(t),this.options=Object.assign({},{sectionClass:".scrollspy",menuActiveTarget:"li > a",offset:0,hrefAttribute:"href",activeClass:"active",scrollContainer:"",smoothScroll:{}},e),this.options.scrollContainer?this.scroller=this.options.scrollContainer instanceof HTMLElement?this.options.scrollContainer:document.querySelector(this.options.scrollContainer):this.scroller=window,this.sections=document.querySelectorAll(this.options.sectionClass),this.attachEventListeners()}attachEventListeners(){if(this.scroller&&(this.scroller.addEventListener("scroll",(()=>this.onScroll())),this.options.smoothScroll&&this.menuList)){this.menuList.querySelectorAll(this.options.menuActiveTarget).forEach((t=>t.addEventListener("click",this.onClick.bind(this))))}}onClick(t){if(t.target){const e=t.target.getAttribute(this.options.hrefAttribute);if(e){const o=document.querySelector(e);o&&this.options.smoothScroll&&(t.preventDefault(),this.scrollTo(o))}}}onScroll(){const t=this.getSectionInView(),e=this.getMenuItemBySection(t);if(!t||!e)return;const o=e?.getAttribute(this.options.hrefAttribute),s=this.activeItem?.getAttribute(this.options.hrefAttribute);e&&o&&o!==s&&(this.removeCurrentActive({ignore:e}),this.setActive(e))}scrollTo(t){const e="function"==typeof this.options.smoothScrollBehavior&&this.options.smoothScrollBehavior;e?e(t,this.options.smoothScroll):t.scrollIntoView({...!0===this.options.smoothScroll?{}:this.options.smoothScroll,behavior:"smooth"})}getMenuItemBySection(t){if(!t||!this.menuList)return;const e=t.getAttribute("id");return this.menuList.querySelector(`[${this.options.hrefAttribute}="#${e}"]`)}getSectionInView(){for(let t=0;te&&s<=o)return this.sections[t]}}setActive(t){this.activeItem=t;this.activeItem.classList.contains(this.options.activeClass)||(this.activeItem.classList.add(this.options.activeClass),"function"==typeof this.options.onActive&&this.options.onActive(this.activeItem))}removeCurrentActive({ignore:t}={}){if(this.activeItem)this.activeItem.classList.remove(this.options.activeClass),this.activeItem=null;else if(this.menuList){const{hrefAttribute:e,menuActiveTarget:o,activeClass:s}=this.options,i=t?`${o}.${s}:not([${e}="${t.getAttribute(e)}"])`:`${o}.${s}`;this.menuList.querySelectorAll(i).forEach((t=>t.classList.remove(this.options.activeClass)))}}}}},e={};function o(s){var i=e[s];if(void 0!==i)return i.exports;var r=e[s]={exports:{}};return t[s](r,r.exports,o),r.exports}var s={};return(()=>{var t=s;const e=o(37);t.default=(t,o={})=>{const s=new e.ScrollSpy(t,o);return s.onScroll(),window.addEventListener("scroll",(()=>s.onScroll())),s}})(),s=s.default})())); \ No newline at end of file diff --git a/demo/toc.html b/demo/toc.html index eda9a68..bec1e00 100644 --- a/demo/toc.html +++ b/demo/toc.html @@ -190,8 +190,11 @@
-
-

+
+

Section 1: Lorem ipsum dolor sit amet consectetur.

@@ -218,8 +221,11 @@

-
-

+
+

Section 2: Lorem, ipsum dolor.

@@ -244,8 +250,11 @@

-
-

+
+

Section 3: Lorem ipsum dolor sit amet consectetur.

@@ -258,8 +267,11 @@

-
-

+
+

Section 4: Lorem ipsum dolor sit amet consectetur.

@@ -286,8 +298,11 @@

-
-

+
+

Section 5: Lorem, ipsum dolor.

@@ -312,8 +327,11 @@

-
-

+
+

Section 6: Lorem ipsum dolor sit amet consectetur.

@@ -441,9 +459,9 @@