如何用jQuery检测弹窗display为flex/block时设置body的overflow为hidden
原代码存在的问题
css()方法使用逻辑错误:jQuery的.css()方法传入两个参数时为设置样式属性,而非读取。你写的$(".bdp-poup").css("display", "flex")会直接强制将弹窗的display属性设为flex,完全没有读取当前值做判断的作用。读取样式属性只需传入属性名一个参数,即$(".bdp-poup").css("display")。- 判断条件不符合需求:需求要求
display为flex或block时都要锁定页面滚动,原代码仅覆盖了flex一种情况。 - 选择器使用错误:
$('.body')是选中class为body的元素,而要选中页面的<body>标签应该使用无点的标签选择器$('body')。 - 轮询方案性能&体验缺陷:
setInterval每秒固定轮询的方式,无论弹窗状态是否变化都会执行逻辑,存在不必要的性能开销,同时最多会有1秒的响应延迟,体验较差。 - 缺少边界兼容:如果页面上不存在
.bdp-poup元素,代码仍会执行,可能导致body的overflow属性被错误修改。
修复方案
方案1:修复原轮询逻辑(简单适配原写法)
如果需要保留原轮询的实现方式,修复后代码如下:
function checkPopup() { const $popup = $(".bdp-poup"); // 先判断弹窗元素是否存在 if (!$popup.length) return; // 读取当前display属性 const displayVal = $popup.css("display"); // 判断是否为展示状态 if (displayVal === "flex" || displayVal === "block") { $('body').css('overflow', 'hidden'); } else { $('body').css('overflow', 'auto'); } } setInterval(checkPopup, 1000);
方案2:更优的MutationObserver监听方案(推荐)
使用MutationObserver直接监听弹窗元素的属性变化,无需轮询,状态变化实时响应,性能更好:
const $popup = $(".bdp-poup"); if ($popup.length) { // 初始化状态同步 const initDisplay = $popup.css("display"); $('body').css('overflow', (initDisplay === 'flex' || initDisplay === 'block') ? 'hidden' : 'auto'); // 创建观察者实例 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { // 仅监听style属性变化 if (mutation.attributeName === 'style') { const currentDisplay = $popup.css('display'); $('body').css('overflow', (currentDisplay === 'flex' || currentDisplay === 'block') ? 'hidden' : 'auto'); } }); }); // 配置监听目标:监听style属性变化 observer.observe($popup[0], { attributes: true, attributeFilter: ['style'] }); }
内容的提问来源于stack exchange,提问作者DNa
相关产品推荐
相关产品推荐

