页面多JS Swiper实例销毁问题:桌面端销毁时实例数组为空的解决方法
问题分析与解决方案
嘿,我一眼就看到问题出在哪了——你把存储Swiper实例的swiperArray和init变量放在了swiperMode函数的内部!这意味着每次调用swiperMode(不管是页面加载还是窗口 resize),都会重新创建一个空的swiperArray,之前在移动端创建的实例根本没法被后续的销毁逻辑访问到。
核心问题拆解
当窗口尺寸是移动端时,你创建了Swiper实例并存在局部的swiperArray里,但函数执行完毕后,这个局部数组就被垃圾回收了。等你把窗口拉大到桌面宽度,再次调用swiperMode时,新的swiperArray是空的,自然销毁逻辑直接返回,没法清理之前的实例。
修复方案
把swiperArray和init变量移到函数外部,让它们在全局(或者至少是函数作用域之外)保持持久化。另外,我还优化了窗口宽度的判断方式,以及添加了防抖逻辑避免resize频繁触发:
// 把变量移到函数外部,保持持久化 var init = false; let swiperArray = []; function swiperMode() { const mobileBreakpoint = 972; let allWorks = document.querySelectorAll('.work-item__images'); const buildSlider = (element) => { return new Swiper(element, { loop: true, observer: true, observeParents: true, slidesPerView: 2.5, spaceBetween: 16, }); } // 移动端初始化逻辑 if (window.innerWidth <= mobileBreakpoint) { if (!init) { init = true; allWorks.forEach((item, id) => { const slider = buildSlider(item); swiperArray[id] = slider; }); } } // 桌面端销毁逻辑 else { if (swiperArray.length === 0) return; // 遍历销毁每个实例,同时清理数组 swiperArray.forEach(slider => { if (slider && typeof slider.destroy === 'function') { slider.destroy(true, true); } }); swiperArray = []; init = false; } } // 防抖函数,避免resize频繁触发 function debounce(func, delay = 200) { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; } /* On Load **************************************************************/ window.addEventListener('load', swiperMode); /* On Resize **************************************************************/ window.addEventListener('resize', debounce(swiperMode));
关键改动说明
- 变量持久化:
swiperArray和init移到函数外部,确保每次调用swiperMode都能访问到同一个数组,保存之前创建的实例。 - 窗口宽度判断优化:用
window.innerWidth替代document.body.clientWidth,前者更准确反映当前视口宽度,不受body的padding、margin样式影响。 - 安全销毁:在销毁前检查实例是否存在以及
destroy方法是否可用,避免报错。 - 防抖resize:添加防抖函数,避免窗口调整时连续触发多次
swiperMode,提升性能。
额外注意事项
- 如果你的项目使用模块化开发(比如ES6模块),不要用全局变量,可以把
swiperArray和init放在模块级作用域里,同样能保持持久化。 - 确保
allWorks每次调用swiperMode都重新获取,避免DOM结构变化后实例找不到对应的元素。
内容的提问来源于stack exchange,提问作者Masha Baranova
相关产品推荐
相关产品推荐

