JS+JQuery實(shí)現(xiàn)無縫連接輪播圖
我之前寫過一個(gè)簡易版的自動(dòng)+手動(dòng)輪播圖:簡易輪播圖
但是這個(gè)輪播圖在切換的時(shí)候是沒有實(shí)現(xiàn)無縫滾動(dòng)的,每張圖片都是單張切換的,而不是滑動(dòng)。現(xiàn)在用JQuery實(shí)現(xiàn)無縫連接的輪播圖。
無縫連接的輪播圖的原理如下:

代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>無縫輪播圖</title>
</head>
<style type="text/css">
* {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
}
#container {
position: relative;
/*輪播圖容器的寬高*/
width: 500px;
height: 260px;
margin: 20px auto;
overflow: hidden;
/*溢出隱藏:只顯示一張圖片*/
}
#container .wrapper {
position: absolute;
top: 0;
left: 0;
/*每張圖片的寬度和輪播圖容器的寬度相等,
整個(gè)圖片層長度:500*5=2500,由于克隆了一張,多加一張寬度*/
width: 3000px;
height: 100%;
}
#container .wrapper li {
width: 500px;
height: 100%;
float: left;
}
#container .wrapper li img {
width: 100%;
height: 100%;
vertical-align: middle;
/*去掉未浮動(dòng)時(shí)圖片間的上下空隙*/
}
#container .btnLeft,
#container .btnRight {
display: none;
z-index: 999;
width: 30px;
height: 30px;
position: absolute;
top: 50%;
margin-top: -15px;
background-color: #9E9E9E;
border-radius: 20%;
opacity: 60%;
font-size: 20px;
color: #673ab7;
text-align: center;
line-height: 30px;
}
#container .btnLeft {
left: 0;
}
#container .btnRight {
right: 0;
}
#container .btnLeft:hover,
#container .btnRight:hover {
opacity: 70%;
cursor: pointer;
}
/* 鼠標(biāo)滑過圖片的時(shí)候顯示按鈕 */
#container:hover .btnLeft,
#container:hover .btnRight {
display: block;
}
/*圓點(diǎn)層*/
#container .dots {
background: rgba(0, 0, 0, .3);
position: absolute;
left: 50%;
bottom: 10px;
transform: translateX(-50%);
z-index: 999;
padding: 4px;
border-radius: 24px;
}
#container .dots li {
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #9e9e9e;
float: left;
/*可以使用行塊盒*/
/*display: inline-block;*/
margin: 0 5px;
cursor: pointer;
}
#container .dots li.active {
background-color: #c74b42;
}
.clearfix::after {
content: "";
display: block;
clear: both;
}
</style>
<body>
<!-- 實(shí)現(xiàn)輪播圖的容器 -->
<div id="container">
<!-- 存放全部圖片的容器 -->
<div class="wrapper">
<!-- LI: 每張圖片 -->
<li><img src="0.jpg"></li>
<li><img src="1.jpg"></li>
<li><img src="2.jpg"></li>
<li><img src="3.jpg"></li>
<li><img src="4.jpg"></li>
<!-- 克隆到末尾 -->
<li><img src="0.jpg"></li>
</div>
<div class="btnLeft"><</div>
<div class="btnRight">></div>
<!-- 分頁器:圓點(diǎn) -->
<div class="dots">
<ul class="clearfix">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
<script src="jquery-1.11.3.min.js"></script>
<!-- <script src="index.js"></script> -->
<script type="text/javascript">
let $container = $('#container'),
$wrapper = $container.children('.wrapper'),
$btnLeft = $container.find('.btnLeft'),
$btnRight = $container.find('.btnRight'),
$dots = $container.find('.dots'),
$dotList = $dots.find('li');
let autoTimer = null,
interval = 2000,
imgIndex = 0; //當(dāng)前輪播的圖片索引,默認(rèn)第一張
// 自動(dòng)輪播
function autoPlay() {
// 讓wrapper向左移動(dòng)
imgIndex++;
/* if(imgIndex === 4) imgIndex = 0; 這樣寫會(huì)導(dǎo)致圖片會(huì)一下變到第一張,不是無縫滾動(dòng)
無縫滾動(dòng):
1. 把第一張克隆一份放到末尾,wrapper中會(huì)比真實(shí)的圖片層多一張
2. 依然一張張往后滾動(dòng),滾動(dòng)到第5張的時(shí)候,繼續(xù)向后走(imgIndex=6),看到了克隆的第一張,再要向后走的時(shí)候,
讓其“立即”跳轉(zhuǎn)到真實(shí)的第一張(肉眼看不出跳轉(zhuǎn)),然后運(yùn)動(dòng)到第二張......
*/
if (imgIndex > 5) {
// 上次顯示的是克隆的那張,忽略真實(shí)的第一張,讓其立即跳轉(zhuǎn)到第二張
$wrapper.css('left', 0);
imgIndex = 1;
}
// 勻速向左移動(dòng)
// 無動(dòng)畫版:$wrapper.css('transform', 'translate(' + (-imgIndex * 500) + 'px)');
// 動(dòng)畫版:
$wrapper.stop().animate({
left: -imgIndex * 500 //JQ自動(dòng)補(bǔ)'px'
}, 300);
showDots();
}
autoTimer = setInterval(autoPlay, interval);
// 圓點(diǎn)對(duì)焦
function showDots() {
// 由于不能修改imgIndex的值,所以定義一個(gè)臨時(shí)變量
let temp = imgIndex;
temp === 5 ? temp = 0 : null;
$dotList.each((index, item) => {
let $item = $(item);
if (index === temp) {
$item.addClass('active');
return;
}
$item.removeClass('active');
});
}
// 鼠標(biāo)進(jìn)入/離開輪播區(qū)域時(shí)停止/開啟自動(dòng)輪播
$container.on('mouseenter', () => {
clearInterval(autoTimer);
});
$container.on('mouseleave', () => {
autoTimer = setInterval(autoPlay, interval);
});
// 點(diǎn)擊圓點(diǎn)
$dotList.click(function () {
let index = $(this).index();
imgIndex = index;
$wrapper.stop().animate({
left: -imgIndex * 500 //JQ自動(dòng)補(bǔ)'px'
}, 300);
showDots();
});
// 左鍵點(diǎn)擊
$btnLeft.click(function () {
imgIndex--;
if (imgIndex < 0) {
// 上次顯示的是真實(shí)的第一張,忽略克隆的倒數(shù)第一張,讓其立即跳轉(zhuǎn)倒數(shù)第二張
$wrapper.css('left', -2500);
imgIndex = 4;
}
$wrapper.stop().animate({
left: -imgIndex * 500 //JQ自動(dòng)補(bǔ)'px'
}, 300);
showDots();
});
// 右鍵點(diǎn)擊:相當(dāng)于自動(dòng)輪播
$btnRight.click(function() {
autoPlay();
});
</script>
</body>
</html>
這段代碼用單例模式優(yōu)化一下:
html部分:test.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>無縫輪播圖</title>
</head>
<style type="text/css">
* {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
}
#container {
position: relative;
/*輪播圖容器的寬高*/
width: 500px;
height: 260px;
margin: 20px auto;
overflow: hidden;
/*溢出隱藏:只顯示一張圖片*/
}
#container .wrapper {
position: absolute;
top: 0;
left: 0;
/*每張圖片的寬度和輪播圖容器的寬度相等,
整個(gè)圖片層長度:500*5=2500,由于克隆了一張,多加一張寬度*/
width: 3000px;
height: 100%;
}
#container .wrapper li {
width: 500px;
height: 100%;
float: left;
}
#container .wrapper li img {
width: 100%;
height: 100%;
vertical-align: middle;
/*去掉未浮動(dòng)時(shí)圖片間的上下空隙*/
}
#container .btnLeft,
#container .btnRight {
display: none;
z-index: 999;
width: 30px;
height: 30px;
position: absolute;
top: 50%;
margin-top: -15px;
background-color: #9E9E9E;
border-radius: 20%;
opacity: 60%;
font-size: 20px;
color: #673ab7;
text-align: center;
line-height: 30px;
}
#container .btnLeft {
left: 0;
}
#container .btnRight {
right: 0;
}
#container .btnLeft:hover,
#container .btnRight:hover {
opacity: 70%;
cursor: pointer;
}
/* 鼠標(biāo)滑過圖片的時(shí)候顯示按鈕 */
#container:hover .btnLeft,
#container:hover .btnRight {
display: block;
}
/*圓點(diǎn)層*/
#container .dots {
background: rgba(0, 0, 0, .3);
position: absolute;
left: 50%;
bottom: 10px;
transform: translateX(-50%);
z-index: 999;
padding: 4px;
border-radius: 24px;
}
#container .dots li {
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #9e9e9e;
float: left;
/*可以使用行塊盒*/
/*display: inline-block;*/
margin: 0 5px;
cursor: pointer;
}
#container .dots li.active {
background-color: #c74b42;
}
.clearfix::after {
content: "";
display: block;
clear: both;
}
</style>
<body>
<!-- 實(shí)現(xiàn)輪播圖的容器 -->
<div id="container">
<!-- 存放全部圖片的容器 -->
<div class="wrapper">
<!-- LI: 每張圖片 -->
<li><img src="0.jpg"></li>
<li><img src="1.jpg"></li>
<li><img src="2.jpg"></li>
<li><img src="3.jpg"></li>
<li><img src="4.jpg"></li>
<!-- 克隆到末尾 -->
<li><img src="0.jpg"></li>
</div>
<div class="btnLeft"><</div>
<div class="btnRight">></div>
<!-- 分頁器:圓點(diǎn) -->
<div class="dots">
<ul class="clearfix">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
<script src="jquery-1.11.3.min.js"></script>
<script src="index.js"></script>
</body>
</html>
JS部分:index.js
function debounce(func, wait, immediate) {
let timer = null,
result = null;
return function anonymous(...args) {
let context = this,
now = immediate && !timer;
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
!immediate ? (result = func.call(context, ...args)) : null;
}, wait);
now ? (result = func.call(context, ...args)) : null;
return result;
};
}
let bannerModule = (function () {
let $container = $("#container"),
$wrapper = $container.children(".wrapper"),
$btnLeft = $container.find(".btnLeft"),
$btnRight = $container.find(".btnRight"),
$dots = $container.find(".dots"),
$dotList = $dots.find("li");
let autoTimer = null,
interval = 2000,
imgIndex = 0; //當(dāng)前輪播的圖片索引,默認(rèn)第一張
// 自動(dòng)輪播
function autoPlay() {
// 讓wrapper向左移動(dòng)
imgIndex++;
/* if(imgIndex === 4) imgIndex = 0; 這樣寫會(huì)導(dǎo)致圖片會(huì)一下變到第一張,不是無縫滾動(dòng)
無縫滾動(dòng):
1. 把第一張克隆一份放到末尾,wrapper中會(huì)比真實(shí)的圖片層多一張
2. 依然一張張往后滾動(dòng),滾動(dòng)到第5張的時(shí)候,繼續(xù)向后走(imgIndex=6),看到了克隆的第一張,再要向后走的時(shí)候,
讓其“立即”跳轉(zhuǎn)到真實(shí)的第一張(肉眼看不出跳轉(zhuǎn)),然后運(yùn)動(dòng)到第二張......
*/
if (imgIndex > 5) {
// 上次顯示的是克隆的那張,忽略真實(shí)的第一張,讓其立即跳轉(zhuǎn)到第二張
$wrapper.css("left", 0);
imgIndex = 1;
}
// 勻速向左移動(dòng)
// 無動(dòng)畫版:$wrapper.css('transform', 'translate(' + (-imgIndex * 500) + 'px)');
// 動(dòng)畫版:
$wrapper.stop().animate({
left: -imgIndex * 500 //JQ自動(dòng)補(bǔ)'px'
}, 300);
showDots();
}
// 圓點(diǎn)對(duì)焦
function showDots() {
// 由于不能修改imgIndex的值,所以定義一個(gè)臨時(shí)變量
let temp = imgIndex;
temp === 5 ? (temp = 0) : null;
$dotList.each((index, item) => {
let $item = $(item);
if (index === temp) {
$item.addClass("active");
return;
}
$item.removeClass("active");
});
}
//點(diǎn)擊圓點(diǎn)
function clickDots() {
$dotList.click(debounce(function () {
let index = $(this).index();
imgIndex = index;
$wrapper.stop().animate({
left: -imgIndex * 500 //JQ自動(dòng)補(bǔ)'px'
}, 300);
showDots();
},300,true));
}
// 左右按鍵
function btnClick() {
$btnLeft.click(function () {
imgIndex--;
if (imgIndex < 0) {
// 上次顯示的是真實(shí)的第一張,忽略克隆的倒數(shù)第一張,讓其立即跳轉(zhuǎn)倒數(shù)第二張
$wrapper.css('left', -2500);
imgIndex = 4;
}
$wrapper.stop().animate({
left: -imgIndex * 500 //JQ自動(dòng)補(bǔ)'px'
}, 300);
showDots();
});
// 右鍵點(diǎn)擊:相當(dāng)于自動(dòng)輪播
$btnRight.click(debounce(autoPlay, 300, true));
}
return {
init: function () {
autoTimer = setInterval(autoPlay, interval);
// 鼠標(biāo)進(jìn)入/離開輪播區(qū)域時(shí)停止/開啟自動(dòng)輪播
$container.on("mouseenter", () => {
clearInterval(autoTimer);
});
$container.on("mouseleave", () => {
autoTimer = setInterval(autoPlay, interval);
});
clickDots();
btnClick();
},
};
})();
bannerModule.init();
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript數(shù)組合并的8種常見方法小結(jié)
項(xiàng)目過程中經(jīng)常會(huì)遇到 JS 數(shù)組合并的情況,時(shí)常為這個(gè)糾結(jié),這里整理一下,下面這篇文章主要給大家介紹了關(guān)于JavaScript數(shù)組合并的8種常見方法,需要的朋友可以參考下2022-11-11
JavaScript圖片旋轉(zhuǎn)效果實(shí)現(xiàn)方法詳解
這篇文章主要介紹了JavaScript圖片旋轉(zhuǎn)效果實(shí)現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
checkbox全選所涉及到的知識(shí)點(diǎn)介紹
checkbox全選涉及到的知識(shí)點(diǎn)比如IE里起作用,火狐不起作用,getElementById()與getElementsByName()的區(qū)別等等2013-12-12
JavaScript 實(shí)現(xiàn)普通數(shù)組數(shù)據(jù)轉(zhuǎn)化為樹形數(shù)據(jù)結(jié)構(gòu)的步驟說明
在 JavaScript 中,將普通數(shù)組數(shù)據(jù)轉(zhuǎn)化為樹形結(jié)構(gòu)的數(shù)據(jù)是一個(gè)常見的任務(wù),特別是在處理層級(jí)數(shù)據(jù)(例如分類、組織結(jié)構(gòu)等)時(shí),本文展示如何將一個(gè)扁平的數(shù)組轉(zhuǎn)化為樹形數(shù)據(jù)結(jié)構(gòu),感興趣的朋友一起看看吧2024-12-12
基于element?UI?input組件自行封裝“數(shù)字區(qū)間”輸入框組件的問題及解決
這篇文章主要介紹了基于element?UI?input組件自行封裝“數(shù)字區(qū)間”輸入框組件,實(shí)現(xiàn)代碼可以分為兩塊一塊為組件的封裝代碼,一塊為文中實(shí)現(xiàn)效果的演示代碼,對(duì)element?UI數(shù)字區(qū)間輸入組件相關(guān)知識(shí)感興趣的朋友一起看看吧2022-05-05
文件上傳,iframe跨域數(shù)據(jù)提交的實(shí)現(xiàn)
下面小編就為大家?guī)硪黄募蟼?iframe跨域數(shù)據(jù)提交的實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11
firefox下input type="file"的size是多大
firefox對(duì)type="file" 的input的width定義目前是不支持的,但是FF支持size屬性,可以給size設(shè)置一個(gè)值,來控制上傳框的大小2011-10-10

