You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VueJS 如何禁用外层div滚动 待内层div滚动到底部后恢复外层滚动

实现思路
  • 监听外层滚动容器的scroll事件,判断第一个区块是否完全滚动到视口外:核心逻辑为外层容器scrollTop + 视口高度 >= 第一个区块高度,可设置1~2px的阈值避免浏览器精度问题导致判断失效
  • 触发条件后给外层容器设置overflow: hidden禁用外层滚动,同时给第二个div设置overflow-y: auto启用内层滚动
  • 监听第二个div的scroll事件,判断是否滚动到内层底部,触底后恢复外层容器的overflow-y: auto即可恢复外层滚动能力
  • 滚动事件添加防抖处理,避免频繁触发导致的性能损耗,也可减少边界条件下的反复触发问题
完整代码示例
<div class="outer-container">
  <div class="section section-1">第一个区块内容</div>
  <div class="section section-2">第二个区块内容</div>
  <div class="section section-3">后续其他区块内容</div>
</div>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.outer-container {
  width: 100vw;
  height: 100vh;
  overflow-y: auto;
  scroll-behavior: smooth;
}
.section {
  width: 100%;
  height: 100vh;
}
.section-1 {
  background: #f5f5f5;
  padding: 24px;
  font-size: 20px;
}
.section-2 {
  background: #e0f7fa;
  overflow-y: hidden; /* 默认关闭内层滚动 */
  padding: 24px;
  font-size: 18px;
  line-height: 2;
}
.section-3 {
  background: #f3e5f5;
  padding: 24px;
  font-size: 20px;
}
const outer = document.querySelector('.outer-container')
const section1 = document.querySelector('.section-1')
const section2 = document.querySelector('.section-2')
const section1Height = section1.offsetHeight

// 防抖函数
function debounce(func, delay = 10) {
  let timer = null
  return function(...args) {
    clearTimeout(timer)
    timer = setTimeout(() => func.apply(this, args), delay)
  }
}

// 判断元素是否滚动到底部
function isScrollBottom(el, offset = 2) {
  return el.scrollTop + el.clientHeight >= el.scrollHeight - offset
}

// 外层滚动监听
const outerScrollHandler = debounce(() => {
  if (outer.scrollTop + outer.clientHeight >= section1Height) {
    // 第一个区块完全滚出视口,禁用外层滚动,启用内层滚动
    outer.style.overflowY = 'hidden'
    section2.style.overflowY = 'auto'
  }
})
outer.addEventListener('scroll', outerScrollHandler)

// 内层滚动监听
const innerScrollHandler = debounce(() => {
  if (isScrollBottom(section2)) {
    // 内层滚动到底部,恢复外层滚动
    outer.style.overflowY = 'auto'
    section2.style.overflowY = 'hidden'
    outer.scrollTop = section1Height + 1 // 避免停在边界反复触发
  }
})
section2.addEventListener('scroll', innerScrollHandler)

// 测试用:填充第二个区块的内容
for(let i = 0; i < 100; i++) {
  section2.innerHTML += `<p>第二个区块第${i+1}行测试内容</p>`
}
适配拓展说明
  • 如需支持反向滚动(用户在内层向上滚动回到顶部时切回外层滚动),可在内层滚动监听中增加判断:当section2.scrollTop === 0时,恢复外层滚动、禁用内层滚动即可
  • 移动端适配可额外监听touchmove事件处理,避免出现滚动穿透问题
  • 多组嵌套滚动场景可将上述逻辑封装为通用函数,传入对应容器节点即可复用

内容的提问来源于stack exchange,提问作者Jet Lye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 08:36:02