無論用什么語言開發可視化界面,都有一個叫輪播圖的東西。我們現在有個需求,如圖:
slideshow1.PNG
左右切換按鈕默認為隱藏,當鼠標進入圖片時,左右切換按鈕時顯示的,當鼠標離開圖片時左右切換按鈕時隱藏的,當圖片滾動時,校園頂跟著一起滾動,當鼠標放到相應的小圓點,就切換到相應的照片。
那思路啥子呢?看圖說話
slideshow2.png
這圖就是輪播圖的思路
html代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>輪播圖</title>
<script src="utils.js"></script>
<script src="slideshow.js"></script>
<link rel="stylesheet" href="slideshow.css">
</head>
<body>
<div class="box">
<div class="imgList" id="imgList">
<img src="img/img1.jpg" alt="">
<img src="img/img2.jpg" alt="">
<img src="img/img3.jpg" alt="">
<img src="img/img4.jpg" alt="">
</div>
<div class="btn" id="btn">
<a class="leftBtn" href="javascript:"><</a>
<a class="rightBtn" href="javascript:">></a>
</div>
<div class="tab" id="tab">
<a href="javascript:"></a>
<a href="javascript:"></a>
<a href="javascript:"></a>
<a href="javascript:"></a>
</div>
</div>
</body>
</html>
css代碼
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
background: #fff;
}
.box {
width: 600px;
height: 350px;
margin: 100px auto;
position: relative;
overflow: hidden;
}
.imgList {
position: absolute;
}
.imgList img {
width: 600px;
height: 350px;
position: absolute;
right: 0;
}
.img1 {
left: 0;
}
.img2 {
left: 600px;
}
.img3 {
left: 1200px;
}
.img4 {
left: 1600px;
}
.btn {
position: relative;
left: 0;
right: 0;
}
.btn a {
position: absolute;
top: 150px;
display: inline-block;
padding: 15px 8px;
background: rgba(0, 0, 0, 0.5);
font-size: 20px;
color: white;
}
.leftBtn {
left: 0;
}
.rightBtn {
right: 0;
}
.tab {
position: absolute;
left: 40%;
bottom: 0;
}
.tab a {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin: 10px
}
.whiteTab {
background: #fff;
}
.redTab {
background: #000;
}
js代碼
window.onload = function () {
//獲得標簽對象
let imgList = $("imgList");
let btn = $("btn");
let tab = $("tab");
let leftBtn = $("leftBtn");
let rightBtn = $("rightBtn");
//獲得子元素
let imgListChildren = imgList.children;
let tabChildren = tab.children;
//用來記錄當前是第幾張圖片
let index = 0;
//用來記錄當前是第幾個小圓點
let tabIndex = 0;
//一張圖片的寬度
const IMG_WIDTH = 600;
//存儲定時器的返回值
let timer = null;
//當鼠標移入imgList時,btn顯示
imgList.onmousemove = function () {
btn.style.display = "block";
//鼠標進入時不自動播放,清除定時器
clear();
}
//當鼠標移出imgList時,btn隱藏
imgList.onmouseout = function () {
btn.style.display = "none";
//鼠標離開時,啟動定時器
startAuto();
}
//若不添加下面兩句,則會出席那bug,鼠標進入btn時會抖動
//當鼠標移到btn時,btn顯示
btn.onmouseenter = function () {
btn.style.display = "block";
//鼠標進入時不自動播放,清除定時器
clear();
}
//當鼠標移出btn時,btn隱藏
btn.onmouseout = function () {
btn.style.display = "none";
//鼠標離開時,啟動定時器
startAuto();
}
//點擊左側按鈕時,left向左移動
leftBtn.onclick = function () {
leftMove();
}
//點擊右側按鈕時,left向右運動
rightBtn.onclick = function () {
rightMove();
}
for (let i = 0; i < tabChildren.length; i++) {
//鼠標懸浮再第幾個小圓點上,就切換到第幾張圖片
tabChildren[i].onmouseover = function () {
//鼠標懸浮時不自動播放,清除定時器
clear();
MotionUtils.bufferMove(imgList, {
left: -i * IMG_WIDTH
});
//切換小圓點
tabMove(i);
}
}
//自動播放
startAuto();
//自動播放
function startAuto() {
//自動播放時間間隔1500,你可以隨意設置
timer = setInterval(function () {
rightMove();
}, 1500);
}
//清除定時器
function clear() {
clearInterval(timer);
}
//小圓點
function tabMove(i) {
//切換到第幾個小圓點,并修改index值,要求和i的值一致
index = i;
tabChildren[i].className = "redTab";
//遍歷tab,如果和i的值不想等則設為白色
for (let j = 0; j < tabChildren.length; j++) {
if (j !== i) {
tabChildren[j].className = "whiteTab";
}
}
}
//左側按鈕
function leftMove() {
//向做移動index--
index--;
//若index===-1,那么就跳到最后一張圖片,其index=3
if (index === -1) {
index = 3;
}
//設置left值
MotionUtils.bufferMove(imgList, {
left: -index * IMG_WIDTH
});
//切換小圓點
tabMove(index);
}
//右側按鈕
function rightMove() {
//向右移動index++
index++;
//若index===4,那么就跳到第一張圖,其index=0
if (index === 4) {
index = 0;
}
//設置left值
MotionUtils.bufferMove(imgList, {
left: -index * IMG_WIDTH
});
//切換小圓點
tabMove(index);
}
}
注釋很詳細了,就不過多解釋了。以上就實現了簡單輪播圖。為什么叫簡單呢,因為還沒完成,還有一個問題。當滾動到最后一張圖片再滾回第一張圖片時,我們發現會經過中間的圖片,那么我們怎樣才能去掉這個效果呢。接下來就看看如何實現無縫輪播圖,我們只需再第四張圖片的最后加上第一張圖即可。
window.onload = function () {
//獲得標簽對象
let imgList = $("imgList");
let btn = $("btn");
let tab = $("tab");
let leftBtn = $("leftBtn");
let rightBtn = $("rightBtn");
//獲得子元素
let imgListChildren = imgList.children;
let tabChildren = tab.children;
//用來記錄當前是第幾張圖片
let index = 0;
//用來記錄當前是第幾個小圓點
let tabIndex = 0;
//一張圖片的寬度
const IMG_WIDTH = 600;
//存儲定時器的返回值
let timer = null;
//當鼠標移入imgList時,btn顯示
imgList.onmousemove = function () {
btn.style.display = "block";
//鼠標進入時不自動播放,清除定時器
clear();
}
//當鼠標移出imgList時,btn隱藏
imgList.onmouseout = function () {
btn.style.display = "none";
//鼠標離開時,啟動定時器
startAuto();
}
//若不添加下面兩句,則會出席那bug,鼠標進入btn時會抖動
//當鼠標移到btn時,btn顯示
btn.onmouseenter = function () {
btn.style.display = "block";
//鼠標進入時不自動播放,清除定時器
clear();
}
//當鼠標移出btn時,btn隱藏
btn.onmouseout = function () {
btn.style.display = "none";
//鼠標離開時,啟動定時器
startAuto();
}
//點擊左側按鈕時,left向左移動
leftBtn.onclick = function () {
leftMove();
}
//點擊右側按鈕時,left向右運動
rightBtn.onclick = function () {
rightMove();
}
for (let i = 0; i < tabChildren.length; i++) {
//鼠標懸浮再第幾個小圓點上,就切換到第幾張圖片
tabChildren[i].onmouseover = function () {
//鼠標懸浮時不自動播放,清除定時器
clear();
MotionUtils.bufferMove(imgList, {
left: -i * IMG_WIDTH
});
//切換小圓點
tabMove(i);
}
tabChildren[i].onmouseout = function () {
startAuto();
}
}
//自動播放
startAuto();
//自動播放
function startAuto() {
timer = setInterval(function () {
rightMove();
}, 1500);
}
//清除定時器
function clear() {
clearInterval(timer);
}
//小圓點
function tabMove(i) {
//切換到第幾個小圓點,并修改index值,要求和i的值一致
index = i;
//當i===4時,小圓點應該為0
if (i === 4) {
i = 0;
}
tabChildren[i].className = "redTab";
//遍歷tab,如果和i的值不想等則設為白色
for (let j = 0; j < tabChildren.length; j++) {
if (j !== i) {
tabChildren[j].className = "whiteTab";
}
}
}
//左側按鈕
function leftMove() {
//向做移動index--
index--;
//若index===-1,那么就直接設置left為-4*IMG_WIDTH,然后index = 3
if (index === -1) {
imgList.style.left = -4 * IMG_WIDTH + "px";
index = 3;
}
//設置left值
MotionUtils.bufferMove(imgList, {
left: -index * IMG_WIDTH
});
//切換小圓點
tabMove(index);
}
//右側按鈕
function rightMove() {
//向右移動index++
index++;
//若index===5,那么直接把imgList的left值設為0,index設為1
if (index === 5) {
imgList.style.left = 0;
index = 1;
}
//設置left值
MotionUtils.bufferMove(imgList, {
left: -index * IMG_WIDTH
});
//切換小圓點
tabMove(index);
}
}
function $(id) {
return document.getElementById(id);
}
function getStyle(element, attr) {
let result = element.currentStyle ? element.currentStyle[attr] : getComputedStyle(element, null)[attr];
return Number.parseFloat(result);
}
let MotionUtils = {
/**
*
* @param obj 要改變的對象
* @param attr 要改變的對象的屬性
* @param finalValue 要改變對象的屬性的最大值
* @param callback 在上一次運動完后下一次要運動的函數,回調自己
*/
bufferMove: function (obj, data, callback) {
//清除舊定時器
clearInterval(obj.timer);
//開啟新定時器
obj.timer = setInterval(function () {
//flg標識運動是否完畢
let flg = true;
for (let attr in data) {
//獲得當前obj屬性值
let currentValue;
if (attr === "opacity") {
currentValue = Number.parseFloat(getStyle(obj, attr)) * 100;
} else {
currentValue = Number.parseInt(getStyle(obj, attr));
}
//計算速度
let speed = (data[attr] - currentValue) / 8;
//計算物體運動方向
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
//計算下一次obj的屬性值
let nextValue = currentValue + speed;
//設置屬性值
if (attr === "opacity") {
obj.style[attr] = nextValue / 100;
obj.style.filter = "alpha(opacity=" + nextValue + ")";
} else {
obj.style[attr] = nextValue + "px";
}
//判斷當前屬性是否運動完畢
if (nextValue !== data[attr]) {
flg = false;
}
}
//清除定時器
if (flg) {
clearInterval(obj.timer);
//如果傳了callback,那么就執行這個函數
if (callback) {
callback();
}
}
}, 50);
},
fadein: function (element) {
let speed = 0.1;
clearInterval(element.timer);
element.timer = setInterval(function () {
let currentOpacity = Number(getStyle(element, "opacity"));
if (currentOpacity < 1) {
element.style.opacity = currentOpacity + speed;
}
if (currentOpacity >= 1) {
element.style.opacity = 1;
clearInterval(element.timer);
}
}, 50);
},
fadeout: function (element) {
let speed = 0.1;
clearInterval(element.timer);
element.timer = setInterval(function () {
let currentOpacity = Number(getStyle(element, "opacity"));
if (currentOpacity > 0) {
element.style.opacity = currentOpacity - speed;
}
if (currentOpacity <= 0) {
element.style.opacity = 0;
clearInterval(element.timer);
}
}, 50);
}
}