harry
harry

Reputation: 501

How to add class in element on scroll React js

How to add class in element on scroll React js, I want to add class in on scroll and remove that class if on top of the page.

import React from "react"
import { Link } from "react-router"
import { prefixLink } from "gatsby-helpers"
import Helmet from "react-helmet"
import { config } from "config"

module.exports = React.createClass({
  propTypes() {
    return {
      children: React.PropTypes.any,
    }
  },
  render() {
  window.addEventListener('scroll', (event) => {

    });
    return (
      <div>
        <header className="header">
          <div className="top-bar">
            <span><a href="tel:6788272782">678-827-2782 </a></span>
            <span><a href="mailto:[email protected]"> [email protected]</a></span>
            <button>Login</button>
          </div>
        </header>
        {this.props.children}
      </div>
    )
  },

})

Upvotes: 17

Views: 34753

Answers (4)

Griha Mikhailov
Griha Mikhailov

Reputation: 733

One more variant with hooks and cleanup to avoid memory leaks, if the browser is not handled it properly.

const [isScrollValueMoreThanHeaderHeight, setIsScrollValueMoreThanHeaderHeight] = useState(false);

//here 96(px) - height of current header

useEffect(() => {
    const handleScroll = () => {
        setIsScrollValueMoreThanHeaderHeight(window.scrollY > 96);
    }
    window.addEventListener('scroll', handleScroll)
    return () => window.removeEventListener('scroll', handleScroll);
},[])

And then used it in a ternary way to change class

className={isScrollValueMoreThanHeaderHeight ? "class1" : "class2"}

Upvotes: 1

Gerardo Alcantara
Gerardo Alcantara

Reputation: 31

import React, { useState, useEffect } from "react"
import { Link } from "react-router"
import { prefixLink } from "gatsby-helpers"
import Helmet from "react-helmet"
import { config } from "config"

export default function Header(props) {
  const [scroll, setScroll] = useState(false)
  useEffect(() => {
    window.addEventListener("scroll", () => {
      setScroll(window.scrollY > 10)
    })
  }, [])
  return (
    <header className={scroll ? "main-header scrolled" : "main-header"}>
</header>
  )
}

Upvotes: 2

ZiaUllahZia
ZiaUllahZia

Reputation: 1142

If you want to use React Hooks in 2020 stateless component

const [scroll, setScroll] = useState(false);
 useEffect(() => {
   window.addEventListener("scroll", () => {
     setScroll(window.scrollY > 50);
   });
 }, []);

and use it anywhere in your code

className={scroll ? "bg-black" : "bg-white"}

setScroll(window.scrollY > 50); here 50 specify the height.

Upvotes: 34

Chase DeAnda
Chase DeAnda

Reputation: 16441

Use state to manage classnames and update state in the scroll event. Also, you should move the scroll event binding into the componentDidMount function instead of render.

import React from "react"
import { Link } from "react-router"
import { prefixLink } from "gatsby-helpers"
import Helmet from "react-helmet"
import { config } from "config"

module.exports = React.createClass({
  propTypes() {
    return {
      children: React.PropTypes.any,
    }
  },
  componentDidMount(){
      window.addEventListener('scroll', () => {
         let activeClass = 'normal';
         if(window.scrollY === 0){
             activeClass = 'top';
         }
         this.setState({ activeClass });
      });
  }
  render() {
    return (
      <div>
        <header className="header">
          <div className={`top-bar ${this.state.activeClass}`}>
            <span><a href="tel:6788272782">678-827-2782 </a></span>
            <span><a href="mailto:[email protected]"> [email protected]</a></span>
            <button>Login</button>
          </div>
        </header>
        {this.props.children}
      </div>
    )
  },

})

Upvotes: 17

Related Questions