1在平时开发中经常会遇到这样一种问题当打开一个弹窗时后面的页面是可以滚动的演示如下
 2
 3

那么,该如何锁定页面的滚动呢?

一、传统的实现方式

传统的方式其实也不复杂,就是在打开弹窗时阻止滚动就行了,通常是改变overflow属性

`const openModal = () => {
document.body.style.overflow = ‘hidden’}

const closeModal = () => {
document.body.style.overflow = ‘auto’}
`

如果是在现代框架里,比如vue,可以用监听弹窗状态来实现

watch( () => show.value, (val) => { if (val) { document.body.style.overflow = 'hidden' } else { document.body.style.overflow = 'auto' } },)

这样就能锁定滚动了

二、传统方式的局限

虽然上面的实现看似完美,其实还有潜在问题的。比如有多个弹窗,弹窗覆盖的情况下,这个时候锁定就会出问题了。

因为在关闭第二个弹窗的时候,页面已经解除锁定了,所以在第一个弹窗还在的时候,页面已经可以滚动了

如果想要优化这个问题,还需要做进一步判断。

三、借助 CSS has 实现

现在有了CSS :has伪类,一切就好办了,无需过多的判断,直接一个选择器搞定

body:has(dialog[open]){ overflow: hidden}

这行选择器表示,只要有属性为open的弹窗,body就自动锁定,无论有多少层弹窗

是不是非常简单?

完整代码可以查看:CSS has lock scroll (juejin.cn)[1]

四、has已经全兼容了

提一下兼容性,目前现代浏览器都支持了,如下

个人笔记记录 2021 ~ 2025