一段程式碼闡述一個輪播思路
不BB,直接上程式碼:
1. if (direction === `next`) {
2. this.index = nextIndex;
3. /*如果是下一個,那就先吧下個的dom設定成none來移動位置,防止使用者看到*/
4. nextEl.style.display = `none`;
5. nextEl.style.webkitTransition = ``;
6. currentEl.style.display = `block`;
7. currentEl.style.webkitTransition = `-webkit-transform ` + this.speed + `ms ease-in-out`;
8. setTimeout(()=> {
9. /*將下個放到指定的位置*/
10. nextEl.style.webkitTransform = this.toward === `horizontal` ? `translate3d(100%, 0, 0)` : `translate3d(0, 100%, 0)`;
11. nextEl.style.display = `block`;
12. nextEl.style.webkitTransition = `-webkit-transform ` + this.speed + `ms ease-in-out`;
13. setTimeout(() => {
14. /*開始輪播*/
15. currentEl.style.webkitTransform = this.toward === `horizontal` ? `translate3d(-100%, 0, 0)` : `translate3d(0, -100%, 0)`;
16. nextEl.style.webkitTransform = `translate3d(0, 0, 0)`;
17. }, 20);
18. }, 10);
19. }
注意:以上只是主思路程式碼,完整的程式碼解讀完之後會貼出來供大家參考。
程式碼解讀:思路是先判斷滾動方向,如果是向下一個節點那我就準備下一個節點到指定位置(僅適合介面一次展示一個輪播節點),如果直接移動到指定位置肯定是不合理的,因為節點直接移動會讓使用者在瀏覽器介面看到,可是節點是肯定要移動啊,思路很簡單,那我給節點穿一件隱身衣(display:none),之後再移動到指定位置使用者不就看不到了,但是注意這裡存在一個問題,如果直接設定設定display:none之後立馬就移動位置的話會存在一個問題,移動的效果使用者仍然能看的到,這是因為非非同步的JS程式碼在執行的過程中是會阻止瀏覽器的繪圖和重繪的,所以為了繞開瀏覽器這個機制那就使用非同步好了(setTimeout),下一個節點的位置現在已經準備好了,現在如果還是直接移動的話,又會存在一個問題下一個節點竟然看不到移動,這是因為我們在準備節點的節點的時候已經將它隱藏了,所以為了讓使用者看到就不得不把隱身衣脫了(display:block)才行,這樣又得加一個非同步(setTimeout)才能生效了,現在就可以安心的執行當前節點和早已就緒的下一個節點了。
完整程式碼如下:
下面的輪播JS部分的程式碼是vue寫的,主要功能包括了垂直輪播,水平輪播,手勢輪播等幾個輪播的主要功能
export default {
name: `swipe`,
props: {
/*預設是水平滾動*/
toward: {
type: String,
default: `vertical`
},
/*是否展示指示標誌*/
showIndicators: {
type: Boolean,
default: true
},
/*滾動速度*/
speed: {
type: Number,
default: 300
},
/*預設下標從哪兒開始*/
defaultIndex: {
type: Number,
default: 0
},
/*自動滾動間隔*/
interval: {
type: Number,
default: 3000
}
},
data() {
return {
dots: [], // 頁面標記圓點
index: this.defaultIndex, //當前頁面的下標
pageEls: [], // 所有的子輪播項集合
timer: null, //輪播定時器物件
noSwipe: false, //禁止滾動
startPosition: ``, //touch的起始位置
currentPosition: ``, //touch的目前位置
translatePosition: ``, //touch位移的位置
distance: 10, //touch的位移大於10的時候生效
}
},
watch: {},
beforeMount: function () {
},
mounted(){
this.initSwipe();
this.swipeTimeout();
this.initTouchEvent();
},
computed: {
getNum(){
return this.pageEls.length;
},
},
methods: {
/*手動上一張*/
prev(){
window.clearTimeout(this.timer);
this.swipeTimeout(`prev`);
},
/*手動下一張*/
next(){
window.clearTimeout(this.timer);
this.swipeTimeout(`next`);
},
initTouchEvent(){
let dom = this.$el.querySelector(`.swipe-warp`);
dom.addEventListener(`touchstart`, this.handleTouchStart);
dom.addEventListener(`touchmove`, this.handleTouchMove);
dom.addEventListener(`touchend`, this.handleTouchEnd);
console.log(dom);
},
/*初始化輪播節點*/
initSwipe(){
var children = this.$children;
if (children.length === 1) {
this.noSwipe = false;
return;
}
children.forEach((child, _index)=> {
this.pageEls.push(child.$el);
});
},
/*定時輪播*/
swipeTimeout(toward = `next`){
this.translate(toward, ()=> {
this.timer = window.setTimeout(()=> {
this.swipeTimeout(`next`);
}, this.interval);
});
},
/*滾動方法*/
translate(direction = `next`, cb){
let length = this.pageEls.length;
let currentIndex = this.index;
let currentEl = this.pageEls[currentIndex];
let nextIndex = ((this.index + 1) > (length - 1)) ? 0 : (this.index + 1);
let nextEl = this.pageEls[nextIndex];
let pervIndex = (this.index - 1) < 0 ? (length - 1) : (this.index - 1);
let pervEl = this.pageEls[pervIndex];
if (direction === `next`) {
this.index = nextIndex;
/*如果是下一個,那就先吧下個的dom設定成none來移動位置,防止使用者看到*/
nextEl.style.display = `none`;
nextEl.style.webkitTransition = ``;
currentEl.style.display = `block`;
currentEl.style.webkitTransition = `-webkit-transform ` + this.speed + `ms ease-in-out`;
setTimeout(()=> {
/*將下個放到指定的位置*/
nextEl.style.webkitTransform = this.toward === `horizontal` ? `translate3d(100%, 0, 0)` : `translate3d(0, 100%, 0)`;
nextEl.style.display = `block`;
nextEl.style.webkitTransition = `-webkit-transform ` + this.speed + `ms ease-in-out`;
setTimeout(() => {
/*開始輪播*/
currentEl.style.webkitTransform = this.toward === `horizontal` ? `translate3d(-100%, 0, 0)` : `translate3d(0, -100%, 0)`;
nextEl.style.webkitTransform = `translate3d(0, 0, 0)`;
}, 20);
}, 10);
} else {
this.index = pervIndex;
/*如果是上一個,那就先吧上個的dom設定成none來移動位置,防止使用者看到*/
pervEl.style.display = `none`;
pervEl.style.webkitTransition = ``;
currentEl.style.display = `block`;
currentEl.style.webkitTransition = `-webkit-transform ` + this.speed + `ms ease-in-out`;
setTimeout(()=> {
/*將上個放到指定的位置*/
pervEl.style.webkitTransform = this.toward === `horizontal` ? `translate3d(-100%, 0, 0)` : `translate3d(0, -100%, 0)`;
pervEl.style.display = `block`;
pervEl.style.webkitTransition = `-webkit-transform ` + this.speed + `ms ease-in-out`;
setTimeout(() => {
/*開始輪播*/
currentEl.style.webkitTransform = this.toward === `horizontal` ? `translate3d(100%, 0, 0)` : `translate3d(0, 100%, 0)`;
pervEl.style.webkitTransform = `translate3d(0, 0, 0)`;
}, 20);
}, 10);
}
this.once(currentEl, `webkitTransitionEnd`, ()=> {
cb && cb();
});
},
handleTouchStart($evnet){
this.startPosition = this.toward === `horizontal` ? $evnet.touches[0].clientX : $evnet.touches[0].clientY;
},
handleTouchMove($evnet){
this.currentPosition = this.toward === `horizontal` ? $evnet.touches[0].clientX : $evnet.touches[0].clientY;
this.translatePosition = this.currentPosition - this.startPosition;
this.translatePosition !== 0 && window.clearTimeout(this.timer);
$evnet.preventDefault();
$evnet.stopPropagation();
},
handleTouchEnd($evnet){
this.translatePosition < 0 && this.translatePosition < -this.distance && this.swipeTimeout(`next`);
this.translatePosition > 0 && this.translatePosition > this.distance && this.swipeTimeout(`prev`);
},
/*管理事件*/
once(el, event, fn) {
var that = this;
var listener = function () {
if (fn) {
fn.apply(this, arguments);
}
that.off(el, event, listener);
};
this.on(el, event, listener);
},
/*監聽事件*/
on(element, event, handler){
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
},
/*移除事件*/
off(element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false);
}
}
}
};