11import React from 'react' ;
2+ import ReactDom from 'react-dom' ;
23import { PropTypes } from 'prop-types' ;
34import debounce from 'lodash.debounce' ;
45import throttle from 'lodash.throttle' ;
56import isIntersectionObserverAvailable from '../utils/intersection-observer' ;
7+ import getScrollElement from '../utils/get-scroll-element' ;
8+
9+ const getScrollX = ( ) => typeof window === 'undefined' ?
10+ 0 : ( window . scrollX || window . pageXOffset ) ;
11+ const getScrollY = ( ) => typeof window === 'undefined' ?
12+ 0 : ( window . scrollY || window . pageYOffset ) ;
613
714const trackWindowScroll = ( BaseComponent ) => {
815 class ScrollAwareComponent extends React . Component {
@@ -23,48 +30,76 @@ const trackWindowScroll = (BaseComponent) => {
2330
2431 this . state = {
2532 scrollPosition : {
26- x : ( typeof window === 'undefined' ?
27- 0 :
28- ( window . scrollX || window . pageXOffset )
29- ) ,
30- y : ( typeof window === 'undefined' ?
31- 0 :
32- ( window . scrollY || window . pageYOffset )
33- ) ,
33+ x : getScrollX ( ) ,
34+ y : getScrollY ( ) ,
3435 } ,
3536 } ;
37+
38+ this . baseComponentRef = React . createRef ( ) ;
3639 }
3740
3841 componentDidMount ( ) {
39- if ( typeof window == 'undefined' || isIntersectionObserverAvailable ( ) ) {
42+ this . addListeners ( ) ;
43+ }
44+
45+ componentWillUnmount ( ) {
46+ this . removeListeners ( ) ;
47+ }
48+
49+ componentDidUpdate ( ) {
50+ if ( typeof window === 'undefined' || isIntersectionObserverAvailable ( ) ) {
51+ return ;
52+ }
53+
54+ const scrollElement = getScrollElement (
55+ ReactDom . findDOMNode ( this . baseComponentRef . current )
56+ ) ;
57+
58+ if ( scrollElement !== this . scrollElement ) {
59+ this . removeListeners ( ) ;
60+ this . addListeners ( ) ;
61+ }
62+ }
63+
64+ addListeners ( ) {
65+ if ( typeof window === 'undefined' || isIntersectionObserverAvailable ( ) ) {
4066 return ;
4167 }
42- window . addEventListener ( 'scroll' , this . delayedScroll ) ;
68+
69+ this . scrollElement = getScrollElement (
70+ ReactDom . findDOMNode ( this . baseComponentRef . current )
71+ ) ;
72+
73+ this . scrollElement . addEventListener ( 'scroll' , this . delayedScroll ) ;
4374 window . addEventListener ( 'resize' , this . delayedScroll ) ;
75+
76+ if ( this . scrollElement !== window ) {
77+ window . addEventListener ( 'scroll' , this . delayedScroll ) ;
78+ }
4479 }
4580
46- componentWillUnmount ( ) {
81+ removeListeners ( ) {
4782 if ( typeof window == 'undefined' || isIntersectionObserverAvailable ( ) ) {
4883 return ;
4984 }
50- window . removeEventListener ( 'scroll' , this . delayedScroll ) ;
85+
86+ this . scrollElement . removeEventListener ( 'scroll' , this . delayedScroll ) ;
5187 window . removeEventListener ( 'resize' , this . delayedScroll ) ;
88+
89+ if ( this . scrollElement !== window ) {
90+ window . removeEventListener ( 'scroll' , this . delayedScroll ) ;
91+ }
5292 }
5393
5494 onChangeScroll ( ) {
5595 if ( isIntersectionObserverAvailable ( ) ) {
5696 return ;
5797 }
98+
5899 this . setState ( {
59100 scrollPosition : {
60- x : ( typeof window == 'undefined' ?
61- 0 :
62- ( window . scrollX || window . pageXOffset )
63- ) ,
64- y : ( typeof window === 'undefined' ?
65- 0 :
66- ( window . scrollY || window . pageYOffset )
67- ) ,
101+ x : getScrollX ( ) ,
102+ y : getScrollY ( ) ,
68103 } ,
69104 } ) ;
70105 }
@@ -76,6 +111,7 @@ const trackWindowScroll = (BaseComponent) => {
76111
77112 return (
78113 < BaseComponent
114+ ref = { this . baseComponentRef }
79115 scrollPosition = { scrollPosition }
80116 { ...props } />
81117 ) ;
0 commit comments