Chrome中ShadowRoot内元素鼠标滚动失效问题求助
Chrome中ShadowRoot内滚动容器失效的解决方案
问题现象
在ShadowRoot内创建固定高度、overflow: auto的滚动容器时,若外部页面本身存在滚动条,Chrome浏览器中鼠标悬停容器滚动时,只会触发页面滚动,而非容器自身滚动。将容器移至ShadowRoot外,或在非Chrome浏览器中使用ShadowRoot,滚动功能均正常。
无需全局样式改动的解决方案
方案1:通过pointer-events精准控制事件目标
给ShadowRoot的宿主容器设置pointer-events: none,再给滚动容器本身设置pointer-events: auto,让Chrome正确识别滚动事件的目标元素:
const App = () => { return ( <div className="App" style={{ height: "100px", width: "500px", overflow: "auto", pointerEvents: "auto" // 恢复滚动容器的事件响应 }} > <h1 style={{ height: "100px" }}>Try mouse-scrolling here</h1> <h2>Hidden!</h2> </div> ); } const container = document.createElement("div"); container.style.pointerEvents = 'none'; // 阻止宿主容器接收事件 const shadowRoot = container.attachShadow({ mode: "open" }); const domElement = document.getElementById("root"); domElement.append(container); const root = ReactDOM.createRoot(shadowRoot); root.render(<App />);
方案2:阻止滚动事件冒泡
在滚动容器上监听wheel事件,通过stopPropagation()阻止事件冒泡到页面,避免触发页面滚动:
const App = () => { const handleWheel = (e) => { e.stopPropagation(); // 阻止事件向上冒泡 }; return ( <div className="App" style={{ height: "100px", width: "500px", overflow: "auto" }} onWheel={handleWheel} > <h1 style={{ height: "100px" }}>Try mouse-scrolling here</h1> <h2>Hidden!</h2> </div> ); } // 其余代码保持不变 const container = document.createElement("div"); const shadowRoot = container.attachShadow({ mode: "open" }); const domElement = document.getElementById("root"); domElement.append(container); const root = ReactDOM.createRoot(shadowRoot); root.render(<App />);
方案3:针对触控场景的补充设置
如果涉及触控设备滚动,给滚动容器添加touch-action: pan-y,明确告知浏览器该元素负责垂直滚动:
const App = () => { return ( <div className="App" style={{ height: "100px", width: "500px", overflow: "auto", touchAction: "pan-y" // 指定触控滚动行为 }} > <h1 style={{ height: "100px" }}>Try mouse-scrolling here</h1> <h2>Hidden!</h2> </div> ); }
方案优势
以上方案均无需修改页面全局样式(如隐藏body滚动条),不会导致页面偏移,适配微前端WebComponent场景下的样式隔离需求。
内容的提问来源于stack exchange,提问作者stalet
相关产品推荐
相关产品推荐

