JS實現某東移動web輪播圖
阿新 • • 發佈:2019-01-04
移動web輪播圖
參考例項,可以從中儲存輪播圖的圖片,這裡我們放入uploads的資料夾下,將八張圖片一次改為l1.jpg,l2.jpg…
HTML
- 這裡要放入十張圖片,因為手指滑動的時候要從第一張滑動到最後一張,是無縫滑動,當然可以用原生的JS進行新增
- 最終我們可以通過移動ul來達到輪播的效果,所以ul的寬度要剛好放得下十張圖片
- ol下的li是分頁器,也就是我們看到的圓圈,類.current為選中狀態
- clearfix類是清除浮動
<div class="jd_banner">
<ul class="jd_wrap clearfix">
<li><a href="javascript:;"><img src="uploads/l8.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l1.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l2.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l3.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l4.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l5.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l6.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l7.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l8.jpg" alt=""></a></li>
<li><a href="javascript:;"><img src="uploads/l1.jpg" alt=""></a></li>
</ul>
<ol>
<li class="current"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
css樣式
.clearfix::before,
.clearfix::after{
content: "";
display: block;
height: 0;
line-height: 0px;
clear: both;
visibility: hidden;
}
.jd_banner {
max-width: 640px;
min-width: 320px;
margin: 100px auto;
width: 100%;
position: relative;
overflow: hidden;
}
.jd_banner .jd_wrap {
width: 1000%;
transform: translateX(-10%);
}
.jd_banner .jd_wrap li {
width: 10%;
float: left;
}
.jd_banner .jd_wrap li img {
width: 100%;
}
.jd_banner ol {
height: 10px;
position: absolute;
left: 50%;
bottom: 3px;
transform: translateX(-50%);
}
.jd_banner ol li {
width: 6px;
height: 6px;
float: left;
border: 1px solid #fff;
margin-left: 10px;
border-radius: 50%;
}
.jd_banner ol li.current {
background: #fff;
}
JS
- 我們主要通過控制index,translateX,監聽過渡動畫的結束(webkitTransitionEnd)來實現輪播
- 對index進行限制
- 相同的程式碼進行封裝
- 優化程式碼
var jdCon = document.querySelector('.jd_banner')
var ul = document.querySelector('.jd_banner>.jd_wrap')
var index = 1
var li = ul.querySelectorAll('li')
var olLi = document.querySelectorAll('ol>li')
var imgWidth = li[0].offsetWidth
// 過渡移動的效果
var transit = function(move){
var move = move || 0
ul.style.transition = 'all 0.5s linear'
ul.style.transform = `translateX(${-imgWidth*index+move}px)`
}
// 瞬間定位效果
var moment = function(distanceMove){
var distanceMove = distanceMove || 0
ul.style.transform = `translateX(${-imgWidth*index+distanceMove}px)`
ul.style.transition = 'none'
}
window.onresize = function(){
imgWidth = li[0].offsetWidth
}
var timer1 = setInterval(function(){
index++;
transit()
}, 1000)
ul.addEventListener('webkitTransitionEnd', function(){
if(index>li.length-2){
index = 1
moment()
}
if(index<1){
index = li.length-2
moment()
}
document.querySelector('.current').classList.remove('current')
olLi[index-1].classList.add('current')
})
var distanceStart = 0;
var move = 0;
var distanceEnd = 0;
jdCon.addEventListener('touchstart',function(e){
clearInterval(timer1)
distanceStart = e.touches[0].clientX
})
jdCon.addEventListener('touchmove',function(e){
var distance = e.touches[0].clientX
move = distance - distanceStart
moment(move)
})
jdCon.addEventListener('touchend',function(){
if(move>imgWidth/2){
index--
transit()
}else if(move<-imgWidth/2){
index++
transit()
}else{
transit()
}
distanceStart = 0;
move = 0;
distanceEnd = 0;
timer1 = setInterval(function(){
index++;
transit()
}, 1000)
})
整體思路
- 首先做好佈局,ul的子元素li要在一行上,無縫連結
- 利用css,ul的寬度為1000%, 設定transform: translateX(-10%);,使得不會顯示展示給使用者的最後一張圖片,顯示第一張圖片
- 自動播放輪播圖
- 利用定時器,讓index每次加1,然後過渡滾動一張圖片
var timer1 = setInterval(function(){
index++;
ul.style.transition = 'all 0.5s linear'
ul.style.transform = `translateX(${-imgWidth*index}px)`
}, 1000)
- 監聽webkitTransitionEnd,過渡動畫結束時,清除當前的類.current,給ol下的li[index]新增一個類
- 過渡動畫結束後,如果index過大,我們要對其進行限制,當index為9,此時介面顯示的是第十張圖片,也就是使用者看到的第一張圖片,所以我們瞬間(在0s)讓其移動到第一張,在令index=1
ul.addEventListener('webkitTransitionEnd', function(){
// 當時間過渡結束
// 新增.current
if(index>8){
// 當第一張移動完成後
// 瞬間讓index變為1
ul.style.transform = `translateX(${-imgWidth}px)`
ul.style.transition = 'none'
index = 1
} document.querySelector('.current').classList.remove('current')
olLi[index-1].classList.add('current')
})
- ul跟隨著手指的滑動而滑動,當手指滑動多少,ul跟著滑動多少
var distanceStart = 0;
var move = 0;
var distanceEnd = 0;
jdCon.addEventListener('touchstart',function(e){
clearInterval(timer1)
distanceStart = e.touches[0].clientX
})
jdCon.addEventListener('touchmove',function(e){
var distance = e.touches[0].clientX
move = distance - distanceStart
ul.style.transform = `translateX(${-imgWidth*index+move}px)`
ul.style.transition = 'none'
})
- 滑動結束時做吸附效果
- 向右滑動時,如果滑動大於圖片二分之一的寬度,當手指放開則加上過渡動畫效果移動到上一張圖片,此時我們移動始終是控制index
if(move>imgWidth/2){
index--
ul.style.transition = 'all 0.5s linear'
ul.style.transform = `translateX(${-imgWidth*index}px)`
}
- 向左滑動時,如果滑動大於圖片二分之一的寬度,當手指放開則加上過渡動畫效果移動到下一張圖片,此時我們移動始終是控制index
else if(move<-imgWidth/2){
index++
ul.style.transition = 'all 0.5s linear'
ul.style.transform = `translateX(${-imgWidth*index}px)`
}
- 其它情況保持顯示現狀的圖片
else{
ul.style.transition = 'all 0.5s linear'
ul.style.transform = `translateX(${-imgWidth*index}px)`
}
- 最後所有的清0,開啟定時器
- 相同程式碼封裝,測試是否有bug,發現右滑有問題--------始終通過控制index來實現移動和切換ol分頁器,要對index進行限制。對數字通過ul下的li.length來控制,將程式碼封裝成可呼叫,可讀性,邏輯性的程式碼
if(index<1){
ul.style.transform = `translateX(${-imgWidth*8}px)`
ul.style.transition = 'none'
index = 8
}
步驟
/*
獲取 必須知道的 變數
步驟1: 不考慮過渡效果 直接 刷刷刷的 切換
定時器中 index++
判斷是否越界
修改 輪播圖ul的 位置
考慮到 索引從1開始
css 預設 讓ul 往左邊竄一個螢幕寬度
步驟2: 下方的 索引li標籤 修改 外觀
由於我們是使用.current 標示當前的索引值
清空所有li的 class
為當前的那個 li 新增current
步驟3:然切換有動畫效果
使用css3中的transition
.style.transition ='all .3s';
在獲取的時候 進行新增即可
步驟4:當我切換到 最後一張時 瞬間 切到 第一張
關閉過度
瞬間切換到第一張
步驟5:對程式碼 進行重構 新增進來了 過渡結束知識點
由於 我們在修改 ul的位置時 會使用過度
當註冊了 過渡結束事件之後,每次 過渡完畢 都會 呼叫該事件
將 判斷 index 是否 越界 以及 修改 索引的 程式碼 全部 遷移到 過渡結束事件中
定時器邏輯
index++;
修改 ul的 位置 ->開始過渡
過渡結束事件邏輯
判斷 index是否有效
進行修正
修改索引li標籤的 顯示
步驟6: 使用touch事件,實現 手指 撥動 ul滑動 效果
touchstart
記錄開始值
關閉定時器
關閉過渡效果
touchmove
計算移動值
修改ul的位置(在原始值的基礎上進行修改,沒有過渡效果的)
touchend
記錄移動的距離(?)
開啟定時器(*)
*/
疑問
- 寬高必須考慮到移動web的適配方案
- 可能大家會把ul進行定位,ul定位(absolute),我們就無法把父盒子撐開,也就是父盒子jd_banner就沒有高度,到時ol也很難定位,影響頁面佈局等問題
- 直接給父盒子設定高度,但是我們這個高度不好設定,因為不同的螢幕圖片高度是不一致的
- 使用translateX來移動邏輯會更簡單些
- 注意要樣式重置,比如img要去掉基線
- clearfix可以不加,因為父盒子jd_banner已經設定overflow: hidden;會觸發bfc