簡體   English   中英

如何使用react-spring滾動到元素?

[英]How to scroll to an element using react-spring?

我已經通讀了整個react-spring文檔,似乎沒有明確的方法可以做到這一點。

我的嘗試:

import React, { useRef, useState } from "react"
import { animated, useSpring } from "react-spring"

const App = () => {
    const scrollDestinationRef = useRef()

    const [elementScroll, setElementScroll] = useState(false)

    const buttonClickHandler = () => setElementScroll(prevState => !prevState)

    const scrollAnimation = useSpring({
        scroll: elementScroll
            ? scrollDestinationRef.current.getBoundingClientRect().top
            : 0
    })

    return (
        <main>
            {/* Click to scroll to destination */}
            <animated.button
                onClick={buttonClickHandler}
                scrollTop={scrollAnimation.scroll}
                style={{
                    height: "1000px",
                    width: "100%",
                    backgroundColor: "tomato"
                }}
            >
                Scroll to destination
            </animated.button>

            {/* Scroll destination */}
            <div
                ref={scrollDestinationRef}
                style={{
                    height: "200px",
                    width: "200px",
                    backgroundColor: "green"
                }}
            ></div>
        </main>
    )
}

export default App

我正在嘗試使用 ref 和 hooks。

useRef附加到滾動目的地,以便從網站的天花板找到它的偏移頂部。

我使用useState在單擊狀態之間切換以觸發滾動。

我使用useSpring來觸發從 0 到滾動目標的滾動頂部(又名getBoundingClientRect().top的動畫。

任何人都可以協助解決這個問題嗎?

網上沒有太多解釋,謝謝!

useSpring返回一個函數來設置/更新動畫值。 您可以使用該函數為動畫變量分配一個新值。 然后,您可以使用onFrame屬性來更新滾動位置。

像這樣定義你的spring

const [y, setY] = useSpring(() => ({
    immediate: false,
    y: 0,
    onFrame: props => {
      window.scroll(0, props.y);
    },
    config: config.slow,
  }));

然后使用setY函數啟動彈簧,如下所示:

 <button
        onClick={() => {
          setY({ y: scrollDestinationRef.current.getBoundingClientRect().top });
        }}
      >
        Click to scroll
 </button>

當您單擊該按鈕時,它將為彈簧中的y變量分配一個新值,並且每次更新時都會調用onFrame函數。

請注意,我們所說的window.scroll從功能onFrame物業useSpring

請參閱此處的工作演示。

const targetElement = useRef(null)
const [, setY] = useSpring(() => ({ y: 0 }))

let isStopped = false
const onWheel = () => {
  isStopped = true
  window.removeEventListener('wheel', onWheel)
}

const scrollToTarget = () => {
  const element = targetElement.current
  const value = window.scrollY + element.getBoundingClientRect().top

  window.addEventListener('wheel', onWheel)

  setY({
    y: value,
    reset: true,
    from: { y: window.scrollY },
    onRest: () => {
      isStopped = false
      window.removeEventListener('wheel', onWheel)
    },
    onFrame: props => {
      if (!isStopped) {
        window.scroll(0, props.y)
      }
    }
  })
}

此版本還允許用戶通過使用wheel事件來擺脫強制滾動。 (我個人討厭強制滾動:D)

除了set之外, useSpring(fn)確實返回了一個stop方法。 但我無法讓它發揮作用。 我把它貼到了一個相關的github 問題上 如果你讀到這個,也許已經有一個很好的答案了:)

現在它使用isStopped標志的一些解決方法。


更新:

似乎stop fn 實際上有些可疑,應該在v9 canary 中解決 尚未測試,因為 v9 還不穩定。

最后通過https://github.com/pmndrs/react-spring/issues/544 后,Yannick Schuchmann 的回答對我有用,我只需要將 onFrame 更改為 onChange

我為解決方案做了一個自定義鈎子: https : //github.com/TomasSestak/react-spring-scroll-to-hook

react-sring 版本:9.0.0-rc.3

暫無
暫無

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

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