Darren
Darren

Reputation: 2290

Getting scroll position of element ID with window.scrollY

My React app has overflow: hidden applied to the body for reasons of tranformations. This left the issue of not being able to register the scroll position of scrollY as scrolling happens in child components.

How can I apply window.scrollY or similar to register the scroll position of <div id="innerContainer">?

Here is a snippet of where one scroll addEventListener is creating a class on scroll. Problem is without registering the scrollY I cannot add the event.

componentDidMount () {
  window.addEventListener('scroll', this.handleHeaderStuck);
}

componentWillUnmount () {
  window.removeEventListener('scroll', this.handleHeaderStuck);
} 

or

handleHeaderStuck() {
  console.log('scrollPos', window.scrollY)
  if (window.scrollY === 0 && this.state.isStuck === true) {
      this.setState({isStuck: false});
  }
  else if (window.scrollY !== 0 && this.state.isStuck !== true) {
      this.setState({isStuck: true});
  }
}

and the general layout of is...

render() {
  return (
    <main className={this.state.isStuck ? 'header-stuck' : ''}>
      <div id="container">
        <header />
        <div id="innerContainer">...</div>
        <footer />
      </div>
    </main>

Update - after applying the answer submitted by Kingdaro:

Screenshot of console using the code submitted by Kingdaro that registers the scrollPos change but not the actual position

enter image description here

Upvotes: 0

Views: 1285

Answers (1)

kingdaro
kingdaro

Reputation: 12008

A ref should do the job here. Also make sure to unregister the event listener when the component unmounts, to avoid memory leaks.

class Example extends React.Component {
  innerContainer = null

  componentDidMount() {
    this.innerContainer.addEventListener("scroll", this.handleHeaderStuck)
  }

  componentWillUnmount() {
    this.innerContainer.removeEventListener("scroll", this.handleHeaderStuck)
  }

  // using a class property here so the `this` context remains properly bound
  handleHeaderStuck = () => {
    console.log('div scroll position:', this.innerContainer.scrollTop)
  }

  render() {
    return <div id="innerContainer" ref={el => (this.innerContainer = el)} />
  }
}

Upvotes: 1

Related Questions