Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/js/src/util
diff options
context:
space:
mode:
authorGeoSot <geo.sotis@gmail.com>2021-06-06 09:26:36 +0300
committerGitHub <noreply@github.com>2021-06-06 09:26:36 +0300
commitcb47b8c9640abcc19c17908475153849b9d4ad60 (patch)
tree574ef4e05facb52e35d4a939e4d69d963106a43b /js/src/util
parent08139c2280d60e4904f2bb7c7477f05cc3d34b1a (diff)
Refactor scrollbar.js to be used as a Class (#33947)
Diffstat (limited to 'js/src/util')
-rw-r--r--js/src/util/scrollbar.js121
1 files changed, 67 insertions, 54 deletions
diff --git a/js/src/util/scrollbar.js b/js/src/util/scrollbar.js
index 79a3b12c78..e23415f1dc 100644
--- a/js/src/util/scrollbar.js
+++ b/js/src/util/scrollbar.js
@@ -7,78 +7,91 @@
import SelectorEngine from '../dom/selector-engine'
import Manipulator from '../dom/manipulator'
+import { isElement } from './index'
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
const SELECTOR_STICKY_CONTENT = '.sticky-top'
-const 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)
-}
+class ScrollBarHelper {
+ constructor() {
+ this._element = document.body
+ }
-const hide = (width = getWidth()) => {
- _disableOverFlow()
- // give padding to element to balances the hidden scrollbar width
- _setElementAttributes('body', 'paddingRight', calculatedValue => calculatedValue + width)
- // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements, to keep shown fullwidth
- _setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width)
- _setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width)
-}
+ 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)
+ }
-const _disableOverFlow = () => {
- const actualValue = document.body.style.overflow
- if (actualValue) {
- Manipulator.setDataAttribute(document.body, 'overflow', actualValue)
+ hide() {
+ const width = this.getWidth()
+ this._disableOverFlow()
+ // give padding to element to balance the hidden scrollbar width
+ this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width)
+ // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
+ this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width)
+ this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width)
}
- document.body.style.overflow = 'hidden'
-}
+ _disableOverFlow() {
+ this._saveInitialAttribute(this._element, 'overflow')
+ this._element.style.overflow = 'hidden'
+ }
-const _setElementAttributes = (selector, styleProp, callback) => {
- const scrollbarWidth = getWidth()
- SelectorEngine.find(selector)
- .forEach(element => {
- if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
+ _setElementAttributes(selector, styleProp, callback) {
+ const scrollbarWidth = this.getWidth()
+ const manipulationCallBack = element => {
+ if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
return
}
- const actualValue = element.style[styleProp]
- if (actualValue) {
- Manipulator.setDataAttribute(element, styleProp, actualValue)
- }
-
+ this._saveInitialAttribute(element, styleProp)
const calculatedValue = window.getComputedStyle(element)[styleProp]
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`
- })
-}
+ }
-const reset = () => {
- _resetElementAttributes('body', 'overflow')
- _resetElementAttributes('body', 'paddingRight')
- _resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight')
- _resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight')
-}
+ this._applyManipulationCallback(selector, manipulationCallBack)
+ }
+
+ reset() {
+ this._resetElementAttributes(this._element, 'overflow')
+ this._resetElementAttributes(this._element, 'paddingRight')
+ this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight')
+ this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight')
+ }
+
+ _saveInitialAttribute(element, styleProp) {
+ const actualValue = element.style[styleProp]
+ if (actualValue) {
+ Manipulator.setDataAttribute(element, styleProp, actualValue)
+ }
+ }
+
+ _resetElementAttributes(selector, styleProp) {
+ const manipulationCallBack = element => {
+ const value = Manipulator.getDataAttribute(element, styleProp)
+ if (typeof value === 'undefined') {
+ element.style.removeProperty(styleProp)
+ } else {
+ Manipulator.removeDataAttribute(element, styleProp)
+ element.style[styleProp] = value
+ }
+ }
-const _resetElementAttributes = (selector, styleProp) => {
- SelectorEngine.find(selector).forEach(element => {
- const value = Manipulator.getDataAttribute(element, styleProp)
- if (typeof value === 'undefined') {
- element.style.removeProperty(styleProp)
+ this._applyManipulationCallback(selector, manipulationCallBack)
+ }
+
+ _applyManipulationCallback(selector, callBack) {
+ if (isElement(selector)) {
+ callBack(selector)
} else {
- Manipulator.removeDataAttribute(element, styleProp)
- element.style[styleProp] = value
+ SelectorEngine.find(selector, this._element).forEach(callBack)
}
- })
-}
+ }
-const isBodyOverflowing = () => {
- return getWidth() > 0
+ isOverflowing() {
+ return this.getWidth() > 0
+ }
}
-export {
- getWidth,
- hide,
- isBodyOverflowing,
- reset
-}
+export default ScrollBarHelper