在 Web 開發(fā)中,使用 3D 組件展示內(nèi)容已經(jīng)變得越來越普遍构捡,通常希望通過鼠標(biāo)滾輪來對 3D 組件進(jìn)行縮放操作,但在同一頁面上壳猜,y軸滾動條也可能存在勾徽,這樣一來,當(dāng)滾輪操作時统扳,既會觸發(fā) 3D 組件的縮放喘帚,又會導(dǎo)致頁面的滾動,那么如何優(yōu)雅地解決這個問題咒钟?
問題描述:
頁面中包含 3D 組件展示區(qū)以及一些其他內(nèi)容吹由,滾動鼠標(biāo)滾輪時,不僅會對 3D 組件進(jìn)行縮放朱嘴,同時頁面也會跟著滾動倾鲫,如下圖所示:
修改前
解決方案概述:
- 要實(shí)現(xiàn)的目標(biāo):
- 在用戶鼠標(biāo)放置 3D 組件展示區(qū)滾動鼠標(biāo)滾輪時 3D 組件跟隨縮放,但頁面不會跟著滾動萍嬉。
- 當(dāng)用戶鼠標(biāo)放置在 3D 組件展示區(qū)之外滾動鼠標(biāo)滾輪時乌昔,3D 組件不會跟隨縮放,頁面會上下滾動壤追。
- 實(shí)現(xiàn)這一目標(biāo)磕道,采取以下思路:
- 確保只有當(dāng)鼠標(biāo)位于 3D 組件區(qū)域時,才阻止頁面滾動行冰。
具體實(shí)現(xiàn):
1. 添加鼠標(biāo)滾輪事件監(jiān)聽器:
const containerRef = useRef(null);
useEffect(() => {
const container: any = containerRef.current;
//passive: false在特定情況下阻止頁面滾動
container.addEventListener('wheel', handleWheel, { passive: false });
return () => {
container.removeEventListener('wheel', handleWheel);
};
}, []);
containerRef 為頁面滾動區(qū)域的元素溺蕉。
2. 使用 closest
方法判斷事件目標(biāo):
為了確保只有當(dāng)鼠標(biāo)位于 3D 組件區(qū)域時才阻止頁面滾動,使用 closest
方法來判斷 event.target
是否屬于我們定義的 3D 組件容器悼做。
const handleWheel = useCallback((event: any) => {
// 阻止頁面默認(rèn)的滾動行為
if (event.target.closest('#rootGeo3DCanvas')) {
event.preventDefault();
}
}, []);
event.target.closest('#3d-container')
會從事件的目標(biāo)元素開始向上查找疯特,直到找到與選擇器 #rootGeo3DCanvas
匹配的祖先元素。如果找到了贿堰,則表示鼠標(biāo)當(dāng)前位于 3D 組件區(qū)域內(nèi)辙芍。通過 event.preventDefault()
來阻止頁面默認(rèn)的滾動行為。
解決后的效果:
修改后