NuxtJS中Swiper嵌入iFrame无法滑动需保留iFrame事件
Swiper轮播嵌入iFrame时无法在iFrame区域触发滑动的解决方法
问题描述
在NuxtJS项目中实现Swiper轮播组件时,slide内嵌入的iFrame广告会导致滑动卡顿:当触点/鼠标移动到iFrame覆盖区域时,Swiper无法接收到滑动事件,滑动操作直接中断。已尝试为iFrame添加scrolling='no'属性未生效,同时需要保留iFrame本身的交互事件正常响应能力。
原有Swiper初始化代码如下:
new Swiper(this.$refs.swiper, { slidesPerView: 'auto', spaceBetween: 20, centeredSlidesBounds: true, centerInsufficientSlides: true, watchSlidesProgress: true, watchSlidesVisibility: true, direction: 'horizontal', mousewheel: true, observer: true, observeParents: true, freeMode: true, parallax: true, initialSlide: slideNumber, keyboard: { enabled: true }, scrollbar: { el: '.swiper-scrollbar', draggable: true }, loopFillGroupWithBlank: false, pagination: { clickable: true }, autoHeight: true, modules: 'modules', on: { activeIndexChange: function (swiper) { vm.listenAds() setTimeout(() => { swiper.params.centeredSlides = true swiper.update() }, 100) }, afterInit: function (swiper) { setInterval(() => { swiper.update() }, 100) } } })
问题原因
iFrame是独立的文档上下文,会默认捕获自身区域内的所有指针、触摸、滚轮事件,父页面的Swiper无法获取到iFrame区域内的事件流,因此滑动到iFrame位置就会中断。scrolling='no'仅能禁止iFrame内部内容滚动,不会改变事件的捕获逻辑,因此无效。
解决方案
采用滑动过程中临时禁用iFrame指针事件,滑动结束后恢复的方案,既可以保证Swiper正常接收滑动事件,也不会影响iFrame的点击、交互能力:
- 添加CSS样式控制iFrame的交互权限
/* 滑动状态下临时禁用iFrame的指针事件 */ .swiper.is-swiping .swiper-slide iframe { pointer-events: none; }
- 补充Swiper的事件回调,在滑动生命周期切换状态类名
在原有on配置中追加以下回调,原有逻辑可以保留:
on: { // 原有activeIndexChange、afterInit回调保留,追加以下内容 touchStart: (swiper) => { swiper.el.classList.add('is-swiping') }, touchEnd: (swiper) => { // 延迟移除类名,避免滑动收尾阶段事件丢失 setTimeout(() => { swiper.el.classList.remove('is-swiping') }, 100) }, // 适配鼠标拖动场景 sliderMove: (swiper) => { if (!swiper.el.classList.contains('is-swiping')) { swiper.el.classList.add('is-swiping') } } }
- 可选优化
原有代码中afterInit里设置100ms间隔轮询调用swiper.update()的逻辑建议移除,会造成不必要的性能损耗,你已经开启了observer和observeParents配置,足够自动监听DOM变化完成更新。
如果需要适配鼠标滚轮在iFrame区域控制Swiper滑动,可以在iFrame上层覆盖一层透明div,滚轮事件触发时将事件转发给Swiper容器,点击事件触发时隐藏遮罩层将事件透传给iFrame即可,不需要跨域通信即可实现。
注意:不要永久给iFrame设置
pointer-events: none,会导致iFrame内的广告点击、表单交互全部失效,仅在滑动过程中临时禁用即可同时满足两类交互需求。
内容的提问来源于stack exchange,提问作者Sunil Verma
相关产品推荐
相关产品推荐

