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

模态框打开时禁止body标签滚动的问题求助

解决模态框打开时禁止Body滚动的问题

嘿,我看你在模态框弹出后想锁住Body滚动这件事上碰钉子了,试过wheelscroll函数和CSS方案都没效果对吧?别着急,我给你两个亲测有效的方案,应该能搞定这个问题。

方案一:CSS + JS 组合(推荐)

这个方案是最常用的,通过给Body添加/移除类来控制滚动,同时还能解决滚动条消失导致页面偏移的问题。

第一步:添加CSS样式

先在你的样式表中加入这个类:

/* 禁止Body滚动的类 */
.no-scroll {
  overflow: hidden;
  /* 用CSS变量保存滚动条宽度,防止页面偏移 */
  padding-right: var(--scrollbar-width, 0);
}

第二步:修改JS逻辑

我们需要在模态框打开时给Body加上这个类,关闭时移除,同时计算滚动条宽度来抵消页面偏移:

首先添加一个计算滚动条宽度的小函数:

// 计算浏览器滚动条的宽度
function getScrollbarWidth() {
  const documentWidth = document.documentElement.clientWidth;
  const windowWidth = window.innerWidth;
  return windowWidth - documentWidth;
}

然后修改你的popupOpenClose函数,加上控制滚动的逻辑,同时别忘了把你的.close按钮也加入关闭监听(原来的代码只监听了button[name=close],但你的关闭按钮是a标签):

/* eslint-disable */ 
function popupOpenClose(popup) { 
  /* Open popup */ 
  $(popup).show(); 
  // 打开模态框时:禁止Body滚动
  const scrollbarWidth = getScrollbarWidth();
  document.body.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`);
  document.body.classList.add('no-scroll');

  /* Close popup if user clicks on background */ 
  $(popup).click(function(e) { 
    if ( e.target == this ) { 
      if ($(popup).is(':visible')) { 
        $(popup).hide(); 
        // 关闭时恢复滚动
        document.body.classList.remove('no-scroll');
        document.body.style.removeProperty('--scrollbar-width');
      } 
    } 
  }); 
  /* Close popup and remove errors if user clicks on cancel or close buttons */ 
  $(popup).find("button[name=close], .close").on("click", function() { 
    if ($(".formElementError").is(':visible')) { 
      $(".formElementError").remove(); 
    } 
    $(popup).hide(); 
    // 关闭时恢复滚动
    document.body.classList.remove('no-scroll');
    document.body.style.removeProperty('--scrollbar-width');
  }); 
} 
$(document).ready(function () { 
  $("[data-js=open]").on("click", function() { 
    popupOpenClose($(".popup")); 
  }); 
  // 给你的CENIK按钮绑定打开事件(原按钮无data-js属性)
  $(".button[href='#popup1']").on("click", function(e) {
    e.preventDefault();
    popupOpenClose("#popup1");
  });
})

注:我给你的CENIK按钮也加了打开事件,因为原来的JS只监听了[data-js=open]元素,但你的按钮没有这个属性,这样点击CENIK就能正确弹出模态框啦。

方案二:JS阻止滚动事件(备选)

如果CSS方案还是无效,可能是你的页面结构里有其他滚动容器,这时候可以直接用JS阻止滚动事件:

/* eslint-disable */ 
let isModalActive = false;

// 阻止滚动的函数
function blockScroll(e) {
  e.preventDefault();
  e.stopPropagation();
}

function popupOpenClose(popup) { 
  /* Open popup */ 
  $(popup).show(); 
  isModalActive = true;
  // 监听滚动事件,注意要设置passive:false,否则preventDefault无效
  document.body.addEventListener('wheel', blockScroll, { passive: false });
  document.body.addEventListener('touchmove', blockScroll, { passive: false }); // 适配移动端

  /* Close popup if user clicks on background */ 
  $(popup).click(function(e) { 
    if ( e.target == this ) { 
      if ($(popup).is(':visible')) { 
        $(popup).hide(); 
        isModalActive = false;
        // 移除监听,恢复滚动
        document.body.removeEventListener('wheel', blockScroll);
        document.body.removeEventListener('touchmove', blockScroll);
      } 
    } 
  }); 
  /* Close popup and remove errors if user clicks on cancel or close buttons */ 
  $(popup).find("button[name=close], .close").on("click", function() { 
    if ($(".formElementError").is(':visible')) { 
      $(".formElementError").remove(); 
    } 
    $(popup).hide(); 
    isModalActive = false;
    // 移除监听,恢复滚动
    document.body.removeEventListener('wheel', blockScroll);
    document.body.removeEventListener('touchmove', blockScroll);
  }); 
} 
$(document).ready(function () { 
  $("[data-js=open]").on("click", function() { 
    popupOpenClose($(".popup")); 
  }); 
  $(".button[href='#popup1']").on("click", function(e) {
    e.preventDefault();
    popupOpenClose("#popup1");
  });
})

这个方案的核心是在模态框打开时给Body绑定阻止滚动的事件,关闭时解绑。要注意设置passive: false,因为现代浏览器默认touchmove等事件是passive模式,preventDefault会失效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:13:35