繁体   English   中英

滚动返回顶部按钮在 React.js 中不起作用

[英]Scroll Back To Top Button Not Working in React.js

我正在开发一个基于 React 的项目,并尝试在页脚中实现一个按钮,以便单击以滚动顶部,但面临一个我还无法解决的问题。 如果您想查看代码,请单击以下要点链接。

// GoTop.js

import React from 'react';

const GoTopd = (props) => {

    const [intervalId, setIntervalId] = React.useState(0);
    const [thePosition, setThePosition] = React.useState(false);

    React.useEffect(() => {
        document.addEventListener("scroll", () => {
            if (window.scrollY > 170) {
                setThePosition(true)
            } else {
                setThePosition(false);
            }
        });
        // window.scrollTo(0, 0);
    }, [])

    const onScrollStep = () => {
        if (window.pageYOffset === 0){
            clearInterval(intervalId);
        }
        window.scroll(0, window.pageYOffset - props.scrollStepInPx);
    }

    const scrollToTop = () => {
        const intervalId = setInterval(onScrollStep, props.delayInMs);
        setIntervalId(intervalId);
    }

    const renderGoTopIcon = () => {
        return (
            <div className={`go-top ${thePosition ? 'active' : ''}`} onClick={scrollToTop}>
                <i className="arrow alternate circle up outline icon"></i>
            </div>
        )
    }

    return (
        <React.Fragment>
            {renderGoTopIcon()}
        </React.Fragment>
    )
}

export default GoTopd;

并在页脚上import该组件,如下所示:

<GoTop scrollStepInPx="100" delayInMs="10.50" />

问题在于此代码,例如当第一次加载和 go 到该页面下方时它工作正常,但之后,我不能 go 到页面需要再次刷新。 我不明白为什么会出现这种行为的问题。

谁能弄清楚是什么问题?

我很感激你的帮助,拜托。

谢谢

使用 React 你可以做非常简单的解决方案来滚动到顶部,但我会展示如何改进你的代码。 您可以使用参考文献。 注意clearInterval中的inrevaltId为0,不引用区间,所以不能清除区间!

const timeoutRef = React.useRef(null);

const onScrollStep = () => {

  if (window.pageYOffset === 0){
     clearInterval(timeoutRef.current);
  }
  window.scroll(0, window.pageYOffset - props.scrollStepInPx);
}

const scrollToTop = () => {
  timeoutRef.current = setInterval(onScrollStep, props.delayInMs);
}

小提琴示例: https://jsfiddle.net/4ef2boxm/

使用 React Hooks 滚动到顶部的简单解决方案

ScrollTopArrow.tsx

import React, { FC, useState, useEffect } from 'react'
import {FaArrowCircleUp} from 'react-icons/fa';
import '../App.css';
type ScrollTopArrowProps = {
    showBelow?: number
}
const ScrollTopArrow: FC<ScrollTopArrowProps> = ({ showBelow = 400 }) => {
    const [showScroll, setShowScroll] = useState<boolean>(false)
    useEffect(() => {
        window.addEventListener('scroll', checkScrollTop)
        return () => {
            window.removeEventListener('scroll', checkScrollTop)
        }
    })
    const checkScrollTop = () => {
        if (!showScroll && window.pageYOffset > showBelow) {
            setShowScroll(true)
        } else if (showScroll && window.pageYOffset <= showBelow) {
            setShowScroll(false)
        }
    }

    const scrollTop = () => {
        window.scrollTo({ top: 0, behavior: 'smooth' })
    }
    return (
        <FaArrowCircleUp className="scrollTop" onClick={scrollTop} style={{height: 40, display: showScroll ? 'flex' : 'none'}}/>
    )
}

export { ScrollTopArrow }

应用程序.css

.App {
  text-align: center;
  height: 5000px;
}

.scrollTop {
  position: fixed; 
  width: 100%;
  bottom: 20px;
  align-items: center;
  height: 20px;
  justify-content: center;
  z-index: 1000;
  cursor: pointer;
  animation: fadeIn 0.3s;
  transition: opacity 0.4s;
  opacity: 0.5;
}

.scrollTop:hover{
  opacity: 1;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 0.5;
  }
}

应用程序.tsx

import React from 'react'
import './App.css'
import {ScrollTopArrow} from './components/ScrollTopArrow'

function App() {
  return (
    <div className="App">
      <ScrollTopArrow/>
    </div>
  );
}

export default App

这是setInterval的替代方法

 const { useRef, useState, useEffect } = React; const App = () => { const ref = useRef(null); const [isBottom, setBottom] = useState(false); useEffect(() => { }, []) useEffect(() => { const element = ref && ref.current; if (element) { const checkIsBottomOfPage = () => { if (window.scrollY >= window.innerHeight) { setBottom(true) } else { setBottom(false); } } document.addEventListener("scroll", checkIsBottomOfPage); window.scrollTo({ top: element.scrollHeight }) checkIsBottomOfPage(); return () => { return document.removeEventListener("scroll", checkIsBottomOfPage); } } }, [ref]) const onScroll = (top) => { const incOrDec = top? 1: -1; let chunk = -1; let position = window.scrollY; let isScrollComplete = null; if(top === 0) { chunk = -ref.current.scrollHeight / 3; isScrollComplete = () => window.scrollY < 10; } else { chunk = top / 3; isScrollComplete = () => window.scrollY >= window.innerHeight } const scrollStep = () => { position = position + chunk; window.scrollTo({ behavior: 'smooth', top: position }) if(isScrollComplete()) { return; } setTimeout(scrollStep, 300); } setTimeout(scrollStep, 300) } const onScrollBottom = () => onScroll(ref.current.scrollHeight); const onScrollTop = () => onScroll(0); return <div ref = { ref } > < button style = { { padding: '.5rem' } } onClick = { onScrollBottom } > Scroll To Bottom < /button> < div style = { { background: 'gray', height: '200vh' } } > < /div> < button style = { { visibility: isBottom? 'visible': 'hidden', padding: '.5rem' } } onClick = { onScrollTop } > Scroll To Top < /button> < /div> } ReactDOM.render( < App / >, document.getElementById('root') );
 <script src="https://unpkg.com/react/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <div id="root"></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM