由於項目需求使用了原生組件 ion-slides 來實現輪播圖,從此踏上了一條不歸路
首先上HTML代碼
<ion-slides #slide1 [options]="slidesOpts" (click)="onClickSlide()">
<ion-slide *ngFor="let item of bannerList">
<img [src]="item.img" />
<div class="bannerIntro">
<div class="bannerIntroTitle">{{item.title}}</div>
<div class="bannerIntroNum">{{item.num}}</div>
</div>
</ion-slide>
</ion-slides>
JS
public slidesOpts = {//輪播圖屬性
speed: 500,
autoplay: {
delay: 5000,
disableOnInteraction: false//這個屬性很關鍵,拖動完自動播放
},
loop: true,
zoom: false,
}
問題一:拖動手勢和點擊手勢衝突
第一次實現點擊 (click)="onClickSlide()" 是在 <ion-slide> 上添加的點擊事件,剛開始好好的,可以點擊,突然有一天點擊事件沒有響應了,查了很久沒有發現原因,後來看網上把點擊事件放到了大組件上,然後我就拖到上面。
但是拖到上面後 ,原本還有個 (ionSlideTouchEnd)="slideTouchEnd()" 事件,拖動結束自動播放。點擊後兩個事件會同時響應。
解決方法:在 options 的 autoplay 屬性中設置 disableOnInteraction=false,不用監聽事件也可以自動播放
問題二:點擊事件獲取頁數
直接放代碼,網上都有,用到現在沒出現問題
//輪播圖點擊
onClickSlide() {
this.slide1.getActiveIndex().then(index=>{
console.log(index);
let leng = this.bannerList.length;
if (index>leng) {
index=index-leng-1
}else if(index == 0){
index = leng-1;//第0張是最後一張圖片
}else{
index--;
}
console.log(index);
let item = this.bannerList[index];
this.gotoNewsDetail(item)
});
}
問題三:離開頁面後不自動播放
需要在頁面中監聽生命週期函數,離開的時候停止,回來的時候播放
ionViewDidEnter(){
if (this.slide1) {
console.log("ionViewDidEnter")
this.slide1.startAutoplay()
}
}
ionViewDidLeave(){
console.log("ionViewDidLeave");
this.slideStopAutoplay()
}
slideStopAutoplay(){
if (this.slide1) {
this.slide1.stopAutoplay()
}
}
問題四:進入子頁面的時候,生命週期函數沒有響應
這個問題困擾了很久,今天終於找到了一個不太完美的解決辦法
首先,我的輪播圖是放在首頁的,首頁底部有四個tabs,當你進入子頁面的時候,生命週期函數是不走的,被 tabbar 攔截了,相當於是 tabs 整個大頁面在切換,所以你可以在 tabs 中獲取生命週期函數的響應
import { EventService } from '../service/event.service';
@ViewChild('TABS') tabs;
ionViewWillEnter() {
let activateComponent = this.tabs.outlet.component;
if (activateComponent instanceof MePage) {
///調用子頁面方法
activateComponent.subPageBack();
}else if (activateComponent instanceof SchoolPage) {
}else if (activateComponent instanceof FindPage) {
}else if (activateComponent instanceof NoticePage) {
activateComponent.refreshData();
}
}
ionViewDidLeave(){
let tab = this.tabs.getSelected();
if (tab=="school") {
this.eventService.eventEmit.emit(this.eventService.KeySchoolEnterInChildPage,"school頁面進入子頁面")
}
// let activateComponent = this.tabs.outlet.component;
// if (activateComponent instanceof MePage) {
// }else if (activateComponent instanceof SchoolPage) {
// console.log("kskskskksks");
// // activateComponent.slideStopAutoplay();
// }else if (activateComponent instanceof FindPage) {
// }else if (activateComponent instanceof NoticePage) {
// }
}
爲什麼 ionViewWillEnter 可以用 this.tabs.outlet.component 來判斷,而 ionViewDidLeave 卻要用通知呢,因爲ionViewDidLeave不能用 component,不信可以自己試一下,打印出來的 component 是沒有找到。
後面就簡單了用通知告訴首頁,你進到子頁面了哦,然後 stop 輪播。返回時就直接繼續播放。
在拼搏的大夥共勉之:長路漫漫,且行且珍惜~
--------------------------------------------------------------------------------------------------------------------
8月8日,更新問題
問題五:瀏覽器可以循環播放,原生包不能循環播放
查看Swiper文檔
loop
設置爲true 則開啓loop模式。loop模式:會在原本slide前後複製若干個slide(默認一個)並在合適的時候切換,讓Swiper看起來是循環的。
loop模式在與free模式同用時會產生抖動,因爲free模式下沒有複製slide的時間點。
注意紅字,在原本基礎上覆制若干個slide,可是在ionic的ng-for中時,異步加載的數據都還沒有返回時,就先加載了Swiper組件並複製了sliper
解決方法:*ngIf="bannerList.length" 判斷數組有數據再加載,完美解決