功能预览
实现步骤
- 搭建静态框架
- 轮播图实现核心在于:设置图片盒子ul相对于父盒子div的left数值
- 基于以上原理,需要先将图片显示在一条线上,实现左浮动的效果
- 实现代码如下:
html 代码
<div class="sildeshow">
<!-- 左侧按钮-->
<a href="javascript:;" class="arrow-l">⬅</a>
<!-- 右侧按钮-->
<a href="javascript:;" class="arrow-r">➡</a>
<!-- 滚动区域-->
<ul>
<li>
<a href="#"><img src="../imgs/OIP.jpg" alt="图片"></a>
</li>
<li>
<a href="#"><img src="../imgs/green_bg.jpg" alt="图片"></a>
</li>
<li >
<a href="#"><img src="../imgs/grils.png" alt="图片"></a>
</li>
</ul>
<!-- 点击圆圈区域-->
<ol class="circle"></ol>
</div>
css代码
ul,
ol {
margin: 0;
padding: 0;
list-style-type: none;
}
.sildeshow {
position: relative;
margin: 0 auto;
width: 760px;
height: 400px;
/*border: 1px solid #86c4d6;*/
/*background-color: #999999;*/
overflow: hidden;
}
.sildeshow ul {
position: absolute;
top: 0px;
left: 0px;
width: 400%;
height: 100%;
}
.sildeshow ul li {
float: left;
}
img {
width: 760px;
height: 400px;
}
a {
text-decoration: none;
}
.arrow-l {
display: none;
position: absolute;
top: 200px;
left: 10px;
font-size: 30px;
color: #fff;
z-index: 9;
}
.arrow-r {
display: none;
position: absolute;
top: 200px;
right: 10px;
font-size: 30px;
color: #fff;
z-index: 9;
}
.circle {
position: absolute;
bottom: 10px;
left: 50px;
z-index: 9;
}
.circle li {
float: left;
width: 10px;
height: 10px;
/*background-color: #fff;*/
border: 3px solid rgba(255, 255, 255, 0.5);
margin: 0 3px;
border-radius: 50%;
/*鼠标经过显示小手*/
cursor: pointer;
}
.current_circle {
background-color: #fff;
}
- 鼠标经过以及离开注册事件
- 当鼠标经过的时候,设置注册事件,显示左右图标,并移除定时器(其中,定时器实现轮播图的自动播放效果)
- 当鼠标离开的时候,设置注册事件,隐藏左右图标,并设置定时器。
- 实现代码如下
var sildeshow = document.querySelector('.sildeshow'); var arrow_l = document.querySelector('.arrow-l'); var arrow_r = document.querySelector('.arrow-r'); // 鼠标经过轮播图 显示隐藏左右箭头 sildeshow.addEventListener('mouseenter',function () { arrow_l.style.display = 'block'; arrow_r.style.display = 'block'; // 终止计时器 clearInterval(timer); timer = null; }) sildeshow.addEventListener('mouseleave',function () { arrow_l.style.display = 'none'; arrow_r.style.display = 'none'; timer = setInterval(function () { // 手动调用计时器 arrow_r.click(); },2000); })
- 底部小圆圈动态生成以及注册点击事件
- 首先根据图片的个数来动态生成li标签,从而实现动态显示小圆圈
- 给每个li标签添加点击注册事件,实现点击不同小圆圈切换不同图片,实现如下
- 给每个li标签添加自定义属性以便与每个图片建立索引上的联系
li.setAttribute('data-index',i);
- 在li标签点击事件中,计算图片盒子ul偏移量。由于每个图片的宽度和父盒子ul都是一样的,所以可以建立索引与ul偏移量的方式显示每个盒子,也即ul偏移 = -1 * (图片索引 * ul父盒子宽度)。
此处涉及的animate函数详见js动画函数实现侧边栏动态显示内容.var li = document.createElement('li'); // 点击小圆圈 切换图片 var index = this.dataset.index; var sildeshowWidth = ul.querySelectorAll('img')[index].offsetWidth + 4; animate(ul,-index * sildeshowWidth,15);
- 左右箭头注册点击事件
- 为左右箭头注册点击事件
- 当右箭头被点击(左箭头类似)时,会涉及到的业务逻辑为:图片切换同时小圆圈选中状态同步变化
- 图片切换,也即需要ul盒子偏移变化,通过设置变量num控制当前显示的图片索引
- 当切换到最后一张图片时,由于直接将图片索引num = 0,直接切换第一张会导致如下情况:
可以看出有明显的图片快速右移的现象,为了解决这种情况,采用无缝滚动原理:在图片最后添加第一张图片
当切换到最后一张图的时候,再次点击,ul父盒子偏移量变成第一个图片的偏移量,索引num = 0 再num + 1,再一定程度上实现似乎是由第一张图切换到第二张图片的效果。
// 采取无缝滚动原理 num == ul.children.length - 1的原因是: 点击后图片为下一张图片,因此num 与 图片实际相差1
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
- 多次快速点击会导致图片未显示完便显示下一张,是的播放过快的情况,因此采用节流阀来解决以上情况
- 节流阀的目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让函数无法连续触发
- 核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数
- 开始设置一个变量var flag = true;
- if(flag){flag = false;do something} 关闭水龙头
- 利用回调函数 动画执行完毕,flag = true 打开水龙头
- 自动播放
- 由于自动播放的实现原理与点击右箭头一样,因此只需要在定时器中手动调用右箭头点击事件即可
// 自动播放轮播图 var timer = setInterval(function () { // 手动调用点击事件 arrow_r.click(); },2000)
实现代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>practice1</title>
<link href="../css/practive1.css" rel="stylesheet"/>
<script src="../js/animate.js"></script>
<script type="text/javascript" src="../js/practice1.js"></script>
</head>
<body>
<div class="sildeshow">
<!-- 左侧按钮-->
<a href="javascript:;" class="arrow-l">⬅</a>
<!-- 右侧按钮-->
<a href="javascript:;" class="arrow-r">➡</a>
<!-- 滚动区域-->
<ul>
<li>
<a href="#"><img src="../imgs/OIP.jpg" alt="图片"></a>
</li>
<li>
<a href="#"><img src="../imgs/green_bg.jpg" alt="图片"></a>
</li>
<li >
<a href="#"><img src="../imgs/grils.png" alt="图片"></a>
</li>
</ul>
<!-- 点击圆圈区域-->
<ol class="circle"></ol>
</div>
</body>
</html>
css
ul,
ol {
margin: 0;
padding: 0;
list-style-type: none;
}
.sildeshow {
position: relative;
margin: 0 auto;
width: 760px;
height: 400px;
/*border: 1px solid #86c4d6;*/
/*background-color: #999999;*/
overflow: hidden;
}
.sildeshow ul {
position: absolute;
top: 0px;
left: 0px;
width: 400%;
height: 100%;
}
.sildeshow ul li {
float: left;
}
img {
width: 760px;
height: 400px;
}
a {
text-decoration: none;
}
.arrow-l {
display: none;
position: absolute;
top: 200px;
left: 10px;
font-size: 30px;
color: #fff;
z-index: 9;
}
.arrow-r {
display: none;
position: absolute;
top: 200px;
right: 10px;
font-size: 30px;
color: #fff;
z-index: 9;
}
.circle {
position: absolute;
bottom: 10px;
left: 50px;
z-index: 9;
}
.circle li {
float: left;
width: 10px;
height: 10px;
/*background-color: #fff;*/
border: 3px solid rgba(255, 255, 255, 0.5);
margin: 0 3px;
border-radius: 50%;
/*鼠标经过显示小手*/
cursor: pointer;
}
.current_circle {
background-color: #fff;
}
js
window.addEventListener('pageshow',function () {
var sildeshow = document.querySelector('.sildeshow');
var arrow_l = document.querySelector('.arrow-l');
var arrow_r = document.querySelector('.arrow-r');
// 鼠标经过轮播图 显示隐藏左右箭头
sildeshow.addEventListener('mouseenter',function () {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
// 终止计时器
clearInterval(timer);
timer = null;
})
sildeshow.addEventListener('mouseleave',function () {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
timer = setInterval(function () {
// 手动调用计时器
arrow_r.click();
},2000);
})
// 动态生成小圆圈
var ul = sildeshow.querySelector('ul');
var ol = sildeshow.querySelector('.circle');
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
// 绑定自定义属性Index
li.setAttribute('data-index',i);
ol.appendChild(li);
// li标签绑定点击事件
li.addEventListener('click',function () {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
this.className = 'current_circle';
// 点击小圆圈 切换图片
var index = this.dataset.index;
// 控制与左右箭头点击以及小圆圈显示同步
num = index;
circle = index;
var sildeshowWidth = ul.querySelectorAll('img')[index].offsetWidth + 4;
animate(ul,-index * sildeshowWidth,15);
})
}
// 设置第一个小圆圈默认被选中
if (ol.children[0]) {
ol.children[0].className = 'current_circle';
}
// 右侧箭头点击注册事件
var num = 0; // 控制显示图片次序
// 克隆第一张图片 在生成小圆圈之后操作,不会引起多于小圆圈的产生
var firstLi = ul.children[0].cloneNode(true);
ul.appendChild(firstLi);
// 控制小圆圈播放
var circle = 0;
// 节流阀
var flag = true;
arrow_r.addEventListener('click',function () {
if (flag) {
// 关闭节流阀
flag = false;
// 采取无缝滚动原理 num == ul.children.length - 1的原因是: 点击后图片为下一张图片,因此num 与 图片实际相差1
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
var sildeshowWidth = ul.querySelectorAll('img')[num].offsetWidth + 4;
animate(ul,-num * sildeshowWidth,15,function () {
// 动画执行完毕,方可打开节流阀
flag = true;
});
// 小圆圈播放设置
circle++;
circle = circle == ul.children.length - 1? 0 : circle;
clearOlLi();
}
})
// 左侧箭头点击注册事件
arrow_l.addEventListener('click',function () {
if (flag) {
// 关闭节流阀
flag = false;
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = - num * (ul.querySelectorAll('img')[num].offsetWidth + 4) + 'px';
}
num--;
var sildeshowWidth = ul.querySelectorAll('img')[num].offsetWidth + 4;
animate(ul,-num * sildeshowWidth,15,function () {
// 只有当当前动画执行完毕,方可打开节流阀
flag = true;
});
// 小圆圈播放设置
circle--;
circle = circle < 0? ol.children.length - 1 : circle;
clearOlLi();
}
})
// 自动播放轮播图
var timer = setInterval(function () {
// 手动调用点击事件
arrow_r.click();
},2000)
// 清除ol样式
function clearOlLi() {
// 排他思想清除其他样式
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 设置小圆圈的样式
ol.children[circle].className = 'current_circle';
}
})
涉及的animate函数见js动画函数实现侧边栏动态显示内容.