swiper.js 是一款強大的外掛,也是我最喜歡的開源外掛之一。它可以輕鬆實現輪播、tab 標籤以及各種風騷的頁面滑動效果。
我在自己的很多專案裡都用到了 swiper,配合 vue 使用真的非常方便。不過近日遇到一個小坑,幾番搜尋和試驗,才發現與 loop 特性有關。
具體現象是,當 swiper 開啟 loop 屬性實現迴圈輪播,同時用 vue 的事件繫結語法為每個輪播頁繫結事件,當輪播到特定的頁面時繫結的事件無法被正常監聽。
例如下面的程式碼:
<template>
<div id="app">
<div class="swiper-container">
<div class="swiper-wrapper">
<div
class="swiper-slide"
v-for="i in 2"
:key="i"
>Slide {{ i }}</div>
</div>
</div>
</div>
</template>
<script>
import Swiper from 'swiper'
import 'swiper/css/swiper.css'
export default {
name: 'app',
mounted () {
const mySwiper = new Swiper('.swiper-container', {
loop: true
})
console.log(mySwiper)
},
methods: {
handleClick (i) {
console.log(`click slide ${i}`)
}
}
}
</script>
這段程式碼實際上新增了兩頁輪番,loop = true 會實現迴圈輪播的效果。但實際使用過程中發現,Slide1 上繫結的 click 事件監聽,除了初始時第一次顯示時能正常捕獲外,當連續向左滾動之後顯示的 Slide1 頁上點選就沒效果了。同樣,向右滑動時,Slide2 上繫結的事件監聽器也可能出現問題。
開啟除錯控制檯檢視頁面元素,發現除了實際新增的兩頁輪播對應的 slide 元素之外,左邊多了一個複製的 Slide2 元素,而右邊則多了一個複製的 Slide1。
原來 Swiper 是通過在實際輪播頁前後複製若干個頁面來實現 loop(首尾相連迴圈滾動)效果的,聯想到前面提到的問題現象,馬上猜測是因為雖然複製了輪播頁元素但 vue 所繫結的事件處理器卻沒有被複制。於是進一步檢視了這個元素上繫結的事件監聽器,果然如此。
找到的問題原因,那也就有頭緒了。Swiper.js 自己其實也提供了一套事件繫結機制,我們只需要把原始碼裡 vue 指定繫結的事件監聽器通過 Swiper 初始選項中繫結就好了。調整後的程式碼如下。
<template>
<div id="app">
<div class="swiper-container">
<div class="swiper-wrapper">
<div
class="swiper-slide"
v-for="i in 2"
:key="i"
:data-index="i"
>Slide {{ i }}</div>
</div>
</div>
</div>
</template>
<script>
import Swiper from 'swiper'
import 'swiper/css/swiper.css'
export default {
name: 'app',
mounted () {
const mySwiper = new Swiper('.swiper-container', {
loop: true,
on: {
click: (e) => {
const index = e.target.dataset.index
console.log(`click slide ${index}`)
}
}
})
console.log(mySwiper)
}
}
</script>
再次試用點選事件,一切正常了。
本作品採用《CC 協議》,轉載必須註明作者和本文連結