forked from Amphiluke/handy-scroll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handy-scroll.es6.min.js
6 lines (6 loc) · 3.26 KB
/
handy-scroll.es6.min.js
1
2
3
4
5
6
/*!
handy-scroll v1.1.3
https://amphiluke.github.io/handy-scroll/
(c) 2023 Amphiluke
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).handyScroll=t()}(this,(function(){"use strict";let e=Array.prototype.slice,t="object"==typeof document&&!!document.documentElement,i={isDOMAvailable:t,doc:t?document:null,html:t?document.documentElement:null,body:t?document.body:null,ready(e){"loading"===i.doc.readyState?i.doc.addEventListener("DOMContentLoaded",(()=>{e()}),{once:!0}):e()},$:e=>"string"==typeof e?i.body.querySelector(e):e,$$:t=>Array.isArray(t)?t:t.nodeType===Node.ELEMENT_NODE?[t]:"string"==typeof t?e.call(i.body.querySelectorAll(t)):e.call(t)},n={init(e){let t=this,n=i.$$(".handy-scroll-body").filter((t=>t.contains(e)));n.length&&(t.scrollBody=n[0]),t.container=e,t.visible=!0,t.initWidget(),t.update(),t.addEventHandlers(),t.skipSyncContainer=t.skipSyncWidget=!1},initWidget(){let e=this,t=e.widget=i.doc.createElement("div");t.classList.add("handy-scroll");let n=i.doc.createElement("div");n.style.width=`${e.container.scrollWidth}px`,t.appendChild(n),e.container.appendChild(t)},addEventHandlers(){let e=this;(e.eventHandlers=[{el:e.scrollBody||window,handlers:{scroll(){e.checkVisibility()},resize(){e.update()}}},{el:e.widget,handlers:{scroll(){e.visible&&!e.skipSyncContainer&&e.syncContainer(),e.skipSyncContainer=!1}}},{el:e.container,handlers:{scroll(){e.skipSyncWidget||e.syncWidget(),e.skipSyncWidget=!1},focusin(){setTimeout((()=>{e.widget&&e.syncWidget()}),0)}}}]).forEach((({el:e,handlers:t})=>{Object.keys(t).forEach((i=>e.addEventListener(i,t[i],!1)))}))},checkVisibility(){let e=this,{widget:t,container:n,scrollBody:l}=e,o=t.scrollWidth<=t.offsetWidth;if(!o){let e=n.getBoundingClientRect(),t=l?l.getBoundingClientRect().bottom:window.innerHeight||i.html.clientHeight;o=e.bottom<=t||e.top>t}e.visible===o&&(e.visible=!o,t.classList.toggle("handy-scroll-hidden"))},syncContainer(){let e=this,{scrollLeft:t}=e.widget;e.container.scrollLeft!==t&&(e.skipSyncWidget=!0,e.container.scrollLeft=t)},syncWidget(){let e=this,{scrollLeft:t}=e.container;e.widget.scrollLeft!==t&&(e.skipSyncContainer=!0,e.widget.scrollLeft=t)},update(){let e=this,{widget:t,container:i,scrollBody:n}=e,{clientWidth:l,scrollWidth:o}=i;t.style.width=`${l}px`,n||(t.style.left=`${i.getBoundingClientRect().left}px`),t.firstElementChild.style.width=`${o}px`,o>l&&(t.style.height=t.offsetHeight-t.clientHeight+1+"px"),e.syncWidget(),e.checkVisibility()},destroy(){let e=this;e.eventHandlers.forEach((({el:e,handlers:t})=>{Object.keys(t).forEach((i=>e.removeEventListener(i,t[i],!1)))})),e.widget.parentNode.removeChild(e.widget),e.eventHandlers=e.widget=e.container=e.scrollBody=null}},l=[],o={mount(e){i.$$(e).forEach((e=>{if(o.mounted(e))return;let t=Object.create(n);l.push(t),t.init(e)}))},mounted(e){let t=i.$(e);return l.some((e=>e.container===t))},update(e){i.$$(e).forEach((e=>{l.some((t=>t.container===e&&(t.update(),!0)))}))},destroy(e){i.$$(e).forEach((e=>{l.some(((t,i)=>t.container===e&&(l.splice(i,1)[0].destroy(),!0)))}))},destroyDetached(){l=l.filter((e=>!!i.body.contains(e.container)||(e.destroy(),!1)))}};return i.isDOMAvailable&&i.ready((()=>{o.mount("[data-handy-scroll]")})),o}));