使用 Reactjs 获取滚动位置
Posted
技术标签:
【中文标题】使用 Reactjs 获取滚动位置【英文标题】:Get scroll position with Reactjs 【发布时间】:2019-04-09 01:44:27 【问题描述】:我使用 reactjs,想用click
事件处理滚动。
首先,我使用componentDidMount
呈现帖子列表。
其次,通过click event
在列表中的每个帖子上,它将显示帖子详细信息并滚动到顶部(因为我将帖子详细信息放在页面的顶部位置)。
第三,通过点击帖子详细信息中的"close button"
,它将返回以前的帖子列表,但我希望网站将滚动到点击帖子的确切位置。
我是这样使用的:
点击事件查看帖子详情:
inSingle = (post, e) =>
this.setState(
post: post,
theposition: //How to get it here?
);
window.scrollTo(0, 0);
我想获得theposition
的状态,然后我可以精确滚动到'Close event'
所点击帖子的位置。
【问题讨论】:
你用的是什么版本的 react? @SungKim 我正在使用最新版本 【参考方案1】:像这样:
theposition: e.y // or, e.pageY
或者,
theposition: e.clientY - e.currentTarget.getBoundingClientRect().top
【讨论】:
【参考方案2】:您可以像在其他 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,
)
【讨论】:
这有助于检测滚动时是否到达页面底部。谢谢。 很高兴帮助你@raksheetbhat :)【参考方案3】:要获取当前滚动位置,您可以使用
水平滚动量window.pageXOffset
垂直滚动量window.pageYOffset
【讨论】:
【参考方案4】:这应该可行:
this.setState(
post: post,
theposition: window.pageYOffset
);
【讨论】:
不好吗?我的意思是,如果你 setState,你每次都重新渲染你的组件,似乎更好地结合 useState 和 useEffect 或 useLayoutEffect【参考方案5】:如果您需要跟踪滚动位置,您可以使用 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);
;
, []);
在这种情况下,useEffect
的行为类似于componentDidMount
,它会在组件渲染后触发,而且在每次渲染时都会触发,正如 Jared Beach 评论道:“window.addEventListener 足够聪明,可以丢弃后续调用相同的参数”。 .确保返回清理函数,类似于您在 componentWillUnmount
中所做的。
【讨论】:
欣赏解决方案。但是,说useEffect
类似于componentDidMount
有点误导。它运行每一个渲染,而不仅仅是第一个。此代码仍然有效,因为 window.addEventListener 足够聪明,可以丢弃具有相同参数的后续调用
总是给 window.pageYOffset 0
他的useEffect的第二个参数是一个空数组,类似于componentDidMount。如果不存在,它将类似于 componentDidUpdate。【参考方案6】:
这个 repo 帮了我很多https://github.com/n8tb1t/use-scroll-position
yarn add @n8tb1t/use-scroll-position
import useScrollPosition from '@n8tb1t/use-scroll-position'
useScrollPosition(( prevPos, currPos ) =>
console.log(currPos.x)
console.log(currPos.y)
)
【讨论】:
【参考方案7】: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;
【讨论】:
【参考方案8】:你可以使用原生的 react 事件监听器。
<div onScroll=(e) => console.log("scrolling!", e.target.scrollTop)>
<h3>Some huge div</h3>
</div>
【讨论】:
【参考方案9】:在MDN找到这个:
element.scrollHeight - Math.abs(element.scrollTop) === element.clientHeight
【讨论】:
【参考方案10】:结合其他一些答案,这正是这里所需要的。只需使用此钩子即可从窗口中获取 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
然后在你的函数组件中调用钩子:
/// in MyComponent.jsx
import useWindowScrollPositions from 'path/to/useWindowScrollPositions'
export const MyComponent = () =>
const scrollX, scrollY = useWindowScrollPositions()
return <div>Scroll position is (scrollX, scrollY)</div>
请注意,几年前在其他答案中使用的
window.pageXOffset
和window.pageYOffset
已被弃用,取而代之的是window.scrollX
和window.scrollY
【讨论】:
以上是关于使用 Reactjs 获取滚动位置的主要内容,如果未能解决你的问题,请参考以下文章