在 React 中,如何将滚动转移到另一个元素?

In React, how to divert the scrolling to another element?

我的APP有3个div:边、中、右。

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

问题是当用户滚动到侧面或右侧 divs 时,没有任何反应。

要解决此问题,无论指针悬停在何处,所有滚动都应div置于中间div。

如何在 React 中完成?

在 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 to get access to the element that I want to scroll. In my example, this is the div with the class content. In your case it will be your middle div. This is important because doing this gives access to the element's scrollTop属性。使用 scrollTop 我们可以设置元素滚动条的位置。

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

最后,useEffect hook. I added an event listener for the wheel event. When the wheel event is fired, the event object passed to the handleScrolling function contains a deltaY property. Inside handleScrolling I add deltaY to the ref element's scrollTop property to get a similar result as scrolling normally. Finally, I remove the event listener in useEffect's clean up function

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

希望这对您有所帮助!

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

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