如何将<div>滚动事件透传至Excalidraw的<canvas>?
解决方案:让上层Div透传滚动事件但保留其他交互
要解决上层Div拦截滚动事件、但又不想丢失其交互能力的问题,可以通过手动转发滚动事件的方式实现,核心思路是监听Div的滚轮事件,将事件透传给下层Excalidraw的Canvas元素。
修改后的代码示例
"use client"; import { useMemo, useRef, useEffect } from "react"; import dynamic from "next/dynamic"; const Excalidraw = dynamic( async () => { const mod = await import("@excalidraw/excalidraw"); return mod.Excalidraw; }, { ssr: false }, ); export default function Home() { const Excal = useMemo(() => <Excalidraw gridModeEnabled />, []); // 上层遮罩Div的Ref const overlayRef = useRef<HTMLDivElement>(null); // Excalidraw容器的Ref,用于获取内部Canvas const excalidrawContainerRef = useRef<HTMLDivElement>(null); useEffect(() => { const canvas = excalidrawContainerRef.current?.querySelector("canvas"); const overlayDiv = overlayRef.current; // 确保元素存在再执行 if (!canvas || !overlayDiv) return; const handleWheel = (e: WheelEvent) => { // 阻止Div默认的滚动行为(避免触发页面滚动) e.preventDefault(); // 创建并转发滚轮事件给Canvas canvas.dispatchEvent(new WheelEvent("wheel", { ...e })); }; // 添加滚轮事件监听 overlayDiv.addEventListener("wheel", handleWheel); // 组件卸载时移除监听,避免内存泄漏 return () => overlayDiv.removeEventListener("wheel", handleWheel); }, []); return ( <main className="absolute w-screen h-screen"> <div ref={overlayRef} style={{ position: "fixed", zIndex: 100, top: "100px", left: "100px", backgroundColor: "yellow", cursor: "pointer", }} > <p>here</p> </div> <div ref={excalidrawContainerRef}>{Excal}</div> </main> ); }
关键说明
- Ref获取元素:通过
useRef分别绑定上层Div和Excalidraw容器,确保能准确获取到目标元素。 - 事件转发逻辑:监听Div的
wheel事件,阻止默认行为后,创建一个新的滚轮事件并派发给Excalidraw的Canvas,这样Excalidraw就能接收到滚动指令来移动画布。 - 保留原有交互:这种方式不会影响Div的点击、hover等其他交互,仅处理滚动事件的透传。
内容的提问来源于stack exchange,提问作者psygo
相关产品推荐
相关产品推荐

