1.首先我们确定一下轮播图的思路。
1.我们用一个div充当容器
2.我们在这个div容器当中引入ul标签
3.我们将轮播的图片填充到ul标签下的li标签
4.通过设置css样式使得轮播图片在同行排列并且设置多余的图片隐藏
5.给轮播图添加各种控件并设置样式
6.写js代码使轮播图运动起来
2.让我们开始吧
<div class="wrapper">
//轮播图区域
<ul id="sliderPage">
<li><img src="cat1.jpg" alt=""></li>
<li><img src="cat2.jpg" alt=""></li>
<li><img src="cat3.jpg" alt=""></li>
<li><img src="cat4.jpg" alt=""></li>
<li><img src="cat1.jpg" alt=""></li>
</ul>
<div class="sliderIndex">
//轮播的小圆点
<i class="active"></i>
<i></i>
<i></i>
<i></i>
</div>
//向左的控制按钮
<div class="btn leftBtn" id="leftBtn"><</div>
//向右的控制按钮
<div class="btn rightBtn" id="rightBtn">></div>
</div>
然后我们设置css样式
<style type="text/css">
*{
margin: 0;
padding: 0;
list-style: none;
}
.wrapper{
position: relative;
margin: 100px auto;
width: 400px;
height: 200px;
border:1px solid black;
overflow: hidden;
}
.wrapper ul {
position: absolute;
left:0px;
top:0px;
width: 2000px;
height: 200px;
}
.wrapper ul li{
float: left;
width: 400px;
height: 200px;
}
.wrapper ul li img{
width: 400px;
height: 200px;
}
.wrapper .sliderIndex{
position: absolute;
bottom: 10px;
left: 50%;
width: 80px;
height: 20px;
margin-left: -40px;
text-align: center;
}
.wrapper .sliderIndex i{
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: black;
margin-right: 6px;
cursor: pointer;
}
.wrapper .sliderIndex i.active{
background: red;
width: 12px;
height: 12px;
}
.wrapper .btn{
position: absolute;
width:30px;
height: 30px;
background: black;
opacity: 0.5;
margin-top: -15px;
top:50%;
line-height: 30px;
color: white;
text-align: center;
cursor: pointer;
}
.wrapper .btn.leftBtn{
left: 20px;
}
.wrapper .btn.rightBtn{
right: 20px;
}
.wrapper .btn:hover {
opacity: 1;
}
</style>
这里几个主要的地方在于:
1.我们通过给li标签设置左浮动,让几张轮播图能够同行排列(类似胶片的效果)
2.给外面div容器设置overflow: hidden
让多余的图片隐藏,因为我们轮播图每次只完整显示一张图片(切换过程不算)
3.然后给控件添加css样式,轮播图的小圆点我们用i标签实现,但是i标签是行内元素,对其设置宽高无效所以我们设置display: inline-block
使其能够变成行内块级元素设置宽高,且不会换行。
4.其次我们对按钮设置样式
3.用js实现轮播
1.首先我们完成运动函数move.js
//获取元素当前的属性值
function getStyle (obj, attr) {
//兼容性处理
if (obj.currentStyle) {
return obj.currentStyle[attr];
}else {
return window.getComputedStyle(obj, false)[attr];
}
}
function startMove (obj, data, func) {
clearInterval(obj.timer);
var iSpeed;
var iCur;
var name;
startTimer = obj.timer = setInterval(function () {
//变量bStop来控制着运动结束与否,因为有可能多个属性值都需要变化,我们需要所有属性值都运动到目标值才能结束我们的函数
var bStop = true;
//我们用for in遍历对象里的每一个属性,让他们都能够运动
for (var attr in data) {
if (attr === 'opacity') {
name = attr;
iCur = parseFloat(getStyle(obj, attr)) * 100;
}else {
iCur = parseInt(getStyle(obj, attr));
}
iSpeed = ( data[attr] - iCur) / 8;
if (iSpeed > 0) {
iSpeed = Math.ceil(iSpeed);
}else {
iSpeed = Math.floor(iSpeed);
}
if (attr === 'opacity') {
//透明度(0~1)所以需要缩小一百倍
obj.style.opacity = ( iCur + iSpeed ) / 100;
}else {
obj.style[attr] = iCur + iSpeed + 'px';
}
if ( Math.floor(Math.abs(data[attr] - iCur)) != 0 ) {
//当存在任意属性值还未到该属性的目标值证明运动还没结束,将bStop设置成false继续运动
bStop = false;
}
}
//当运动全部结束,bStop变为true,清除定时器,执行回调函数
if (bStop) {
clearInterval(obj.timer);
if (name === 'opacity') {
obj.style.opacity = data[name] / 100;
}
func();
}
},30);
}
2.实现按钮控制轮播方向和自动轮播
<script>
//获取相应dom元素
var sliderTimer = null;
var sliderPage = document.getElementById("sliderPage");
var leftBtn = document.getElementById("leftBtn");
var rightBth = document.getElementById("rightBtn");
var moveWidth = sliderPage.children[0].offsetWidth;
var index = 0;
var num = sliderPage.children.length - 1;
var lock = true;
var imgArr = document.getElementsByTagName('i');
//点击相应的索引跳到对应的轮播图
for (var i = 0; i < imgArr.length; i++) {
//这里使用立即执行函数是因为产生了闭包
imgArr[i].onclick = (function(sliderIndex) {
return function() {
clearInterval(sliderTimer);
index = sliderIndex;
changeIndex(index);
startMove(sliderPage, {
left: -moveWidth * sliderIndex
}, function() {
sliderTimer = window.setInterval(autoMove, 1500);
//这里是为了防止自动轮播到一半(此时lock = false)点击索引的圆点导致运动停止(进入不了if循环)
lock = true;
});
}
})(i);
}
leftBtn.onclick = function() {
//从右向左轮播
autoMove(-1);
}
rightBth.onclick = function() {
//从左向右 也就是默认的轮播方向
autoMove(1);
}
function autoMove(target) {
//lock是为了防止在一次运动未完成的情况下多次点击按钮导致index超出,根本无法进行判断且导致left的属性值也超出范围使得函数无法正常执行
if (lock) {
//进入函数关闭锁
lock = false;
//为了点击按钮和默认轮播不冲突,每次运动都先清除定时器在后面再启动
clearInterval(sliderTimer);
//判断当target === 1或者undefined(即默认)证明是从左往右轮播
if (target === 1 || !target) {
index++;
//并执行move.js里的startmove函数开始运动
startMove(sliderPage, {
left: sliderPage.offsetLeft - moveWidth
}, function() {
//这是index是图片的索引,当index===4证明已经从第一张图片重新开始轮播,并且将索引归0
if (index === 4) {
sliderPage.style.left = "0px";
index = 0;
}
sliderTimer = window.setInterval(autoMove, 1500);
lock = true;
changeIndex(index);
});
} else if (target == -1) {
//sliderPage.offsetLeft === 0证明此时轮播图在第一张
if (sliderPage.offsetLeft === 0) {
//这个时候点击左按键就应该跳转到最后一张轮播图
sliderPage.style.left = -moveWidth * num + 'px';
//index也变成最后轮播图的索引
index = num;
}
index--;
changeIndex(index);
startMove(sliderPage, {
left: sliderPage.offsetLeft + moveWidth
}, function() {
sliderTimer = window.setInterval(autoMove, 1500);
//函数结束,打开锁使得下次函数能够执行
lock = true;
});
}
}
}
//每次图片轮播对应索引的小圆点添加active样式
function changeIndex(index) {
for (var i = 0; i < imgArr.length; i++) {
imgArr[i].className = '';
}
imgArr[index].className = 'active';
}
sliderTimer = window.setInterval(autoMove, 1500)
</script>
OK,大功告成