Skip to content

Commit

Permalink
Merge pull request #186 from janczizikow/feat/passive-event-listeners
Browse files Browse the repository at this point in the history
feat: support passive event listeners
  • Loading branch information
janczizikow authored Dec 1, 2020
2 parents d6d54c8 + 3f1b2f5 commit 51b78c9
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 9 deletions.
77 changes: 68 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import shallowequal from 'shallowequal'
import raf from 'raf'
import shouldUpdate from './shouldUpdate'
import supportsPassiveEvents from './supportsPassiveEvents'

const noop = () => {}

Expand Down Expand Up @@ -58,6 +59,7 @@ export default class Headroom extends Component {
this.lastKnownScrollY = 0
this.scrollTicking = false
this.resizeTicking = false
this.eventListenerOptions = false
this.state = {
state: 'unfixed',
translateY: 0,
Expand All @@ -67,11 +69,28 @@ export default class Headroom extends Component {

componentDidMount () {
this.setHeightOffset()

this.eventListenerOptions = supportsPassiveEvents()
? { passive: true, capture: false }
: false

if (!this.props.disable) {
this.props.parent().addEventListener('scroll', this.handleScroll)
this.props
.parent()
.addEventListener(
'scroll',
this.handleScroll,
this.eventListenerOptions
)

if (this.props.calcHeightOnResize) {
this.props.parent().addEventListener('resize', this.handleResize)
this.props
.parent()
.addEventListener(
'resize',
this.handleResize,
this.eventListenerOptions
)
}
}
}
Expand All @@ -91,27 +110,67 @@ export default class Headroom extends Component {

// Add/remove event listeners when re-enabled/disabled
if (!prevProps.disable && this.props.disable) {
this.props.parent().removeEventListener('scroll', this.handleScroll)
this.props.parent().removeEventListener('resize', this.handleResize)
this.props
.parent()
.removeEventListener(
'scroll',
this.handleScroll,
this.eventListenerOptions
)
this.props
.parent()
.removeEventListener(
'resize',
this.handleResize,
this.eventListenerOptions
)

if (prevState.state !== 'unfixed' && this.state.state === 'unfixed') {
this.props.onUnfix()
}
} else if (prevProps.disable && !this.props.disable) {
this.props.parent().addEventListener('scroll', this.handleScroll)
this.props
.parent()
.addEventListener(
'scroll',
this.handleScroll,
this.eventListenerOptions
)

if (this.props.calcHeightOnResize) {
this.props.parent().addEventListener('resize', this.handleResize)
this.props
.parent()
.addEventListener(
'resize',
this.handleResize,
this.eventListenerOptions
)
}
}
}

componentWillUnmount () {
if (this.props.parent()) {
this.props.parent().removeEventListener('scroll', this.handleScroll)
this.props.parent().removeEventListener('resize', this.handleResize)
this.props
.parent()
.removeEventListener(
'scroll',
this.handleScroll,
this.eventListenerOptions
)
this.props
.parent()
.removeEventListener(
'resize',
this.handleResize,
this.eventListenerOptions
)
}
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener(
'scroll',
this.handleScroll,
this.eventListenerOptions
)
}

setRef = ref => (this.inner = ref)
Expand Down
26 changes: 26 additions & 0 deletions src/supportsPassiveEvents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Used to detect browser support for adding an event listener with options
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Improving_scrolling_performance_with_passive_listeners
* @returns Boolean
*/
export default function supportsPassiveEvents () {
let passiveSupported = false

try {
const options = {
get passive () {
// This function will be called when the browser
// attempts to access the passive property.
passiveSupported = true
return false
},
}

window.addEventListener('test', null, options)
window.removeEventListener('test', null, options)
} catch (err) {
passiveSupported = false
}

return passiveSupported
}

0 comments on commit 51b78c9

Please # to comment.