Skip to content

Commit 18f00ff

Browse files
committed
Allow a rootEl other than document to be used.
1 parent a418103 commit 18f00ff

File tree

1 file changed

+33
-25
lines changed

1 file changed

+33
-25
lines changed

src/js/lib/Scrollspy.jsx

+33-25
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export class Scrollspy extends React.Component {
1111
style: React.PropTypes.object,
1212
componentTag: React.PropTypes.string,
1313
offset: React.PropTypes.number,
14+
rootNode: React.PropTypes.node,
1415
}
1516
}
1617

@@ -21,6 +22,7 @@ export class Scrollspy extends React.Component {
2122
style: {},
2223
componentTag: 'ul',
2324
offset: 0,
25+
rootNode: document.documentElement,
2426
}
2527
}
2628

@@ -68,7 +70,8 @@ export class Scrollspy extends React.Component {
6870
}
6971

7072
const isLastItem = i === max - 1
71-
const isScrolled = (document.documentElement.scrollTop || document.body.scrollTop) > 0
73+
const isScrolled = this._rootNode.scrollTop > 0
74+
7275

7376
// https://github.com/makotot/react-scrollspy/pull/26#issue-167413769
7477
if (this._isAtBottom() && this._isInView(currentContent) && !isInView && isLastItem && isScrolled) {
@@ -95,22 +98,21 @@ export class Scrollspy extends React.Component {
9598
return false
9699
}
97100
const rect = el.getBoundingClientRect()
98-
const winH = window.innerHeight
99-
const doc = document
100-
const scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop
101-
const scrollBottom = scrollTop + winH
101+
const root = this._rootNode
102+
const rootRect = root.getBoundingClientRect()
103+
const scrollTop = root.scrollTop
104+
const scrollBottom = scrollTop + rootRect.height
102105
const elTop = rect.top + scrollTop + this.props.offset
103106
const elBottom = elTop + el.offsetHeight
104107

105108
return (elTop < scrollBottom) && (elBottom > scrollTop)
106109
}
107110

108111
_isAtBottom () {
109-
const doc = document
110-
const body = doc.body
111-
const scrollTop = (doc.documentElement && doc.documentElement.scrollTop) || body.scrollTop
112-
const scrollHeight = (doc.documentElement && doc.documentElement.scrollHeight) || body.scrollHeight
113-
const scrolledToBottom = (scrollTop + window.innerHeight) >= scrollHeight
112+
const rect = this._rootNode.getBoundingClientRect()
113+
const scrollTop = this._rootNode.scrollTop
114+
const scrollHeight = this._rootNode.scrollHeight
115+
const scrolledToBottom = scrollTop + rect.height >= scrollHeight
114116

115117
return scrolledToBottom
116118
}
@@ -142,36 +144,42 @@ export class Scrollspy extends React.Component {
142144
}
143145

144146
_handleSpy () {
145-
let timer
146-
147-
if (timer) {
148-
clearTimeout(timer)
149-
timer = null
150-
}
151-
timer = setTimeout(this._spy.bind(this), 100)
147+
setTimeout(() => this._spy(), 100)
152148
}
153149

154-
_initFromProps () {
155-
const targetItems = this._initSpyTarget(this.props.items)
150+
_initFromProps (props) {
151+
const targetItems = this._initSpyTarget(props.items)
156152

157153
this.setState({
158154
targetItems,
159155
})
160156

161-
this._spy(targetItems)
157+
setTimeout(() => this._spy(targetItems), 100)
158+
}
159+
160+
get _rootNode () {
161+
return this.props.rootNode || document.documentElement
162162
}
163163

164164
componentDidMount () {
165-
this._initFromProps()
166-
window.addEventListener('scroll', this._handleSpy)
165+
this._initFromProps(this.props)
166+
this._rootNode.addEventListener('scroll', this._handleSpy)
167167
}
168168

169169
componentWillUnmount () {
170-
window.removeEventListener('scroll', this._handleSpy)
170+
this._rootNode.removeEventListener('scroll', this._handleSpy)
171171
}
172172

173-
componentWillReceiveProps () {
174-
this._initFromProps()
173+
componentWillReceiveProps (nextProps) {
174+
this._rootNode.removeEventListener('scroll', this._handleSpy)
175+
176+
if (nextProps.rootNode) {
177+
nextProps.rootNode.addEventListener('scroll', this._handleSpy)
178+
} else {
179+
document.documentElement.addEventListener('scroll', this._handleSpy)
180+
}
181+
182+
this._initFromProps(nextProps)
175183
}
176184

177185
render () {

0 commit comments

Comments
 (0)