1. 程式人生 > >zepto框架以及原生方法實現無縫輪播圖

zepto框架以及原生方法實現無縫輪播圖

注 :zepto實現在pc端模擬有一定的bug,把裡面的start=false註釋掉即可

Zepto實現。

HTML程式碼:

<div class="homePageBanner">
						<ul>
							<li><a href="#"><img src="images/banner4.jpg" alt=""></a></li>
							<li><a href="#"><img src="images/banner1.jpg" alt="">
</a></li> <li><a href="#"><img src="images/banner2.jpg" alt=""></a></li> <li><a href="#"><img src="images/banner3.jpg" alt=""></a></li> <li><a href="#"><img src="images/banner4.jpg" alt=""></a>
</li> <li><a href="#"><img src="images/banner1.jpg" alt=""></a></li> </ul> <ul> <li class="active"></li> <li></li> <li></li> <li></li> </ul> </div>

js程式碼:(需要引入zepto.js 請到github下載)

$(function(){
	var wd = $('.homePageBanner').width();
    var start = true;
    var timer;
	var $imgList=$('.homePageBanner ul').eq(0);
	var $circle=$('.homePageBanner ul').eq(1);
    $imgList.on('swipeLeft',moveLeft);
    timer=setInterval(moveLeft,2000);
    function moveLeft (){
        // console.log(1);
        if (start) {
            clearInterval(timer);
            start=false;
            var currLeft = parseInt($imgList.position().left);
			$imgList.animate({
                left: currLeft - wd

            }, 500, function () {
                // console.log($imgList.position().left,-5*wd);
               if (parseInt($imgList.position().left)==-5*wd) {
				$imgList.css({
                        left:-wd
                    });
               }
              setIndex();
            })
            timer=setInterval(moveLeft,2000);
        }
    }
    $imgList.on('swipeRight', function () {
        // console.log(2);
        if(start){
            clearInterval(timer);
            start=false;
            var currLeft = parseInt($imgList.position().left);
            $imgList.animate({
                left: currLeft + wd
            }, 500, function () {
               if (parseInt($imgList.position().left)==0) {
				$imgList.css({
                        left:-4*wd
                    });
               }
               setIndex();
            })
            timer=setInterval(moveLeft,2000);
        }
    })
    function setIndex(){
         var i = ($imgList.position().left/-wd)-1;
		 $circle.find('li').eq(i).addClass('active').siblings().removeClass('active');
    }
    $imgList.on('transitionend',function () { 
        start=true;
    })
})

樣式部分:(寬度為容器的6倍)

.homePageBanner{
        width: 10rem;
        overflow: hidden;
        //防止影響下方元素
        position: relative;
        margin: 0 auto;
        height: 499/75rem;
        ul:first-child{
            position: absolute;
            width: 600%;
            overflow: hidden;
            left: -100%;
            top: 0;
            height: 499/75rem;
            li{
                width: 16.6667%;
                float: left;
                
                img{
                width: 100%;
                height: 499/75rem;
                display: block;
                }
            }
        }
        
        // 小圓點 
        ul:last-child{
             width: 150/75rem;
            height: 20/75rem;
            position: absolute;
            right: 10/75rem;
            bottom: 20/75rem;
            
            li{
            width: 14.5/75rem;
            height: 14.5/75rem;
            margin-left: 10/75rem;
            border-radius: 50%;
            border: 1px solid #0099cc;
            float: left;
            
            &:first-child{
                margin-left: 0;
                }
            }
            .active{
                background: #0099cc;
                }
            }
    }

原生js實現(可以監控到使用者的滑動停留行為)

js程式碼:

