【问题标题】:Get scroll position with Reactjs使用 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 我正在使用最新版本

标签: javascript reactjs


【解决方案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.pageXOffsetwindow.pageYOffset 已被弃用,取而代之的是window.scrollXwindow.scrollY

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2023-01-22
                • 2021-09-06
                • 2019-10-20
                • 2011-01-29
                • 2011-04-08
                • 1970-01-01
                • 1970-01-01
                • 2023-01-10
                相关资源
                最近更新 更多