Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | 3x 3x 3x 3x 100x 324x 324x 67x 67x 67x 67x 67x 32x 32x 32x 32x 2x 67x 67x 201x 201x 77x 2x 75x 75x 75x 201x 142x 142x 11x 128x 74x 74x 63x 63x 11x 11x 128x 329x 131x 131x 198x 20x | /** * -------------------------------------------------------------------------- * Bootstrap (v5.2.3): util/scrollBar.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ import SelectorEngine from '../dom/selector-engine' import Manipulator from '../dom/manipulator' import { isElement } from './index' /** * Constants */ const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' const SELECTOR_STICKY_CONTENT = '.sticky-top' const PROPERTY_PADDING = 'padding-right' const PROPERTY_MARGIN = 'margin-right' /** * Class definition */ class ScrollBarHelper { constructor() { this._element = document.body } // Public getWidth() { // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes const documentWidth = document.documentElement.clientWidth return Math.abs(window.innerWidth - documentWidth) } hide() { const width = this.getWidth() this._disableOverFlow() // give padding to element to balance the hidden scrollbar width this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width) // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width) this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width) } reset() { this._resetElementAttributes(this._element, 'overflow') this._resetElementAttributes(this._element, PROPERTY_PADDING) this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING) this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN) } isOverflowing() { return this.getWidth() > 0 } // Private _disableOverFlow() { this._saveInitialAttribute(this._element, 'overflow') this._element.style.overflow = 'hidden' } _setElementAttributes(selector, styleProperty, callback) { const scrollbarWidth = this.getWidth() const manipulationCallBack = element => { if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) { return } this._saveInitialAttribute(element, styleProperty) const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty) element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`) } this._applyManipulationCallback(selector, manipulationCallBack) } _saveInitialAttribute(element, styleProperty) { const actualValue = element.style.getPropertyValue(styleProperty) if (actualValue) { Manipulator.setDataAttribute(element, styleProperty, actualValue) } } _resetElementAttributes(selector, styleProperty) { const manipulationCallBack = element => { const value = Manipulator.getDataAttribute(element, styleProperty) // We only want to remove the property if the value is `null`; the value can also be zero if (value === null) { element.style.removeProperty(styleProperty) return } Manipulator.removeDataAttribute(element, styleProperty) element.style.setProperty(styleProperty, value) } this._applyManipulationCallback(selector, manipulationCallBack) } _applyManipulationCallback(selector, callBack) { if (isElement(selector)) { callBack(selector) return } for (const sel of SelectorEngine.find(selector, this._element)) { callBack(sel) } } } export default ScrollBarHelper |