@@ -13,6 +13,7 @@ export default class Scrollspy extends React.Component {
1313 style : PropTypes . object ,
1414 componentTag : PropTypes . string ,
1515 offset : PropTypes . number ,
16+ rootEl : PropTypes . string ,
1617 }
1718 }
1819
@@ -60,6 +61,22 @@ export default class Scrollspy extends React.Component {
6061 return newArray
6162 }
6263
64+ _isScrolled ( ) {
65+ return this . _getScrollDimension ( ) . scrollTop > 0
66+ }
67+
68+ _getScrollDimension ( ) {
69+ const doc = document
70+ const { rootEl } = this . props
71+ const scrollTop = rootEl ? doc . querySelector ( rootEl ) . scrollTop : ( doc . documentElement . scrollTop || doc . body . parentNode . scrollTop || doc . body . scrollTop )
72+ const scrollHeight = rootEl ? doc . querySelector ( rootEl ) . scrollHeight : ( doc . documentElement . scrollHeight || doc . body . parentNode . scrollHeight || doc . body . scrollHeight )
73+
74+ return {
75+ scrollTop,
76+ scrollHeight,
77+ }
78+ }
79+
6380 _getElemsViewState ( targets ) {
6481 let elemsInView = [ ]
6582 let elemsOutView = [ ]
@@ -81,9 +98,7 @@ export default class Scrollspy extends React.Component {
8198 }
8299
83100 const isLastItem = i === max - 1
84- const doc = document
85- const body = document . body
86- const isScrolled = ( doc . documentElement || body . parentNode || body ) . scrollTop > 0
101+ const isScrolled = this . _isScrolled ( )
87102
88103 // https://github.com/makotot/react-scrollspy/pull/26#issue-167413769
89104 const isLastShortItemAtBottom = this . _isAtBottom ( ) && this . _isInView ( currentContent ) && ! isInView && isLastItem && isScrolled
@@ -111,24 +126,32 @@ export default class Scrollspy extends React.Component {
111126 if ( ! el ) {
112127 return false
113128 }
129+
130+ const { rootEl, offset } = this . props
131+ let rootRect
132+
133+ if ( rootEl ) {
134+ rootRect = document . querySelector ( rootEl ) . getBoundingClientRect ( )
135+ }
136+
114137 const rect = el . getBoundingClientRect ( )
115- const winH = window . innerHeight
116- const doc = document
117- const body = doc . body
118- const scrollTop = ( doc . documentElement || body . parentNode || body ) . scrollTop
138+ const winH = rootEl ? rootRect . height : window . innerHeight
139+ const { scrollTop } = this . _getScrollDimension ( )
119140 const scrollBottom = scrollTop + winH
120- const elTop = rect . top + scrollTop + this . props . offset
141+ const elTop = rootEl ?
142+ rect . top + scrollTop - rootRect . top + offset
143+ :
144+ rect . top + scrollTop + offset
121145 const elBottom = elTop + el . offsetHeight
122146
123147 return ( elTop < scrollBottom ) && ( elBottom > scrollTop )
124148 }
125149
126150 _isAtBottom ( ) {
127- const doc = document
128- const body = doc . body
129- const scrollTop = ( doc . documentElement || body . parentNode || body ) . scrollTop
130- const scrollHeight = ( doc . documentElement || body . parentNode || body ) . scrollHeight
131- const scrolledToBottom = ( scrollTop + window . innerHeight ) >= scrollHeight
151+ const { rootEl } = this . props
152+ const { scrollTop, scrollHeight } = this . _getScrollDimension ( )
153+ const winH = rootEl ? document . querySelector ( rootEl ) . getBoundingClientRect ( ) . height : window . innerHeight
154+ const scrolledToBottom = ( scrollTop + winH ) >= scrollHeight
132155
133156 return scrolledToBottom
134157 }
@@ -143,8 +166,10 @@ export default class Scrollspy extends React.Component {
143166 const scrolledPastItems = viewStatusList . map ( ( item ) => {
144167 if ( item && ! hasFoundInView ) {
145168 hasFoundInView = true
169+
146170 return false
147171 }
172+
148173 return ! hasFoundInView
149174 } )
150175
@@ -153,6 +178,7 @@ export default class Scrollspy extends React.Component {
153178
154179 _spy ( targets ) {
155180 const elemensViewState = this . _getElemsViewState ( targets )
181+
156182 this . setState ( {
157183 inViewState : elemensViewState . viewStatusList ,
158184 isScrolledPast : elemensViewState . scrolledPast
@@ -175,11 +201,15 @@ export default class Scrollspy extends React.Component {
175201
176202 componentDidMount ( ) {
177203 this . _initFromProps ( )
178- window . addEventListener ( 'scroll' , this . _handleSpy )
204+ const el = this . props . rootEl ? document . querySelector ( this . props . rootEl ) : window
205+
206+ el . addEventListener ( 'scroll' , this . _handleSpy )
179207 }
180208
181209 componentWillUnmount ( ) {
182- window . removeEventListener ( 'scroll' , this . _handleSpy )
210+ const el = this . props . rootEl ? document . querySelector ( this . props . rootEl ) : window
211+
212+ el . removeEventListener ( 'scroll' , this . _handleSpy )
183213 }
184214
185215 componentWillReceiveProps ( ) {
0 commit comments