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

页面含多个Swiper实例时调用swiper.destroy()方法触发报错

问题描述

同一页面存在多个Swiper实例时,需要根据屏幕宽度动态完成滑块的销毁与初始化操作,核心实现代码如下:

const mobile = window.matchMedia('(max-width: 575.98px)');

function instantiateGridSlider() {
const sliders = [];
$('.thumbnails-grid').each(function(index, element){
    const instance = $(this).data('instance');
    sliders[index] = new Swiper(element, {
    speed: 500,
    spaceBetween: 30,
    slidesPerView: 1,
    loop: true,
    init: false,
    pagination: {
        el: '.swiper-pagination-' + instance,
        type: 'bullets',
        clickable: true,
    },
    });
});

return sliders;
}

function initGridSlider() {
if ($('.thumbnails-grid').length == 0) {
    return;
}

const gridSliders = instantiateGridSlider();
for (let i = 0; i < gridSliders.length; i++) {
    if (mobile.matches) {
    gridSliders[i].init(gridSliders[i].el);
    } else {
    gridSliders[i].destroy(true, true);
    }
}
}

window.addEventListener('resize', function() {
initGridSlider();
});

initGridSlider();

调整窗口尺寸尝试销毁滑块时,触发如下报错:

Uncaught TypeError: Cannot read properties of undefined (reading 'children')
at Swiper.loopDestroy (loopDestroy.js:6:1)
at Swiper.destroy (core-class.js:545:1)
at initGridSlider (slider.js:84:1)
at slider.js:90:1

报错在执行loopDestroy逻辑时抛出,需要定位问题成因并获取可行修复方案。

问题成因
  • 每次触发initGridSlider都会重新创建一批全新的Swiper实例,从未清理过之前生成的旧实例。loop模式下Swiper初始化时会自动复制前后slide生成循环DOM结构,重复创建实例会导致DOM结构和实例内部状态完全不匹配。
  • 调用destroy方法前没有判断实例的初始化状态:如果实例创建时设置了init:false且从未执行过初始化,直接调用销毁方法会触发loop模块的清理逻辑,此时实例内部没有存储loop生成的DOM引用,访问children属性时就会拿到undefined抛出错误。
修复方案
  1. 全局缓存已创建的Swiper实例,不要每次resize都重复新建实例
  2. 执行销毁逻辑前先判断实例是否已完成初始化,未初始化的实例不需要调用destroy
  3. 断点切换时先清理所有已存在的旧实例,再根据当前屏幕宽度判断是否需要初始化新实例
  4. 增加resize防抖,避免窗口拖拽调整过程中频繁触发实例的创建、销毁逻辑

修复后的完整代码:

const mobile = window.matchMedia('(max-width: 575.98px)');
// 全局缓存Swiper实例
let gridSliders = [];

function destroyAllSliders() {
  gridSliders.forEach(slider => {
    // 仅对已初始化的实例执行销毁操作
    if (slider.initialized) {
      slider.destroy(true, true);
    }
  });
  // 清空实例缓存
  gridSliders = [];
}

function initGridSlider() {
  if ($('.thumbnails-grid').length === 0) {
    return;
  }
  // 每次状态切换前先清理所有旧实例
  destroyAllSliders();
  // 仅在移动端断点下创建并初始化Swiper
  if (mobile.matches) {
    $('.thumbnails-grid').each(function(index, element){
      const instance = $(this).data('instance');
      const slider = new Swiper(element, {
        speed: 500,
        spaceBetween: 30,
        slidesPerView: 1,
        loop: true,
        pagination: {
          el: '.swiper-pagination-' + instance,
          type: 'bullets',
          clickable: true,
        },
      });
      gridSliders.push(slider);
    });
  }
}

// resize防抖,避免频繁触发逻辑
let resizeTimer = null;
window.addEventListener('resize', function() {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(initGridSlider, 200);
});

// 首次加载执行初始化
initGridSlider();

如果使用的是Swiper 6及以上版本,更推荐直接使用组件自带的breakpoints配置项实现不同宽度下的效果切换,不需要手动编写销毁、初始化逻辑,组件内部会自动处理断点切换的状态更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:54:38