ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

前端实战:滚动监听实现顶部 logo 平滑显隐效果

前端实战:滚动监听实现顶部 logo 平滑显隐效果 开发弹窗、侧边抽屉、全屏遮罩这类组件时经常会遇到一个问题弹窗弹出后底层页面依然可以滚动体验很差。常见方案就是控制body的滚动本文使用 jQuery 实现禁止页面滑动和恢复页面滑动同时说明坑点。核心原理修改body的overflow属性禁止滚动条阻止页面滚动。代码示例1. 禁止页面滚动// 禁止滚动 $(body).css(overflow, hidden);2. 恢复页面滚动// 恢复滚动就是你写的这句 $(body).css(overflow, auto);完整演示弹窗场景!DOCTYPE html html langzh-CN head meta charsetUTF-8 title禁止页面滚动演示/title script srchttps://cdn.jsdelivr.net/npm/jquery3.7.1/dist/jquery.min.js/script style .mask{ display: none; position: fixed; top:0;left:0; width:100%;height:100%; background: rgba(0,0,0,0.5); } /style /head body styleheight:2000px; button classopen打开弹窗禁止滚动/button div classmask button classclose关闭弹窗恢复滚动/button /div script // 打开弹窗禁止body滚动 $(.open).on(click, function(){ $(.mask).show(); $(body).css(overflow, hidden); }) // 关闭弹窗恢复body滚动 $(.close).on(click, function(){ $(.mask).hide(); $(body).css(overflow, auto); }) /script /body /html存在的问题重点滚动条消失页面会发生横向抖动overflow:hidden会直接隐藏滚动条页面宽度瞬间变大出现页面往右 “弹一下” 的抖动。解决思路禁止滚动时给 body 增加padding-right值等于滚动条宽度。// 获取滚动条宽度 function getScrollWidth(){ const div document.createElement(div); div.style.width 100px; div.style.height 100px; div.style.overflow scroll; div.style.position absolute; div.style.left -9999px; document.body.appendChild(div); const width div.offsetWidth - div.clientWidth; document.body.removeChild(div); return width; } // 禁止滚动 $(body).css({ overflow: hidden, paddingRight: getScrollWidth() px }); // 恢复滚动 $(body).css({ overflow: auto, paddingRight: 0px });移动端兼容性差在手机浏览器单纯设置body {overflow:hidden}经常失效手指依然可以上下拖动页面。移动端推荐搭配touchmove事件阻止。// 禁止移动端touch滚动 function preventTouch(e){ e.preventDefault(); } // 禁止滚动时绑定 document.addEventListener(touchmove, preventTouch, {passive:false}); // 恢复滚动时解绑 document.removeEventListener(touchmove, preventTouch);注意passive:false是新版浏览器要求否则无法执行e.preventDefault()页面滚动位置丢失设置overflow:hidden后部分浏览器会重置滚动位置。如果需要保留滚动位置需要额外记录scrollTop。其他方案对比表格方案优点缺点body overflow:hidden简单一行 jQuery 代码移动端失效、滚动条抖动固定定位 fixed 锁页面兼容性好需要记录保存 scrollTop阻止 touchmove 事件移动端效果好会禁止弹窗内部滚动总结PC 端简单场景直接使用//禁止 $(body).css(overflow,hidden) //恢复 $(body).css(overflow,auto)生产环境需要处理滚动条抖动移动端场景不能只靠 overflow必须配合 touchmove 事件。注意如果弹窗内部有滚动区域不能全局阻止 touchmove否则弹窗内部也无法滚动需要做事件判断
返回列表