[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 import { E as EventHandler, S as SelectorEngine, d as defineJQueryPlugin, B as BaseComponent, f as getSelectorFromElement, M as Manipulator, h as getElement, a as typeCheckConfig } from './dom.js?5.1.3'; 2 3 /** 4 * -------------------------------------------------------------------------- 5 * Bootstrap (v5.1.3): scrollspy.js 6 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 7 * -------------------------------------------------------------------------- 8 */ 9 /** 10 * ------------------------------------------------------------------------ 11 * Constants 12 * ------------------------------------------------------------------------ 13 */ 14 15 const NAME = 'scrollspy'; 16 const DATA_KEY = 'bs.scrollspy'; 17 const EVENT_KEY = `.$DATA_KEY}`; 18 const DATA_API_KEY = '.data-api'; 19 const Default = { 20 offset: 10, 21 method: 'auto', 22 target: '' 23 }; 24 const DefaultType = { 25 offset: 'number', 26 method: 'string', 27 target: '(string|element)' 28 }; 29 const EVENT_ACTIVATE = `activate$EVENT_KEY}`; 30 const EVENT_SCROLL = `scroll$EVENT_KEY}`; 31 const EVENT_LOAD_DATA_API = `load$EVENT_KEY}$DATA_API_KEY}`; 32 const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; 33 const CLASS_NAME_ACTIVE = 'active'; 34 const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'; 35 const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'; 36 const SELECTOR_NAV_LINKS = '.nav-link'; 37 const SELECTOR_NAV_ITEMS = '.nav-item'; 38 const SELECTOR_LIST_ITEMS = '.list-group-item'; 39 const SELECTOR_LINK_ITEMS = `$SELECTOR_NAV_LINKS}, $SELECTOR_LIST_ITEMS}, .$CLASS_NAME_DROPDOWN_ITEM}`; 40 const SELECTOR_DROPDOWN = '.dropdown'; 41 const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'; 42 const METHOD_OFFSET = 'offset'; 43 const METHOD_POSITION = 'position'; 44 /** 45 * ------------------------------------------------------------------------ 46 * Class Definition 47 * ------------------------------------------------------------------------ 48 */ 49 50 class ScrollSpy extends BaseComponent { 51 constructor(element, config) { 52 super(element); 53 this._scrollElement = this._element.tagName === 'BODY' ? window : this._element; 54 this._config = this._getConfig(config); 55 this._offsets = []; 56 this._targets = []; 57 this._activeTarget = null; 58 this._scrollHeight = 0; 59 EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process()); 60 this.refresh(); 61 62 this._process(); 63 } // Getters 64 65 66 static get Default() { 67 return Default; 68 } 69 70 static get NAME() { 71 return NAME; 72 } // Public 73 74 75 refresh() { 76 const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION; 77 const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method; 78 const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0; 79 this._offsets = []; 80 this._targets = []; 81 this._scrollHeight = this._getScrollHeight(); 82 const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target); 83 targets.map(element => { 84 const targetSelector = getSelectorFromElement(element); 85 const target = targetSelector ? SelectorEngine.findOne(targetSelector) : null; 86 87 if (target) { 88 const targetBCR = target.getBoundingClientRect(); 89 90 if (targetBCR.width || targetBCR.height) { 91 return [Manipulator[offsetMethod](target).top + offsetBase, targetSelector]; 92 } 93 } 94 95 return null; 96 }).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => { 97 this._offsets.push(item[0]); 98 99 this._targets.push(item[1]); 100 }); 101 } 102 103 dispose() { 104 EventHandler.off(this._scrollElement, EVENT_KEY); 105 super.dispose(); 106 } // Private 107 108 109 _getConfig(config) { 110 config = { ...Default, 111 ...Manipulator.getDataAttributes(this._element), 112 ...(typeof config === 'object' && config ? config : {}) 113 }; 114 config.target = getElement(config.target) || document.documentElement; 115 typeCheckConfig(NAME, config, DefaultType); 116 return config; 117 } 118 119 _getScrollTop() { 120 return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; 121 } 122 123 _getScrollHeight() { 124 return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); 125 } 126 127 _getOffsetHeight() { 128 return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; 129 } 130 131 _process() { 132 const scrollTop = this._getScrollTop() + this._config.offset; 133 134 const scrollHeight = this._getScrollHeight(); 135 136 const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight(); 137 138 if (this._scrollHeight !== scrollHeight) { 139 this.refresh(); 140 } 141 142 if (scrollTop >= maxScroll) { 143 const target = this._targets[this._targets.length - 1]; 144 145 if (this._activeTarget !== target) { 146 this._activate(target); 147 } 148 149 return; 150 } 151 152 if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { 153 this._activeTarget = null; 154 155 this._clear(); 156 157 return; 158 } 159 160 for (let i = this._offsets.length; i--;) { 161 const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]); 162 163 if (isActiveTarget) { 164 this._activate(this._targets[i]); 165 } 166 } 167 } 168 169 _activate(target) { 170 this._activeTarget = target; 171 172 this._clear(); 173 174 const queries = SELECTOR_LINK_ITEMS.split(',').map(selector => `$selector}[data-bs-target="$target}"],$selector}[href="$target}"]`); 175 const link = SelectorEngine.findOne(queries.join(','), this._config.target); 176 link.classList.add(CLASS_NAME_ACTIVE); 177 178 if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { 179 SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE); 180 } else { 181 SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP).forEach(listGroup => { 182 // Set triggered links parents as active 183 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor 184 SelectorEngine.prev(listGroup, `$SELECTOR_NAV_LINKS}, $SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE)); // Handle special case when .nav-link is inside .nav-item 185 186 SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => { 187 SelectorEngine.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE)); 188 }); 189 }); 190 } 191 192 EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, { 193 relatedTarget: target 194 }); 195 } 196 197 _clear() { 198 SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target).filter(node => node.classList.contains(CLASS_NAME_ACTIVE)).forEach(node => node.classList.remove(CLASS_NAME_ACTIVE)); 199 } // Static 200 201 202 static jQueryInterface(config) { 203 return this.each(function () { 204 const data = ScrollSpy.getOrCreateInstance(this, config); 205 206 if (typeof config !== 'string') { 207 return; 208 } 209 210 if (typeof data[config] === 'undefined') { 211 throw new TypeError(`No method named "$config}"`); 212 } 213 214 data[config](); 215 }); 216 } 217 218 } 219 /** 220 * ------------------------------------------------------------------------ 221 * Data Api implementation 222 * ------------------------------------------------------------------------ 223 */ 224 225 226 EventHandler.on(window, EVENT_LOAD_DATA_API, () => { 227 SelectorEngine.find(SELECTOR_DATA_SPY).forEach(spy => new ScrollSpy(spy)); 228 }); 229 /** 230 * ------------------------------------------------------------------------ 231 * jQuery 232 * ------------------------------------------------------------------------ 233 * add .ScrollSpy to jQuery only if jQuery is present 234 */ 235 236 defineJQueryPlugin(ScrollSpy); 237 238 window.bootstrap = window.bootstrap || {}; 239 window.bootstrap.Scrollspy = ScrollSpy; 240 241 if (Joomla && Joomla.getOptions) { 242 // Get the elements/configurations from the PHP 243 const scrollspys = Joomla.getOptions('bootstrap.scrollspy'); // Initialise the elements 244 245 if (typeof scrollspys === 'object' && scrollspys !== null) { 246 Object.keys(scrollspys).forEach(scrollspy => { 247 const opt = scrollspys[scrollspy]; 248 const options = { 249 offset: opt.offset ? opt.offset : 10, 250 method: opt.method ? opt.method : 'auto' 251 }; 252 253 if (opt.target) { 254 options.target = opt.target; 255 } 256 257 const elements = Array.from(document.querySelectorAll(scrollspy)); 258 259 if (elements.length) { 260 elements.map(el => new window.bootstrap.Scrollspy(el, options)); 261 } 262 }); 263 } 264 } 265 266 export { ScrollSpy as S };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |