滚动时为重叠div添加shadow类及滚轮适配问题求助
解决堆叠面板的阴影添加与鼠标滚轮支持问题
首先,我帮你梳理下原代码里的几个核心问题,然后给出修改后的完整代码和详细解释:
原代码的主要问题
- 阴影类判断逻辑偏差:你当前是在面板到达固定位置时就添加阴影,但这时候面板还没和前一个面板重叠,不符合"仅重叠时加阴影"的需求。
- 鼠标滚轮不兼容:苹果妙控鼠标默认是纵向滚动,而你的容器是横向滚动,需要手动把纵向滚动事件转换成横向滚动。
- 初始定位冲突:
.wrapper和.box都设置了position: sticky,这会导致布局异常,应该把.box的初始定位改为static。 - 阴影移除逻辑不全:在面板回到原位置的分支里没有移除阴影类,导致阴影不会在不重叠时消失。
修改后的完整代码
HTML(无改动)
<div class="wrapper"> <div class="box box1"></div> <div class="box box2"></div> <div class="box box3"></div> <div class="box box4"></div> <div class="box box5"></div> <div class="box box6"></div> <div class="box box7"></div> <div class="box box8"></div> </div>
CSS(修正定位与样式)
body { margin: 0; padding: 0; } .wrapper { width: 1442px; border-right: 1px solid #f2f2f2; border-bottom: 1px solid #f2f2f2; display: flex; overflow: scroll; /* 移除不必要的sticky定位,改用relative */ position: relative; height: 750px; } .box { /* 初始定位改为static,避免和容器定位冲突 */ position: static; height: 750px; z-index: 1; } .wrapper .box1 { min-width: 357px; background-color: #1a1a1a; } .wrapper .box2 { min-width: 357px; background-color: #333; } .wrapper .box3 { min-width: 702px; background-color: #4d4d4d; } .wrapper .box4 { min-width: 630px; background-color: #666; } .wrapper .box5 { min-width: 630px; background-color: #808080; } .wrapper .box6 { min-width: 357px; background-color: #999; } .wrapper .box7 { min-width: 630px; background-color: #b3b3b3; } .wrapper .box8 { min-width: 630px; background-color: #ccc; } .shadow { box-shadow: -4px 0px 40px rgba(0, 0, 0, 0.2); }
JavaScript(修正阴影逻辑与添加滚轮支持)
const boxes = Array.from(document.querySelectorAll(".box")); const wrapper = document.querySelector(".wrapper"); const leftMargin = 60; //px function scrollWrap(e) { let scrollCoord = wrapper.scrollLeft; // 横向滚动值 boxes.forEach((box, index) => { let leftMarginStop = index * leftMargin; const boxCoord = box.getBoundingClientRect(); // 获取前一个面板(如果存在) const prevBox = index > 0 ? boxes[index - 1] : null; let isOverlapping = false; if (boxCoord.left <= leftMarginStop) { // 面板到达固定位置 box.style.position = "sticky"; box.style.left = `${leftMarginStop}px`; // 判断是否和前一个面板重叠:当前面板左边缘 <= 前一个面板右边缘 if (prevBox) { const prevBoxCoord = prevBox.getBoundingClientRect(); isOverlapping = boxCoord.left <= prevBoxCoord.right; } } else { // 面板回到原位置 box.style.position = "static"; box.style.left = 0; } // 根据重叠状态添加/移除阴影类 isOverlapping ? box.classList.add("shadow") : box.classList.remove("shadow"); }); } // 监听容器横向滚动 wrapper.addEventListener("scroll", scrollWrap); // 监听鼠标滚轮,转换为横向滚动 wrapper.addEventListener("wheel", (e) => { e.preventDefault(); // 阻止默认纵向滚动行为 // 将纵向滚动差值转为横向滚动距离,1.5是速度系数可调整 wrapper.scrollBy({ left: e.deltaY * 1.5, behavior: "smooth" // 可选:平滑滚动效果 }); });
关键修改点解释
1. 阴影类判断逻辑优化
现在我们会检查当前面板和前一个面板的位置关系:只有当当前面板的左边缘小于等于前一个面板的右边缘时,才判定为重叠,这时候才添加shadow类。这样就精准实现了"仅重叠时显示阴影"的需求。
2. 鼠标滚轮支持
添加了wheel事件监听,通过e.deltaY获取纵向滚动的差值,再调用scrollBy将其转换为横向滚动。同时用e.preventDefault()阻止页面默认的纵向滚动,确保操作完全作用在横向容器上。你可以调整1.5这个系数来改变滚动速度,适配自己的操作习惯。
3. 布局定位修正
移除了.wrapper的sticky定位(容器不需要粘性),并将.box的初始定位改为static,避免了定位冲突,让粘性定位的逻辑能正常工作。
4. 阴影移除逻辑完善
现在每次循环都会根据重叠状态更新阴影类,确保面板不重叠时阴影会及时消失,不会残留。
你可以把这些代码替换进去测试,应该就能解决你遇到的两个问题了。如果还有细节需要调整,比如阴影样式或滚动速度,直接修改对应的参数即可~
内容的提问来源于stack exchange,提问作者user2762414
相关产品推荐
相关产品推荐

