鼠标悬停固定可滚动侧边栏时禁止页面主体滚动
解决Bootstrap 4侧边栏滚动时主体内容联动滚动的问题
这个问题我之前做项目时也碰到过,本质是元素重叠导致浏览器误判了滚动事件的目标。咱们用纯jQuery就能搞定,完全不用额外插件,具体步骤如下:
第一步:先确保侧边栏的基础样式正确
首先得让你的侧边栏成为独立的可滚动容器,给它加固定定位和垂直滚动属性,这样它的滚动区域和主体内容彻底分开:
.sidenav { position: fixed; top: 0; left: 0; height: 100vh; /* 占满整个视口高度 */ overflow-y: auto; /* 内容超出时显示滚动条 */ width: 25%; /* 对应offset-md-3的宽度,可根据你的布局调整 */ z-index: 100; /* 确保侧边栏在主体内容上方,避免鼠标事件被主体抢走 */ }
第二步:用jQuery控制滚动行为
我们需要监听三个核心事件,实现“鼠标在侧边栏上时禁止主体滚动,离开后恢复”的效果,同时还要处理侧边栏滚到顶/底时的浏览器默认滚动行为:
$(document).ready(function() { let isMouseOverSidenav = false; // 鼠标进入侧边栏时,标记状态并禁止body滚动 $('.sidenav').on('mouseenter', function() { isMouseOverSidenav = true; $('body').addClass('no-scroll'); }); // 鼠标离开侧边栏时,清除标记并恢复body滚动 $('.sidenav').on('mouseleave', function() { isMouseOverSidenav = false; $('body').removeClass('no-scroll'); }); // 处理侧边栏滚到顶/底时的浏览器默认滚动(防止继续滚动body) $('.sidenav').on('wheel', function(e) { const $sidebar = $(this); const scrollTop = $sidebar.scrollTop(); const totalScrollHeight = $sidebar[0].scrollHeight; const sidebarHeight = $sidebar.height(); const scrollDirection = e.originalEvent.deltaY; // 滚到顶部还想往上滑时,阻止默认行为 if (scrollTop === 0 && scrollDirection < 0) { e.preventDefault(); } // 滚到底部还想往下滑时,阻止默认行为 if (scrollTop + sidebarHeight >= totalScrollHeight && scrollDirection > 0) { e.preventDefault(); } }); // 动态添加禁止滚动的样式(避免单独写CSS文件) $('head').append(` <style> .no-scroll { overflow: hidden; position: fixed; width: 100%; } </style> `); });
关键细节说明
- z-index设置:必须给侧边栏加足够高的z-index,确保鼠标能正确触发侧边栏的事件,而不是被下方的主体内容区捕获。
- no-scroll类:用
position: fixed是为了避免body禁止滚动后出现页面跳变,overflow: hidden直接禁用了body的滚动功能。 - wheel事件处理:解决了侧边栏滚到顶/底时,浏览器会自动继续滚动body的问题,通过阻止默认行为彻底切断联动。
这样设置后,鼠标在侧边栏上滚动时,只有侧边栏会动,主体内容完全不受影响;鼠标离开侧边栏后,主体内容的滚动又会恢复正常。
内容的提问来源于stack exchange,提问作者lloyd
相关产品推荐
相关产品推荐

