使用Reactjs获取滚动位置

Hai*_*ien 13 javascript reactjs

我使用reactjs并希望处理click事件滚动.

首先,我用以下内容列出了帖子componentDidMount.

其次,通过click event列表中的每个帖子,它将显示帖子详细信息并滚动到顶部(因为我将帖子详细信息放到页面的顶部位置).

第三,通过点击"close button"帖子详细信息,它将返回上一个帖子列表,但我希望网站将滚动到确切点击帖子的位置.

我用这样的:

点击事件查看帖子详细信息:

inSingle = (post, e) => {
   this.setState({
        post: post,
        theposition: //How to get it here?
   });
   window.scrollTo(0, 0);
}
Run Code Online (Sandbox Code Playgroud)

我想获得状态theposition然后我可以完全滚动到点击帖子的位置'Close event'.

非常感谢.

Luc*_*ade 25

如果您需要跟踪滚动位置,可以使用 react hooks 来做到这一点,这样就可以在需要时随时检查滚动位置:

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

...
// inside component:

const [scrollPosition, setScrollPosition] = useState(0);
const handleScroll = () => {
    const position = window.pageYOffset;
    setScrollPosition(position);
};

useEffect(() => {
    window.addEventListener('scroll', handleScroll, { passive: true });

    return () => {
        window.removeEventListener('scroll', handleScroll);
    };
}, []);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,useEffect行为类似于componentDidMount,它会在组件渲染后触发,但也会在每次渲染中触发,正如 Jared Beach 评论道:“window.addEventListener 足够聪明,可以丢弃具有相同参数的后续调用”。. 确保返回清理函数,类似于您在componentWillUnmount.

  • 他的 useEffect 的第二个参数是一个空数组,这与 componentDidMount 类似。如果不存在,它将类似于 componentDidUpdate。 (7认同)
  • 总是给 window.pageYOffset 0 (4认同)
  • 赞赏该解决方案。然而,说“useEffect”与“componentDidMount”类似有点误导。它运行每个渲染,而不仅仅是第一个。此代码仍然有效,因为 window.addEventListener 足够智能,可以丢弃具有相同参数的后续调用 (2认同)

EQu*_*per 23

你可以像在其他js框架或库中一样使用事件监听器.

componentDidMount() {
  window.addEventListener('scroll', this.listenToScroll)
}

componentWillUnmount() {
  window.removeEventListener('scroll', this.listenToScroll)
}

listenToScroll = () => {
  const winScroll =
    document.body.scrollTop || document.documentElement.scrollTop

  const height =
    document.documentElement.scrollHeight -
    document.documentElement.clientHeight

  const scrolled = winScroll / height

  this.setState({
    theposition: scrolled,
  })
}
Run Code Online (Sandbox Code Playgroud)


Sab*_*med 10

这应该工作:

this.setState({
    post: post,
    theposition: window.pageYOffset
});
Run Code Online (Sandbox Code Playgroud)

  • 这很糟糕不是吗?我的意思是,如果您设置State,则每次都重新渲染组件,似乎将 useState 和 useEffect 或 useLayoutEffect 结合起来更好 (4认同)

小智 10

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

export default function useWindowPosition() {
  const [scrollPosition, setPosition] = useState(0);
  useLayoutEffect(() => {
    function updatePosition() {
      setPosition(window.pageYOffset);
    }
    window.addEventListener('scroll', updatePosition);
    updatePosition();
    return () => window.removeEventListener('scroll', updatePosition);
  }, []);
  return scrollPosition;
}
Run Code Online (Sandbox Code Playgroud)


lwd*_*he1 9

结合其他一些答案,这正是这里所需要的。只需使用此钩子即可从窗口获取scrollX(水平)和scrollY(垂直)位置。它会随着用户滚动而更新。

/// in useWindowScrollPositions.js

import { useEffect, useState } from 'react'

export const useWindowScrollPositions = () => {

   const [scrollPosition, setPosition] = useState({ scrollX: 0, scrollY: 0 })

   useEffect(() => {
    function updatePosition() {
        setPosition({ scrollX: window.scrollX, scrollY: window.scrollY })
    }

    window.addEventListener('scroll', updatePosition)
    updatePosition()

    return () => window.removeEventListener('scroll', updatePosition)
   }, [])

   return scrollPosition
}
Run Code Online (Sandbox Code Playgroud)

然后在函数组件中调用钩子:

/// in MyComponent.jsx

import { useWindowScrollPositions } from 'path/to/useWindowScrollPositions'

export const MyComponent = () => {
   const { scrollX, scrollY } = useWindowScrollPositions()
   
   return <div>Scroll position is ({scrollX}, {scrollY})</div>
} 
Run Code Online (Sandbox Code Playgroud)

请注意,几年前在其他答案中使用的window.pageXOffsetand已被弃用,取而代之的是window.pageYOffsetwindow.scrollXwindow.scrollY


Min*_*int 8

您可以使用本机反应事件侦听器。

<div onScroll={(e) => console.log("scrolling!", e.target.scrollTop)}>
    <h3>Some huge div</h3>
</div>
Run Code Online (Sandbox Code Playgroud)