How to add a ClassName and remove it onScroll event in React.JS?

眉间皱痕 提交于 2019-12-24 05:02:12

问题


I'm trying to make a Sticky Header that can change its background-color based on his position on the page. To do that, I'm trying to add a className "active" to my Styled Component "StyledHeader" that will appears when the scrollPositionY is above 400px and disappear when below.

In other words, what I want to do is something like this but using React.JS, JSX syntax and Styled Components.

Here's what I have for now:

import { Link } from '@reach/router';

import DuskLogo from '../images/dusk_logo.svg';

import { 
    StyledHeader, 
    StyledDuskLogo
} from '../styles/StyledHeader';

const Header = () => (
<StyledHeader>
  <div className="header-content">
    <Link to="/">
    <StyledDuskLogo src={DuskLogo} alt="dusk-logo" />
    </Link>
  </div>
</StyledHeader>
)

export default Header;

Do you know a simple way to do it ?


回答1:


add an event listener in your useEffect. when you scroll down the value of window.scrollY will increase such as 1, 2, ...100 .. (in px) and update your color in useState as per the window.scrollY. try something like this

const StyledBody = window.styled.div`
  background: lightgray;
  height: 5000px;
`;

const StyledText = window.styled.h4`
  text-align: center;
  width: 250px;
  margin: auto;
  line-height: 40px;
`;

const StyledHeader = window.styled.div`
  background-color: ${props => props.color};
  width: 100%;
  height: auto;
  position: fixed;
  top: 0;
  left: 0;
  right: 0px;
  padding: 0;
  z-index: 10000;
  transition: all 1s ease-in-out;
`;

const Header = () => {
  const [color, setColor] = React.useState("rgba(17, 42, 107, 0.7)");

  const handleScroll = React.useCallback((event) => {
    let scrollTop = window.scrollY;

      //console.log(scrollTop );  //1,2,...100,...200...etc (in px)

      if (scrollTop >= 20 && scrollTop < 50) {
        setColor("yellow");
      }

      if (scrollTop >= 50 && scrollTop < 90) {
        setColor("red");
      }

      if (scrollTop >= 90 && scrollTop < 120) {
        setColor("green");
      }
      if (scrollTop >= 120 && scrollTop < 150) {
        setColor("blue");
      }
      if (scrollTop >= 150 && scrollTop < 180) {
        setColor("violet");
      }
      if (scrollTop >= 180 && scrollTop < 210) {
        setColor("purple");
      }
});

  React.useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll, false);
    };
  }, []);

  return (
    <StyledBody>
      <StyledHeader color={color}>
        <StyledText>My background color changes</StyledText>
      </StyledHeader>
    </StyledBody>
  );
};

export default Header;

here is a working demo ..change the code as per your need.demo

Edit: I have added styled-components for you. check it out and let me know whether it works for you. to know more about these hooks go to useEffect and useCallback




回答2:


haven't run this code myself but could be something like:

const Header = () => {
  const headerEl = React.useRef();
  const [offsetTop, setOffsetTop] = React.useState(0);

  React.useEffect(() => {
    window.addEventListener("scroll", onScroll, false);
    return () => {
      window.removeEventListener("scroll", onScroll, false); // to remove scroll event on unmount
    };
  }, []);

  const onScroll = () => setOffsetTop(headerEl.current.offsetTop);

  return (
    <StyledHeader ref={headerEl} className={offsetTop > 400 ? "active" : ""}>
      ...
    </StyledHeader>
  );
};

export default Header;


来源:https://stackoverflow.com/questions/58555762/how-to-add-a-classname-and-remove-it-onscroll-event-in-react-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!