一、轮播图样式 + 结构
1. 结构(左右箭头、小圆圈、轮播图片区域)
<div class="banner">
<a href="javascript:;" class="arrow_pre arrow"></a>
<a href="javascript:;" class="arrow_next arrow"></a>
<ul class="lunbo">
<li>
<a href="#">
<img src="./uploads/banner1.jpg">
</a>
</li>
<li>
<a href="#">
<img src="./uploads/banner2.jpg">
</a>
</li>
<li>
<a href="#">
<img src="./uploads/banner3.jpg">
</a>
</li>
<li>
<a href="#">
<img src="./uploads/banner4.jpg">
</a>
</li>
</ul>
<ul class="dot"></ul>
</div>
2. 样式
* {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.banner {
position: relative;
width: 721px;
height: 455px;
margin: 50px auto;
overflow: hidden;
}
.banner img {
width: 100%;
height: 100%;
}
.arrow {
position: absolute;
top: 50%;
width: 20px;
height: 32px;
transform: translateY(-50%);
z-index: 1;
display: none;
}
.arrow_pre {
left: 0;
background: url('./img/arrow-prev.png') no-repeat;
}
.arrow_next {
right: 0;
background: url('./img/arrow-next.png') no-repeat;
}
.dot {
position: absolute;
left: 50%;
bottom: 10px;
height: 15px;
padding: 3px;
transform: translateX(-50%);
background-color: rgba(0, 0, 0, .3);
}
.dot li {
float: left;
width: 15px;
height: 15px;
margin: 0 5px;
border-radius: 50%;
background-color: #ccc;
cursor: pointer;
}
.dot li.current {
background-color: #fff;
}
.lunbo {
position: absolute;
top: 0;
left: 0;
width: 500%;
}
.lunbo li {
float: left;
}
3. 小圆圈动态生成
注意:这里面的cloneNode是在生成小圆圈之后写的,所以小圆圈数量正确
var lunbo = document.querySelector('.lunbo');
var length = document.querySelector('.lunbo').children.length;
var dot = document.querySelector('.dot');
for(var i = 0; i < length; i++) {
var li = document.createElement('li');
li.setAttribute('data-index',i);
dot.appendChild(li);
li.addEventListener('click', function() {
for(var i = 0; i < dot.children.length; i++) {
dot.children[i].className = '';
}
this.className = 'current';
animate(lunbo, -banner.offsetWidth * this.dataset.index);
})
}
dot.children[0].className = 'current';
lunbo.appendChild(lunbo.children[0].cloneNode(true));
二、操作
1. 鼠标经过轮播图时,显示左右箭头按钮;离开轮播图时,隐藏左右箭头按钮。
window.addEventListener('load', function() {
var banner = document.querySelector('.banner');
var arrow_pre = document.querySelector('.arrow_pre');
var arrow_next = document.querySelector('.arrow_next');
banner.addEventListener('mouseenter', function() {
arrow_pre.style.display = 'block';
arrow_next.style.display = 'block';
})
banner.addEventListener('mouseleave', function() {
arrow_pre.style.display = 'none';
arrow_next.style.display = 'none';
})
})
2. 引入animate.js缓动动画封装函数
function animate(obj, destination, callback) {
clearInterval(obj.timer || null);
obj.timer = setInterval(function(){
var step = (destination - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == destination) {
callback && callback();
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 10)
}
3. ul轮播区域的移动公式:dot索引号 × 图片的宽
var num = 0;
var dotNumber = 0;
var lunbo = document.querySelector('.lunbo');
var length = document.querySelector('.lunbo').children.length;
var dot = document.querySelector('.dot');
for(var i = 0; i < length; i++) {
var li = document.createElement('li');
li.setAttribute('data-index',i);
dot.appendChild(li);
li.addEventListener('click', function() {
num = this.dataset.index;
dotNumber = this.dataset.index;
for(var i = 0; i < dot.children.length; i++) {
dot.children[i].className = '';
}
this.className = 'current';
animate(lunbo, -banner.offsetWidth * this.dataset.index);
})
}
dot.children[0].className = 'current';
lunbo.appendChild(lunbo.children[0].cloneNode(true));
4. 左右按钮 + 无缝对接 + 节流阀
无缝对接:在获取num后,查看num值,如果到达临界点,就先改变left值,要不然是变为0,或者是变为倒数第一张(倒数第一张图片 为 正向第一张图片的克隆品)
节流阀:防止因多次的点击事件而出现的动画飞速变化的情况
(1)右侧按钮点击
function dotChange() {
for(var i = 0; i < dot.children.length; i++) {
dot.children[i].className = '';
}
dot.children[dotNumber].className = 'current';
}
var flag = true;
arrow_next.addEventListener('click', function() {
if(flag) {
flag = false;
dotNumber++;
if(num == lunbo.children.length - 1) {
lunbo.style.left = 0;
num = 0;
}
num++;
if(dotNumber == dot.children.length) {
dotNumber = 0;
}
animate(lunbo, -num * banner.offsetWidth, function() {
flag = true;
});
dotChange();
}
})
(2)左侧按钮点击
arrow_pre.addEventListener('click', function() {
if(flag) {
flag = false;
dotNumber--;
if(num == 0) {
lunbo.style.left = -(lunbo.children.length - 1) * banner.offsetWidth + 'px';
num = lunbo.children.length - 1;
dotNumber = dot.children.length - 1;
}
num--;
animate(lunbo, -num * banner.offsetWidth, function() {
flag = true;
});
dotChange();
}
})
5. 自动播放轮播图
注意:element.click() -- 触发点击事件
var timer = setInterval(function(){
arrow_next.click();
}, 1500)
banner.addEventListener('mouseenter', function() {
arrow_pre.style.display = 'block';
arrow_next.style.display = 'block';
clearInterval(timer);
timer = null;
})
banner.addEventListener('mouseleave', function() {
arrow_pre.style.display = 'none';
arrow_next.style.display = 'none';
timer = setInterval(function(){
arrow_next.click();
}, 1500)
})