Dille Fepp
Dille Fepp

Reputation: 65

Updating progress bar state on browser scroll

I am trying to create a progress bar that increases/decreases it's width % when i scroll. I am currently getting the scrolled % to show in the console log but i am unable to set the state with the scrolled percent.

With what i got now im getting that this.percentScrolled() is not a function since i am calling it from componentDidMount. My second concern is the performance of doing it this way, the state will update a lot for every scroll.

This is what i got right now, any help is appreciated.

import React from "react";
import { Line } from "rc-progress";

class ProgressBar extends React.Component {
  constructor() {
    super();

    this.state = {
      percent: 0
    };

    this.percentScrolled = this.percentScrolled.bind(this)
  }

  componentDidMount() {
    window.addEventListener(
      "scroll",
      function() {
        this.percentScrolled();
      },
      false
    );
  }

  getDocHeight = () =>  {
    const d = document;
    return Math.max(
      d.body.scrollHeight,
      d.documentElement.scrollHeight,
      d.body.offsetHeight,
      d.documentElement.offsetHeight,
      d.body.clientHeight,
      d.documentElement.clientHeight
    );
  }

  percentScrolled = () => {
    const winHeight =
      window.innerHeight ||
      (document.documentElement || document.body).clientHeight;
    const docHeight = this.getDocHeight();
    const scrollTop =
      window.pageYOffset ||
      (document.documentElement || document.body.parentNode || document.body)
        .scrollTop;
    const trackLength = docHeight - winHeight;
    const pctScrolled = Math.round((scrollTop / trackLength) * 100);
    console.log("Scrolled: " + pctScrolled + "%");

    this.setState({
      percent: pctScrolled
     });
  }
  render() {
    return (
      <div>
        <Line
          percent={this.state.percent}
          strokeWidth="1"
          strokeColor="green"
          trailColor="white"
        />
      </div>
    );
  }
}

export default ProgressBar;

Upvotes: 0

Views: 315

Answers (1)

Magnum
Magnum

Reputation: 2395

You're calling this.percentScrolled out of scope. If you pull out the anonymous function, it should properly reference in the context of your Component.

Try:

  componentDidMount() {
    window.addEventListener(
      "scroll",
       this.percentScrolled,
       false
    );
  }

Upvotes: 1

Related Questions