【问题标题】:In React, how to divert the scrolling to another element?在 React 中,如何将滚动转移到另一个元素?
【发布时间】:2022-02-21 01:12:13
【问题描述】:

我的 APP 有 3 个 div:side、middle 和 right。

中间部分将包含任意数量的项目的内容列表。它设置为vh 的长度。因此,当存在太多项目时,它需要滚动。

问题是当用户滚动到侧面或右侧 div 时,什么也没有发生。

为了解决这个问题,无论指针悬停在哪里,所有滚动都应该转向中间div。

如何在 React 中做到这一点?

【问题讨论】:

    标签: javascript html reactjs scroll scrollbar


    【解决方案1】:

    在 React 中执行此操作相当简单。这是我创建的一个功能组件,它可以按预期工作:

    import React from "react";
    import { useEffect, useRef, useState } from "react";
    import "./Content.css";
    
    const Content = (props) => {
      
      const [contentHover, setContentHover] = useState(false);
      const contentRef = useRef(null);
    
      useEffect(() => {
    
        const handleScrolling = (event) => {
          if(contentRef !== null) {
            if(contentHover === false) {
              contentRef.current.scrollTop += event.deltaY;
            }
          }
        }
    
        window.addEventListener("wheel", handleScrolling);
    
        return () => {
          window.removeEventListener("wheel", handleScrolling);
        }
      })
    
      return (
        <div 
          className="content" 
          ref={contentRef}
          onMouseEnter={ () => { setContentHover(true) }}
          onMouseLeave={ () => { setContentHover(false) }}
        >
          {/* YOUR LIST OF CONTENT OR WHATEVER */}
        </div>
      )
    }
    
    export default Content; 
    

    说明

    让这个解决方案发挥作用的三件事。

    首先,我使用useRef 来访问我想要滚动的元素。在我的示例中,这是 div,类为 content。在您的情况下,它将是您的中间 div。这很重要,因为这样做可以访问元素的scrollTop 属性。使用scrollTop我们可以设置元素滚动条的位置。

    其次,我使用useState 添加了名为contentHover 的状态。我使用div 上的onMouseEnteronMouseLeve 事件处理程序在truefalse 之间切换它的值,我想滚动。当鼠标进入我的div时contentHover变成true。当它离开时,它变成false。这很重要,因为我们不想让元素滚动两次,即让它滚动两倍的速度。在应用自定义滚动功能之前,我们将检查 contentHover 是否为 false,这意味着鼠标不在我们要滚动的元素中。

    最后,useEffect 钩子。我为wheel 事件添加了一个事件监听器。当wheel 事件被触发时,传递给handleScrolling 函数的事件对象包含deltaY 属性。在handleScrolling 内部,我将deltaY 添加到ref 元素的scrollTop 属性中,以获得与正常滚动类似的结果。最后,我删除了useEffectclean up function中的事件监听器。

    总而言之,我们不一定要将滚动“转移”到另一个元素。相反,我们监听 wheel 事件,保留对我们要滚动的元素的引用,然后在触发事件时更新该元素的 scrollTop。

    希望这对您有所帮助!

    【讨论】:

    • 从功能上讲,它有效。但是滚动不像自然滚动那样平滑。有没有办法让它变得平滑?
    【解决方案2】:

    按照第一个解决方案,我通过将代码更改为以下方式解决了平滑滚动问题:

    const handleScrolling = (event) => {
          if (contentRef !== null) {
            if (contentHover === false) {
              contentRef.current.scrollTo({
                top: contentRef.current.scrollTop + event.deltaY,
                behavior: "smooth",
              });
            }
          }
        };
    

    【讨论】:

      猜你喜欢
      • 2010-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多