现在要自行因代码实现一个轮播图,主要具备下列功能
- 定时轮播
- 鼠标移入暂停轮播,移出继续正常轮播
- 点击左侧按钮,查看上一张
- 点击右侧按钮,查看下一张
- 导航栏地小圆点根据不同轮播图,对应高亮
现在看一下实现地具体效果(找图片太麻烦,我直接把每张轮播图设置不同颜色,方便辨认)
按照以往惯例,依旧是来捋一下思路:
首先看一下大思路:盒子设置溢出隐藏,设置7个 li 标签用于表示轮播图(首尾两张是假图,为了实现无缝轮播),父盒子相对定位,ul绝对定位,利用left属性移动实现轮播。看一下没有设置溢出隐藏时的效果
功能实现 | 思路 |
自动轮播 | 定时器实现 |
无缝轮播衔接 | 需要展示的是五张,准备7张,第一张和第六张一样,第七张和第二张一样(第二张其实就是肉眼见到的第一张),当轮播到第七张以后,无过渡直接跳到第二张,同样地,轮播到第一张时,无过渡直接跳到 |
导航自动对应高亮 | 首先将当前的那张轮播图序号,利用自定义属性设置给父盒子,由此可以将对应的小圆点按照序号设置高亮 |
鼠标移入暂停 | 注册鼠标移入事件,在事件函数中清除定时器 |
鼠标移出按照原位置继续轮播 | 获取父盒子自定义属性中记录的序号,由此实现,注意不要重新再设置一个定时器 |
点击按钮切换上下页 | 依旧是需要获取序号,下一张就序号就加一,上一张就减一 |
代码展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.white{
background-color: #ccc;
}
.black{
background-color:black ;
}
#banner{
width: 400px;
height: 200px;
overflow: hidden;
margin: 100px auto;
position: relative;
}
ul{
position: absolute;
width: 3200px;
height: 200px;
list-style: none;
position: relative;
left: -400px;
}
ul>li{
box-sizing: border-box;
border: 1px solid #000;;
padding-top: 100px;
text-align: center;
width: 400px;
height: 200px;
background-color: rgb(128, 17, 17);
float: left;
}
ul>li:first-child {
background-color: rgb(108, 8, 117);
}
ul>li:nth-child(2) {
background-color: rgb(26, 131, 40);
}
ul>li:nth-child(3) {
background-color: rgb(129, 31, 64);
}
ul>li:nth-child(4) {
background-color: rgb(61, 39, 156);
}
ul>li:nth-child(5){
background-color: rgb(16, 92, 128);
}
ul>li:nth-child(6){
background-color: rgb(108, 8, 117);
}
ul>li:nth-child(7){
background-color: rgb(26, 131, 40);
}
#banner_item {
position: relative;
top: -150px;
width: 100px;
height: 3px;
margin: 0 auto;
}
ol {
list-style: none;
width:100px;
height: 3px;
}
ol>li {
width: 10px;
height: 10px;
border-radius: 50% 50%;
background-color: #cccc;
float: left;
margin-right: 10px;
}
#left_btn,
#right_btn {
width: 40px;
height:40px;
position:absolute;
background-color:rgba(65, 30, 30, 0.5);
font-size: 20px;
box-sizing: border-box;
}
#left_btn {
left: 0;
top:80px;
}
#right_btn{
padding-left: 20px;
right: 0;
top:80px;
}
</style>
</head>
<body>
<div id="banner">
<ul>
<!-- 用于做轮播图 -->
<li>5</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>1</li>
</ul>
<div id="left_btn"><</div>
<div id="right_btn">></div>
</div>
<div id="banner_item">
<ol>
<!-- 用于做导航的小圆点 -->
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
<script>
var ul=document.querySelector("#banner>ul");//获取ul元素
// var first_lis=document.querySelectorAll("ul>li");//获取ul的li元素伪数组
var second_lis=document.querySelectorAll("ol>li");//获取ol的li元素
var banner=document.getElementById("banner");
console.log(first_lis[0].offsetWidth);
var step=first_lis[0].offsetWidth;// 每张轮播图的宽度
var distance=0;//用于记录每次移动地距离
var n=1;//用于记录当前是哪一张轮播图
function fn(){
banner.dataset.index=n;
console.log(n);
distance=n*step;
ul.style.left=-distance+"px";
// 实现导航高亮
for(var i=0;i<second_lis.length;i++){
second_lis[i].className="white";
// 实现排他,先全部不高亮
}
if(n>=6){
second_lis[0].className="black";
}else if(n==0){
second_lis[4].className="black";
}
else{
second_lis[n-1].className="black";
}
}
function timefn(){
ul.style.transition="none";
// 提前清除一下过渡效果
if(n<=-1){
n=5;
fn();
}else if(n>=7){
//当图片到达最后一张时,退回到第一张,实现无缝轮播
n=1;
fn();
}
else{
fn();
ul.style.transition="all 1s";
}
}
//自动轮播效果
var timeid=setInterval(function(){
timefn();
n++;
},1000);
//鼠标移入,轮播暂停
var left=document.getElementById('left_btn');
var right=document.getElementById("right_btn");
banner.addEventListener("mouseenter",mouseFn);
function mouseFn(){
clearInterval(timeid);//清除定时器,轮播图停止
//点击左边按钮,查看上一张
var boot=0;
function toggle(){
n=banner.dataset.index;//获取当前轮播图地序号
if(boot<0){
--n;
timefn();
} else{
++n;;
timefn();
}
}
left.addEventListener("click",function(){
boot=-1;
toggle();
console.log("我现在是第"+banner.dataset.index+"张");
})
// //点击右边按钮,查看下一张
right.addEventListener("click",function(){
boot=1;
toggle();
})
}
banner.addEventListener("mouseleave",function(){
clearInterval(timeid);
n=banner.dataset.index;
timeid=setInterval(function(){
timefn();
n++;
},1000);
})
// banner.addEventListener("mouseleave",function(){
// console.log(banner.dataset.index);
// })
</script>
</body>
</html>
总结:其实轮播图有很多组件可以直接实现,这种原生的写起来也比较麻烦,但是也算是加深了一下对定时器以及过渡等的理解,当然原生的写法也不止这一种,有兴趣也可以用其他方法实现一下。