簡體   English   中英

如何在反應中制作滾動事件?

[英]How to make a scroll event in react?

我正在嘗試制作一個 animation,在您向下滾動頁面時繪制一個 SVG。

我已經設法讓它在 vanilla js 中工作,但有反應問題。 每次我刷新頁面時它都會崩潰。

我認為這是由於瀏覽器努力跟上最新的路徑長度。 因為每次刷新時我得到的錯誤是(path.getTotalLength 不是一個函數)。

我也不確定如何將反應事件偵聽器鏈接到我的 HTML。

關於解決這個問題的任何建議都會很棒

謝謝

import { useRef } from "react";

function About() {
  const pathRef = useRef();

  let path = pathRef;
  let pathLength = path.getTotalLength();

  path.style.strokeDasharray = pathLength + " " + pathLength;

  path.style.strokeDashoffset = pathLength;

  window.addEventListener("scroll", () => {
    let scrollPercentage =
      (document.documentElement.scrollTop + document.body.scrollTop) /
      (document.documentElement.scrollHeight -
        document.documentElement.clientHeight);
    let drawLength = pathLength * scrollPercentage;
    path.style.strokeDashoffset = pathLength - drawLength;
  });

  return (
    <div className="about">
      <div className="about__container">
        <svg
          viewBox="0 0 1043 1831"
          fill="none"
          preserveAspectRatio="xMidYMax meet"
        >
          <path
            ref={path}
            d="M1184.5 3C503.5 3 763 316 595.5 431.5V376.5L645.5 423.5C664.167 436.167 708 446.5 736 426C764.312 405.271 763 402.5 763 402.5C754 390.667 730.4 368 690 368C649.6 368 620.5 409.624 612 418.276L609.5 609H995.5L1.5 1051.5H587.5C590 1059.67 603.3 1076 636.5 1076C638.5 1076 638.667 1074.67 638.5 1074C638.833 1065.33 640.5 1048.2 644.5 1049C649.5 1050 576 1037.5 603 980.5L609.5 971C607.833 961 605.5 941.1 609.5 941.5C613.5 941.9 631.167 950.333 639.5 954.5C651.9 951.3 679.333 952.167 691.5 953C699.667 948.167 716.2 939.1 717 941.5C718 944.5 721 967.5 719 972.5C726 986.5 745.5 1041 681.5 1050C684.5 1049 689.4 1057.8 689 1069L681.5 1440.5C677.5 1793.5 820 1654 1082.5 1654"
            stroke="#0000FF"
            stroke-width="6"
          />
          ;
        </svg>
        <div className="about__landing"></div>
      </div>
    </div>
  );
}

export default About;

使用鈎子,您可以這樣實現它:

import React, { useEffect, useState } from 'react';

function MyApp () {

    const [offset, setOffset] = useState(0);

    useEffect(() => {
        const onScroll = () => setOffset(window.pageYOffset);
        // clean up code
        window.removeEventListener('scroll', onScroll);
        window.addEventListener('scroll', onScroll, { passive: true });
        return () => window.removeEventListener('scroll', onScroll);
    }, []);

    console.log(offset); 
};

在第一次渲染之后useRef鈎子沒有對<path />元素的引用。

結合使用useRef掛鈎和useEffect掛鈎來設置路徑長度,並在第一次渲染發生時添加事件偵聽器。

對元素的實際引用存儲在useRef鈎子值的current屬性中。

import { useRef, useEffect } from "react";

function About() {
  const pathRef = useRef();

  useEffect(() => {
    let pathLength = path.current.getTotalLength();

    path.current.style.strokeDasharray = pathLength + " " + pathLength;
    path.current.style.strokeDashoffset = pathLength;

    window.addEventListener("scroll", () => {
      let scrollPercentage =
        (document.documentElement.scrollTop + document.body.scrollTop) /
        (document.documentElement.scrollHeight -
          document.documentElement.clientHeight);
      let drawLength = pathLength * scrollPercentage;
      path.currnet.style.strokeDashoffset = pathLength - drawLength;
    });
  }, []);

  return (
    <div className="about">
      <div className="about__container">
        <svg
          viewBox="0 0 1043 1831"
          fill="none"
          preserveAspectRatio="xMidYMax meet"
        >
          <path
            ref={path}
            d="M1184.5 3C503.5 3 763 316 595.5 431.5V376.5L645.5 423.5C664.167 436.167 708 446.5 736 426C764.312 405.271 763 402.5 763 402.5C754 390.667 730.4 368 690 368C649.6 368 620.5 409.624 612 418.276L609.5 609H995.5L1.5 1051.5H587.5C590 1059.67 603.3 1076 636.5 1076C638.5 1076 638.667 1074.67 638.5 1074C638.833 1065.33 640.5 1048.2 644.5 1049C649.5 1050 576 1037.5 603 980.5L609.5 971C607.833 961 605.5 941.1 609.5 941.5C613.5 941.9 631.167 950.333 639.5 954.5C651.9 951.3 679.333 952.167 691.5 953C699.667 948.167 716.2 939.1 717 941.5C718 944.5 721 967.5 719 972.5C726 986.5 745.5 1041 681.5 1050C684.5 1049 689.4 1057.8 689 1069L681.5 1440.5C677.5 1793.5 820 1654 1082.5 1654"
            stroke="#0000FF"
            stroke-width="6"
          />
          ;
        </svg>
        <div className="about__landing"></div>
      </div>
    </div>
  );
}

export default About;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM