jQuery實現輪播效果

zihanzy.com發表於2020-10-01

個人部落格上線歡迎來訪 http://www.zihanzy.com

HTML結構

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            padding:0;
            margin:0;
            text-decoration: none;
        }
        body{
            /* padding:20px; */
        }
        #container{
            width:600px;
            height: 400px;
            overflow: hidden; /*圖片超出部分隱藏*/
            position: relative;
            margin:0 auto;
        }
        #list{
            width:3000px; /* 5張圖片的寬度 5*600 */
            height: 400px;
            position: absolute;
            z-index: 1;
        }
        #list img{
            float:left;
            width: 600px;
            height: 400px;
        }
        #dot{
            position:absolute;
            height: 10px;
            width: 100px;
            z-index: 2;
            bottom:20px;
            left:250px;
        }
        #dot .on{
            background:orangered
        }
        #dot span{
            cursor:pointer;
            float:left;
            width: 15px;
            height: 15px;
            border-radius: 50%;
            margin:0 auto;
            background-color: rgba(0,0,0,.7);
        }
        .arrow{
            cursor:pointer;
            display: none;
            line-height: 39px;
            text-align: center;
            font-size: 36px;
            font-weight: bold;
            width: 40px;
            height: 40px;
            position: absolute;
            z-index: 2;
            top:180px;
            background-color: rgba(0,0,0,0.3);
            color:#fff;

        }
        .arrow:hover{
            background-color: rgba(0,0,0,.7);
        }
        /* 滑鼠移動到整個div區域時 */
        #container:hover .arrow{
            display: block;
        }
        #prev{
            left:20px;
        }
        #next{
            right: 20px;
        }
    </style>
</head>
<body>
    <div id="container">
        <div id="list">
            <img src="./images/1.jpg" alt="">
            <img src="./images/2.jpg" alt="">
            <img src="./images/3.jpg" alt="">
            <img src="./images/4.jpg" alt="">
            <img src="./images/5.jpg" alt="">
        </div>
        <div id="dot">
            <span index="1" class="on"></span>
            <span index="2" class=""></span>
            <span index="3" class=""></span>
            <span index="4" class=""></span>
            <span index="5" class=""></span>
        </div>
        <a href="javascript:;" id="prev" class="arrow"><</a>
        <a href="javascript:;" id="next" class="arrow">></a>
    </div>

需求分析

  1. 點選向右(左)的圖示 平滑到下一頁
  2. 無限迴圈切換,第一頁的上一頁為最後頁,最後一頁的下頁是第一頁
  3. 每隔3s自動滑動到下一頁
  4. 當滑鼠進入圖片區域時,自動切換停止,當滑鼠離開後自動切換開始
  5. 切換頁面時,下面的圓點同步更新
  6. 點選圓點圖示切換到對應的頁

點選向右(左)的圖示 平滑到下一頁
要實現點選箭頭向做向右移動我們需要

  1. 設定每次偏移量 PAGE_WIDTH
  2. 設定翻頁持續的時間 TIME
  3. 設定單元移動的間隔時間 ITEM_TIME
  4. 求出單元移動的偏移量 itemOffset = offset(偏移量)/(TIME/ITEM_TIME)
  5. 計算出要移動到的目標位置
  6. 迴圈定時器進行平滑移動

程式碼實現

	$(function(){        
	var $container = $('#container')
	var $list = $('#list')
	var $dot = ('#dot span')
	var $prev = $('#prev')
	var $next = $('#next')
	var PAGE_WIDTH = 600 //偏移常量
	var TIME = 400 //翻頁持續時間
	var ITEM_TIME = 20 //單元間隔時間

	//1.點選向右(左)的圖示 平滑到下一頁
	$next.click(function(){
			//平滑下一頁
			nextPage(true)
	})
	$prev.click(function(){
			//平滑上一頁
			nextPage(false)
	})

	/**
	 平滑翻頁
		true:下一頁
		false:上一頁
	*/
	function nextPage(next){
		 var offset = 0
		 //計算offset 偏移量
		 var offset = next ? -PAGE_WIDTH : PAGE_WIDTH
		 //計算單元移動的偏移量 itemoffset
		 var itemOffset = offset/(TIME/ITEM_TIME)
		 //獲取當前currentLeft
		 var currentLeft = $list.position().left 
		 //計算出目標處的left值
		 var targetLeft = currentLeft + offset
		 //迴圈定時器
		 var timer  = setInterval(() => {
				 //計算最新的current
				 currentLeft += itemOffset
				 //判斷是否到底目標位置
				 if(currentLeft ===targetLeft){
						 //清除定時器
						 clearInterval(timer) 
				 }
				 $list.css('left',currentLeft)

		 }, ITEM_TIME);
	}
})

實現切換無縫滾動
為了實現無縫滾動的效果我們要在第一張圖片前面新增最後一張圖片,在最後一張圖片後面新增第一張圖片
當切換到克隆的(第一張/最後一張)圖片時,跳轉到真正的圖片

修改css

 #list{
	width:4200px; /* 7張圖片的寬度 7*600 */
	height: 400px;
	position: absolute;
	z-index: 1;
}

修改html結構

<div id="list" style="left:-600px">
	<img src="./images/5.jpg" alt="">
	<img src="./images/1.jpg" alt="">
	<img src="./images/2.jpg" alt="">
	<img src="./images/3.jpg" alt="">
	<img src="./images/4.jpg" alt="">
	<img src="./images/5.jpg" alt="">
	<img src="./images/1.jpg" alt="">
</div>

js部分

...
var ITEM_TIME = 20 //單元間隔時間
 //獲取圖片數量
var imgCount = $dot.length;
...
//定時器迴圈滾動
var timer = setInterval(() => {
	currentLeft+=itemOffset
	if(currentLeft === targetLeft){
			clearInterval(timer)
			//在滾動到最後一張圖片的瞬間,跳轉到第一張克隆的最後一張圖片
			if(currentLeft === -(imgCount+1) * PAGE_WIDTH){
					currentLeft = -PAGE_WIDTH
			}else if(currentLeft === 0){
					//在滾動到第一張圖片的瞬間(克隆的最後一張圖片),跳轉到最後一張克隆的第一張圖片
					currentLeft = - PAGE_WIDTH * imgCount
			}
	}

	$list.css('left',currentLeft)

},ITEM_TIME);

迴圈滾動實現

...
 $next.click(function(){
		//  下一頁
		nextPage(true)
 })
//每隔3s自動切換
var timer = setInterval(() => {
		 nextPage(true)
},3000)

//當滑鼠進入圖片區域時,自動停止,當滑鼠離開,有開始自動切換
$container.hover(function(){
		//清除定時器
		clearInterval(timer)

},function(){
		//滑鼠離開 開啟定時器
		timer = setInterval(() => {
				nextPage(true)
		},3000)
})
...

使圓點高亮顯示

...
 //獲取圖片數量
var imgCount = $dot.length
 //當前滾動圖片的下標
var index = 0
...
...
$list.css('left',currentLeft)

		},ITEM_TIME);
		//更新圓點
		updatePoints(flag)
 }
 function updatePoints(flag){

		 //計算出目標圓點的下標targetIndex
		 var targetIndex = 0
		 //下一頁使目標圓點下標+1
		 if(flag){
				targetIndex = index + 1 //[0 ,imgCount+1]
				if(targetIndex === imgCount){
						targetIndex = 0 
				}
		 }else{
				 targetIndex = index -1
				 if(targetIndex === -1){
						 targetIndex = imgCount-1
				 }
		 }
		//將當前index的<span>的class移除
		$dot.eq(index).removeClass('on')
		//給目標圓點新增class='on'
		$dot.eq(targetIndex).addClass('on')
		//將index更新為targetIndex
		index = targetIndex

 }
 ...

點選圓點實現圖片滾動

...
//將index更新為targetIndex
	index = targetIndex
}
//點選圓點圖片切換對應的圖片
 $dot.click(function(){
		 //計算目標頁的下標
		 var targetIndex = $(this).index()
		 if(targetIndex!=index){
				 //點選的不是當前頁的圓點 才進行翻頁
				 nextPage(targetIndex)
		 }
 })

這裡我們將當前圓點的下標傳入nextPage我們要對nextPage進行一部分修改,因為傳進來的引數不止是boolean型別了,還有數字型別

 /**
 * true:下一頁
 * false:上一頁
 * 數值:指定下標頁
 */
 function nextPage(flag){
		//設定偏移量
		var offset = 0
		if(typeof flag==='boolean'){
				offset = flag ? -PAGE_WIDTH : PAGE_WIDTH
		}else{
				offset = -(flag-index) * PAGE_WIDTH
		}
		...

更新圓點方法updatePoints也有修改

...
function updatePoints(flag){        
 //計算出目標圓點的下標targetIndex
 var targetIndex = 0
 if(typeof flag ==='boolean'){
		//下一頁使目標圓點下標+1
		if(flag){
				targetIndex = index + 1 //[0 ,imgCount+1]
				if(targetIndex === imgCount){
						targetIndex = 0 
				}
		}else{
				targetIndex = index -1
				if(targetIndex === -1){
						targetIndex = imgCount-1
				}
		}
 }else{
	targetIndex = flag
 }
...

到此基本的輪播圖實現完成,但是這裡還有一個bug,當快速點選切換圖片時會出現“空白的情況”
出現這種問題的原因是快速點選時觸發了多個定時器進行移動

解決辦法:只時一個定時器生效

 //當前滾動圖片的下標
 var index = 0
 var moving = false  //翻頁狀態
 
 ...
 function nextPage(flag){
	if(moving)return  //如果正在翻頁 直接結束
	moving = true //呼叫翻頁時moving為true
	//設定偏移量
	var offset = 0
	if(typeof flag==='boolean'){
			offset = flag ? -PAGE_WIDTH : PAGE_WIDTH
	}else{
		offset = -(flag-index) * PAGE_WIDTH
}
...
//定時器迴圈滾動
var timer = setInterval(() => {
	currentLeft+=itemOffset
	if(currentLeft === targetLeft){
		clearInterval(timer)
		//標識翻頁停止
		moving = false
 ...
 

個人部落格上線歡迎來訪 http://www.zihanzy.com

相關文章