var scrollPic = function(){
	// 獲取到外層容器homePageBanner
	var banner = document.getElementsByClassName("homePageBanner")[0];
	// 獲取外層容器的寬度,因為每張圖片的寬度與容器寬度相同所以這裡等同於獲取圖片的寬度
	var width = banner.offsetWidth;

	//儲存圖片的容器ul
	var imgBox = banner.getElementsByTagName("ul")[0];

	//儲存輪播下方小圓點的容器ul
	var pointBox = banner.getElementsByTagName("ul")[1];

	//獲取到所有的小圓點
	var pointList = pointBox.getElementsByTagName("li");
	//定義變數index 用來記錄下標 
	var  index = 1;
	// 宣告一個變數timer用做定時器名稱
	var timer ;
	// 宣告一個變數startX用來記錄手指觸控時,手指距離螢幕左邊的距離
	var startX = 0;
	// 我手指開始觸控時到移動手指這個過程中移動了多少距離
	var moveX = 0;
	// 記錄手指移動時,手指距離螢幕左邊的距離
	var endX = 0;

	//定義一個過渡函式使得圖片在輪播時有過渡效果
	var addTransition = function(){
		imgBox.style.transition = "all .3s ease 0s";
		imgBox.style.webkitTransition = "all .3s ease 0s";
	} 

	//去掉過渡函式
	var removeTransition = function(){
		imgBox.style.transition = "none";
		imgBox.style.webkitTransition = "none";
	} 

	//定義一個移動函式使用transform方法來移動,傳入形參t用做需要偏移的位置值
	var setTransform = function(t){
		imgBox.style.transform = "translate("+t+"px)";
		imgBox.style.webkitTransform = "translate("+t+"px)";
	} 

	//定義小圓點函式動態新增active類,原理:先清空所有樣式再給指定的小圓點新增active類,傳入的形參n用做小標,因為複製了首尾兩張圖片所有這裡n-1
	var setpoint = function(n){
		for (var i = 0; i < pointList.length; i++) {
			pointList[i].className = '';
		};
		// 如果到了第六張圖片讓他變成第二張。注:複製了首尾兩張圖片所以第一張要顯示的圖片是下標1
		if (n >= 5) {
			n = 1;
		}else if(n <= 0){
			n = 4;
		}
		pointList[n-1].className ='active';
	}

	

	//定時函式,每次讓下標++,呼叫過渡函式,呼叫偏移函式,傳入的值為-index*width因為是向左偏移所以這裡index是負值,width是圖片的寬度,每次移動一個-index*width的距離
	timer = setInterval(function(){
		index++;
		addTransition();
		setTransform(-index*width);
		// 把當前下標闖入設定小圓點類的函式,使得小圓點根據index值動態新增active類
		 setpoint(index);

	}, 3000)

	//監聽動畫結束後的函式

	imgBox.addEventListener('transitionEnd', function(){
		// 做出判斷,如果到了最後一張克隆的a圖片就讓他的下標成為真正的下標為1的a圖片
		if (index >= 5) {
			index = 1;
		// 做出判斷,如果到了第一張下標為0的克隆的d圖片就讓他的下標成為真正的下標為4的d圖片
		}else if(index <= 0){
			index = 4;
		}
		// 移除動畫效果,這一步使得無縫輪播視覺效果看不出來
		removeTransition();
		// 呼叫偏移函式,傳入的值為-index*width因為是向左偏移所以這裡index是負值,width是圖片的寬度,每次移動一個-index*width的距離
		setTransform(-index*width);

	},false)
	// 以上相容寫法
	imgBox.addEventListener('webkitTransitionEnd', function(){
		if (index >= 5) {
			index = 1;
		}else if(index <= 0){
			index = 4;
		}

		removeTransition();
		setTransform(-index*width);

	},false)



//觸控事件開始,當手指開始觸控時的函式
	imgBox.addEventListener('touchstart', function(e){
		//console.log('strat');
		// 記錄開始的位置,獲取到手指觸控時手指距離螢幕左邊的距離
		startX = e.touches[0].clientX;
	})

	//觸控滑動事件開始,手指移動時的事件
	imgBox.addEventListener('touchmove', function(e){
		//清除定時器
		clearInterval(timer);
		// 清除預設的滾動事件
		e.preventDefault();
		// 記錄手指移動時,手指距離螢幕左邊的距離
		endX = e.touches[0].clientX;
		//記錄手指在觸控時並且移動的過程中產生的這個距離startX - endX,用剛觸碰時獲取到的距離減去我觸控移動時手指距離螢幕左邊距離,
		// 得到我手指開始觸控時到移動手指這個過程中移動了多少距離
		moveX = startX - endX;
		// 移除動畫函式使得移動過程中圖片跟著手指移動
		removeTransition();
		// 設定移動過程中圖片跟著手指移動的距離
		setTransform(-index * width - moveX)
	})

	//觸控滑動事件結束
	imgBox.addEventListener('touchend', function(e){
		//如果移動的距離大於三分之一時向左滑,否則向右滑
		if( Math.abs(moveX) > (1/3*width) && endX != 0){
			// 向左
			if (moveX > 0) {
				index++;
			}else{
				index--;
			}
			// 改變位置
			setTransform(-index*width);
			setpoint(index);

		}

		// 手指鬆開時圖片回到原來的位置
		addTransition();
		setTransform(-index*width);

		startX = 0;
		endX = 0;
		// 清空上一次定時器
		clearInterval(timer);

		//重新呼叫定時器
		timer = setInterval(function(){
			index++;
			addTransition();
			setTransform(-index*width);
			setpoint(index);
		}, 3000)

	})

}

//banner 呼叫方法
scrollPic();

注:HTML佈局保持一致,css部分採用的是transform:translateX的方式,把定位屬性改為translate即可,初始值是-16.66667%負一張圖片的寬度,因為在最前面放的是克隆的第四張圖片。
本部落格內容均為原創,轉載請加以說明。