實現移動端滑動輪播和定時輪播
- slidebanner.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>移動端-輪播圖</title>
<link rel="stylesheet" href="slideshow.css">
</head>
<body>
<div class="layout">
<div class="banner">
<ul class="clearfix">
<li><a href="#"><img src="images/5.jpg"></a></li>
<li><a href="#"><img src="images/1.jpg"></a></li>
<li><a href="#"><img src="images/2.jpg"></a></li>
<li><a href="#"><img src="images/3.jpg"></a></li>
<li><a href="#"><img src="images/4.jpg"></a></li>
<li><a href="#"><img src="images/5.jpg"></a></li>
<li><a href="#"><img src="images/1.jpg"></a></li>
</ul>
<ul>·
<li class="now"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
<script src="base.js"></script>
<script src="slideshow.js"></script>
</body>
</html>
- slidebanner.css
*,
::before,
::after{
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;/*兼容移動端主流瀏覽器*/
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;/*清除移動端點擊高亮效果*/
}
body{
font-family:Microsoft YaHei,sans-serif;/*移動端默認的字體*/
font-size: 14px;
color: #333;
}
ol,ul{
list-style: none;
}
/*清除浮動*/
.clearfix::before,
.clearfix::after{
content: "";
display: block;
height: 0;
line-height: 0;
visibility: hidden;
clear: both;
}
.layout{
width: 100%;
max-width: 750px;
min-width: 320px;
margin: 0 auto;
position: relative;
}
.banner{
width: 100%;
height: 300px;
overflow: hidden;
position: relative;
}
.banner ul:first-child{
width: 1000%;
height: 300px;
-webkit-transform: translateX(-10%);
transform: translateX(-10%);
}
.banner ul:first-child li{
width: 10%;
height: 100%;
float: left;
}
.banner ul:first-child li a{
display: block;
width: 100%;
height: 100%;
}
.banner ul:first-child li a img{
width: 100%;
height: 100%;
display: block;
}
.banner ul:last-child{
position: absolute;
bottom: 6px;
width: 100%;
text-align: center;
}
.banner ul:last-child li{
width: 6px;
height: 6px;
border: 1px solid #fff;
border-radius: 50%;
display: inline-block;
margin-left: 10px;
}
.banner ul:last-child li:first-child{
margin-left: 0;
}
.banner ul:last-child li.now{
background: #fff;
}
- slidebanner.js
/*封裝一些公用的事件或者公用的方法*/
/*定義的一個命名空間*/
window.S = {};
/*封裝一個事件 過渡結束事件*/
S.transitionEnd = function(dom,callback){
//1.給誰加事件
//2.事件觸發後處理什麼業務
if(!dom || typeof dom != 'object'){
//沒dom的時候或者不是一個對象的時候 程序停止
return false;
}
dom.addEventListener('transitionEnd', function(){
callback && callback();
});
dom.addEventListener('webkitTransitionEnd', function(){
callback && callback();
});
}
window.onload = function(){
/*
* 1.自動輪播 定時器 無縫銜接 動畫結束瞬間定位
* 2.點需要隨着輪播的滾動改變對應的點 改變當前樣式 當前圖片的索引
* 3.手指滑動的時候讓輪播圖滑動 touch事件 記錄座標軸的改變 改變輪播圖的定位(位移css3)
* 4.當滑動的距離不超過一定的距離的時候 需要吸附回去 過渡的形式去做
* 5.當滑動超過了一定的距離 需要 跳到 下一張或者上一張 (滑動的方向) 一定的距離(屏幕的三分之一)
* */
var imageCount = 5; //頁面中用來輪播的圖片有5張不同的
//輪播圖大盒子
var banner = document.querySelector('.banner');
//圖片的寬度
var width = banner.offsetWidth;
//圖片盒子
var imageBox = banner.querySelector('ul:first-child');
//點盒子
var pointBox = banner.querySelector('ul:last-child');
//所有的點
var points = pointBox.querySelectorAll('li');
//公用方法
//加過渡
var addTransition = function(){
imageBox.style.transition = "all 0.3s";
imageBox.style.webkitTransition = "all 0.3s";/*做兼容*/
};
//清除過渡
var removeTransition = function(){
imageBox.style.transition = "none";
imageBox.style.webkitTransition = "none";
}
//定位
var setTranslateX = function(translateX){
imageBox.style.transform = "translateX("+translateX+"px)";
imageBox.style.webkitTransform = "translateX("+translateX+"px)";
}
//功能實現
//自動輪播 定時器 無縫銜接 動畫結束瞬間定位
var index = 1;
var timer = setInterval(function(){
index++ ; //自動輪播到下一張
//改變定位 動畫的形式去改變 transition transform translate
addTransition(); //加過渡動畫
setTranslateX(-index * width); //定位
},3000);
//等過渡結束之後來做無縫銜接
S.transitionEnd(imageBox, function(){
//處理事件結束後的業務邏輯
if(index > imageCount ){
index = 1;
}else if(index <= 0){
index = imageCount;
}
removeTransition(); //清除過渡
setTranslateX(-index * width); //定位
setPoint(); //設置底部顯示當前圖片對應的圓角
});
//改變當前樣式 當前圖片的索引
var setPoint = function(){
//清除上一次的now
for(var i = 0 ; i < points.length ; i++){
points[i].className = " ";
}
//給圖片對應的點加上樣式
points[index-1].className = "now";
}
/*
手指滑動的時候讓輪播圖滑動 touch事件 記錄座標軸的改變 改變輪播圖的定位(位移css3)
當滑動的距離不超過一定的距離的時候 需要吸附回去 過渡的形式去做
當滑動超過了一定的距離 需要 跳到 下一張或者上一張 (滑動的方向) 一定的距離(屏幕的三分之一)
*/
//touch事件
var startX = 0; //記錄起始 剛剛觸摸的點的位置 x的座標
var moveX = 0; //滑動的時候x的位置
var distanceX = 0; //滑動的距離
var isMove = false; //是否滑動過
imageBox.addEventListener('touchstart', function(e){
clearInterval(timer); //清除定時器
startX = e.touches[0].clientX; //記錄起始X
});
imageBox.addEventListener('touchmove',function(e){
moveX = e.touches[0].clientX; //滑動時候的X
distanceX = moveX - startX; //計算移動的距離
//計算當前定位 -index*width+distanceX
removeTransition(); //清除過渡
setTranslateX(-index * width + distanceX); //實時的定位
isMove = true; //證明滑動過
});
//在模擬器上模擬的滑動會有問題 丟失的情況 最後在模擬器的時候用window
imageBox.addEventListener('touchend', function(e){
// 滑動超過 1/3 即爲滑動有效,否則即爲無效,則吸附回去
if(isMove && Math.abs(distanceX) > width/3){
//5.當滑動超過了一定的距離 需要 跳到 下一張或者上一張 (滑動的方向)*/
if(distanceX > 0){ //上一張
index --;
}
else{ //下一張
index ++;
}
}
addTransition(); //加過渡動畫
setTranslateX(-index * width); //定位
if(index > imageCount ){
index = 1;
}else if(index <= 0){
index = imageCount;
}
setPoint();
//重置參數
startX = 0;
moveX = 0;
distanceX = 0;
isMove = false;
//加定時器
clearInterval(timer); //嚴謹 再清除一次定時器
timer= setInterval(function(){
index++ ; //自動輪播到下一張
addTransition(); //加過渡動畫
setTranslateX(-index * width); //定位
},3000);
});
};
4.核心代碼解釋
// 第一步
// 首尾兩張圖片是爲了滑動時的過渡,當JS監聽到此時滑動到是最後一張或者第一張的時候,
// 會分別自動地切換到倒數第二張(肉眼看到的最後一張)或者第二張圖片(肉眼看到的第一張)
<li><a href="#"><img src="images/5.jpg"></a></li>
<li><a href="#"><img src="images/1.jpg"></a></li>
<li><a href="#"><img src="images/2.jpg"></a></li>
<li><a href="#"><img src="images/3.jpg"></a></li>
<li><a href="#"><img src="images/4.jpg"></a></li>
<li><a href="#"><img src="images/5.jpg"></a></li>
<li><a href="#"><img src="images/1.jpg"></a></li>
// 第二步
// 上面說到的監聽會在transition結束後進行,
// 例如,要展示的圖片共5張,此時滑到了第七張(也就是最後一張圖片,同時也是我們肉眼看到的第一張圖片),
// 監聽到這種情況發生後,就會將位置移動到第二張(還是我們肉眼看到的第一張),但是這次移動是沒有過渡效果,速度很快,
// 所以肉眼看不出來圖片被我們替換了(因爲是同一張圖片,並且速度快,肉眼看不出位置已經被替換了)
// 同理,左滑滑到了第一張圖片也是這樣的處理邏輯。
S.transitionEnd(imageBox, function(){
//處理事件結束後的業務邏輯
if(index > imageCount ){
index = 1;
}else if(index <= 0){
index = imageCount;
}
removeTransition(); //清除過渡
setTranslateX(-index * width); //定位
setPoint(); //設置底部顯示當前圖片對應的圓角
});
// 第三步
//監聽的核心的給dom添加監聽事件'transitionEnd'。
S.transitionEnd = function(dom,callback){
//1.給誰加事件
//2.事件觸發後處理什麼業務
if(!dom || typeof dom != 'object'){
//沒dom的時候或者不是一個對象的時候 程序停止
return false;
}
dom.addEventListener('transitionEnd', function(){
callback && callback();
});
dom.addEventListener('webkitTransitionEnd', function(){
callback && callback();
});
}
// 第四步
// 用JS添加CSS樣式,添加過渡效果
var addTransition = function(){
imageBox.style.transition = "all 0.3s";
imageBox.style.webkitTransition = "all 0.3s";/*做兼容*/
};
// 第五步
// 動態去改變輪播的位置
var setTranslateX = function(translateX){
imageBox.style.transform = "translateX("+translateX+"px)";
imageBox.style.webkitTransform = "translateX("+translateX+"px)";
}
// 第六步
// 手指觸摸屏幕的時候('touchstart'),記得清楚定時器
// 手指離開屏幕的時候('touchend'),記得添加回定時器
var removeTransition = function(){
imageBox.style.transition = "none";
imageBox.style.webkitTransition = "none";
}
5.效果圖如下