From b02d1e1e381047eafc9fa373f138cabed746b1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Mon, 28 Mar 2022 18:51:21 +0200 Subject: [PATCH] Optimize and refactor getScrollElement --- src/hoc/trackWindowScroll.js | 6 ++--- src/utils/get-scroll-ancestor.ts | 35 ++++++++++++++++++++++++++++ src/utils/get-scroll-element.js | 39 -------------------------------- webpack.config.js | 5 +++- 4 files changed, 42 insertions(+), 43 deletions(-) create mode 100644 src/utils/get-scroll-ancestor.ts delete mode 100644 src/utils/get-scroll-element.js diff --git a/src/hoc/trackWindowScroll.js b/src/hoc/trackWindowScroll.js index 98a813b..1a2a4e5 100644 --- a/src/hoc/trackWindowScroll.js +++ b/src/hoc/trackWindowScroll.js @@ -4,7 +4,7 @@ import { PropTypes } from 'prop-types'; import debounce from 'lodash.debounce'; import throttle from 'lodash.throttle'; import isIntersectionObserverAvailable from '../utils/intersection-observer'; -import getScrollElement from '../utils/get-scroll-element'; +import getScrollAncestor from '../utils/get-scroll-ancestor'; const getScrollX = () => typeof window === 'undefined' ? 0 : window.scrollX || window.pageXOffset; @@ -54,7 +54,7 @@ const trackWindowScroll = BaseComponent => { return; } - const scrollElement = getScrollElement( + const scrollElement = getScrollAncestor( ReactDom.findDOMNode(this.baseComponentRef.current) ); @@ -69,7 +69,7 @@ const trackWindowScroll = BaseComponent => { return; } - this.scrollElement = getScrollElement( + this.scrollElement = getScrollAncestor( ReactDom.findDOMNode(this.baseComponentRef.current) ); diff --git a/src/utils/get-scroll-ancestor.ts b/src/utils/get-scroll-ancestor.ts new file mode 100644 index 0000000..b3b0e9f --- /dev/null +++ b/src/utils/get-scroll-ancestor.ts @@ -0,0 +1,35 @@ +// Adapted from https://github.com/loktar00/react-lazy-load/blob/master/src/utils/parentScroll.js + +const getElementOverflowValues = (element: HTMLElement) : string => { + const computedStyle = getComputedStyle(element, null); + + return ( + computedStyle.getPropertyValue('overflow') + + computedStyle.getPropertyValue('overflow-y') + + computedStyle.getPropertyValue('overflow-x') + ); +}; + +const getScrollAncestor = (element: Node) : HTMLElement | Window => { + if (!(element instanceof HTMLElement)) { + return window; + } + + let parent : Node = element; + + while (parent) { + if (!(parent instanceof HTMLElement)) { + break; + } + + if (/(scroll|auto)/.test(getElementOverflowValues(parent))) { + return parent; + } + + parent = parent.parentNode; + } + + return window; +}; + +export default getScrollAncestor; diff --git a/src/utils/get-scroll-element.js b/src/utils/get-scroll-element.js deleted file mode 100644 index 8f3c4c0..0000000 --- a/src/utils/get-scroll-element.js +++ /dev/null @@ -1,39 +0,0 @@ -// copyright https://github.com/loktar00/react-lazy-load/blob/master/src/utils/parentScroll.js - -const style = (element, prop) => - typeof getComputedStyle === 'undefined' - ? element.style[prop] - : getComputedStyle(element, null).getPropertyValue(prop); - -const overflow = element => - style(element, 'overflow') + - style(element, 'overflow-y') + - style(element, 'overflow-x'); - -const scrollParent = element => { - if (!(element instanceof HTMLElement)) { - return window; - } - - let parent = element; - - while (parent) { - if ( - parent === document.body || - parent === document.documentElement || - !parent.parentNode - ) { - break; - } - - if (/(scroll|auto)/.test(overflow(parent))) { - return parent; - } - - parent = parent.parentNode; - } - - return window; -}; - -export default scrollParent; diff --git a/webpack.config.js b/webpack.config.js index ad88b9f..1cd53b8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -12,7 +12,7 @@ module.exports = { module: { rules: [ { - test: /\.jsx?$/, + test: /\.(j|t)sx?$/, include: path.resolve(__dirname, 'src'), exclude: /(node_modules|bower_components|build)/, use: { @@ -46,4 +46,7 @@ module.exports = { extensions: ['js', 'jsx', 'ts', 'tsx'], }), ], + resolve: { + extensions: ['.ts', '.tsx', '.js', '.jsx'], + }, };