Как добавить ClassName и удалить его по событию OnScroll в React.JS? - PullRequest
2 голосов
/ 25 октября 2019

Я пытаюсь создать липкий заголовок, который может менять цвет фона в зависимости от его положения на странице. Чтобы сделать это, я пытаюсь добавить className «active» к своему стилевому компоненту «StyledHeader», который появится, когда scrollPositionY выше 400px, и исчезнет, ​​когда ниже.

Другими словами, я хочу сделать что-то вроде this , но используя React.JS, синтаксис JSX и Styled Components.

Вот что у меня есть сейчас:

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;

Вы знаете простой способ сделать это?

Ответы [ 2 ]

1 голос
/ 25 октября 2019

добавить прослушиватель событий в ваш useEffect. при прокрутке вниз значение window.scrollY будет увеличиваться, например, 1, 2, ... 100 .. (в пикселях) и обновлять color в useState в соответствии с window.scrollY,попробуйте что-то вроде этого

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;

вот рабочая демоверсия .. измените код в соответствии с вашими потребностями. demo

Редактировать: я добавил стилевые компоненты длявы. проверьте это и дайте мне знать, работает ли он для вас. чтобы узнать больше об этих крючках, перейдите на useEffect и useCallback

0 голосов
/ 25 октября 2019

сам не запускал этот код, но может быть что-то вроде:

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;
...