主要功能介绍:
鼠标移动到轮播图中显示左右按钮,轮播图片的定时器停止
鼠标移出轮播图隐藏左右按钮,轮播图片的定时器开始
动态创建下面的小圆点
无缝滚动效果
点击左右按钮能切换图片,点击小圆点也能切换到对应的图片中,定时器切换图片
使用时间阀,只有点击左右按钮图片运动完成之后,点击左右按钮才能再次滚动,防止点击左右按钮次数过多,图片滚动过快的情况
1、先搭建框架,标签如下图所示
2、html和css代码如下图所示,简单写一下,重要是学习js代码
<style>
* {
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.focus {
margin: 0 auto;
position: relative;
width: 1200px;
height: 600px;
background-color: pink;
overflow: hidden;
}
ul {
position: absolute;
/* margin-left: 100px; */
width: 8000px;
height: 600px;
}
ul li {
float: left;
width: 1200px;
height: 600px;
background-color: purple;
overflow: hidden;
}
img {
width: 100%;
}
span {
position: absolute;
width: 60px;
height: 60px;
background-color: rgba(0, 0, 0, .5);
color: #fff;
font-size: 40px;
text-align: center;
line-height: 60px;
top: 40%;
z-index: 2;
cursor: move;
}
.left {
display: none;
left: 0;
}
.right {
display: none;
left: 1138px;
}
ol {
position: absolute;
top: 550px;
left: 50%;
height: 40px;
background-color: rgba(0, 0, 0, .2);
list-style: none;
transform: translate(-50%);
border-radius: 20px;
padding: 0 20px;
}
ol li {
float: left;
width: 20px;
height: 20px;
border-radius: 10px;
background-color: #fff;
margin-top: 10px;
margin-left: 15px;
}
.current {
background-color: orange;
}
</style>
<script src="animate.js"></script>
<script src="轮播.js"></script>
</head>
<body>
<div class="focus">
<span class="left"><</span>
<span class="right">></span>
<ul>
<li>
<a href="javascript:;"><img src="1.jpg" alt=""></a>
</li>
<li>
<a href="javascript:;"><img src="2.jpg" alt=""></a>
</li>
<li>
<a href="javascript:;"><img src="3.jpg" alt=""></a>
</li>
<li>
<a href="javascript:;"><img src="4.jpg" alt=""></a>
</li>
</ul>
<ol>
</ol>
</div>
三、javascript代码如下
赶时间直接复制版:
导包:这是自己写的一个js代码文件,名字命名为animate.js
function animate(obj, target, callback) {
// 写到创建定时器前面,始终让定时器,做多只有一个。
clearInterval(obj.timer);
obj.timer = setInterval(function() {
// 当box左边距离page的距离大于target的时候,就清除计时器。
// 但一点击就会又调用一次这个函数,就会又创建一次定时器,
// 定时器存在就会不停向右移动
// 只有达到极值(目的目标)时才会清除定时器。
var step = (target - obj.offsetLeft) / 10;
if (step >= 0) {
step = Math.ceil(step);
} else {
step = Math.floor(step);
};
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
// 当他清除定时器时,说明所有的都已经执行完毕,再写回调函数就是所有的执行完,他才执行
if (callback) {
callback();
}
// callback && callback();
}
// console.log('obj.offsetLeft:' + obj.offsetLeft);
// console.log('step:' + step);
// console.log('target' + target);
obj.style.left = (obj.offsetLeft + step) + 'px';
}, 50);
}
轮播图代码:
window.addEventListener('load', function() {
var spanLeft = document.querySelector('.left');
var spanRight = document.querySelector('.right');
var focus = document.querySelector('.focus');
var ol = this.document.querySelector('ol');
var ul = focus.querySelector('ul');
// 鼠标经过focus区域,左右两边的按钮显示
focus.addEventListener('mouseenter', function() {
spanLeft.style.display = 'block';
spanRight.style.display = 'block';
// 当鼠标经过focus区域的时候,清除定时器
clearInterval(timer);
timer = null;
});
// 鼠标离开focus区域,左右两边的按钮隐藏
focus.addEventListener('mouseleave', function() {
spanLeft.style.display = 'none';
spanRight.style.display = 'none';
// 离开focus时开启定时器(这里就不用var timer 了,直接给timer赋一个函数即可)
timer = setInterval(function() {
// 手动调用点击事件 目标对象.事件类型()
spanRight.click();
}, 2000)
});
// 动态创建小圆圈li并将他添加到ol中
for (var i = 0; i < ul.children.length; i++) {
// 每循环一次,创建一个li(不能创建一个li添加多次)
var li = document.createElement('li');
ol.appendChild(li);
// 每创建一个li就给他创建一个自定义属性
li.setAttribute('index', i);
// 点击的这个li(不点击不会触发,当点击时早已经生成完毕)
// 点击li让ul移动相应的距离
li.addEventListener('click', function() {
// 排他思想
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
this.className = 'current';
// 获取被点击li的自定义属性index的值
var index = this.getAttribute('index');
// 当我们点击了某个li时,就把这个li的索引值index给num
// 让点击的小圆圈和点击左右按钮移动图片联系起来
//不然,如果点击第三个小圆圈,下面的小圆点到第三个,再点击右按钮,
// 他又会按照点击右按钮的算法,给num赋值为2,让小圆点到第二个上去
num = index;
// 当我们点击了某个li时,就把这个li的索引值index给circle
// 让点击的小圆圈和点击左右按钮,下面的小圆点也跟着动联系起来
circle = index;
// 注意ul没有position:absolute;就不能移动,原理就是靠改变绝对定位的值来改变位置的
animate(ul, -index * focus.offsetWidth);
});
};
// 先给ol里面的第一个小圆圈一个current属性,让圆圈不点击情况下,默认颜色为橘色
ol.children[0].className = 'current';
// 深度克隆第一个li,为了实现动态的无缝连接
// 克隆的放到生成ol>li的后面,不然就会多生成一个li,影响效果
var first = ul.children[0].cloneNode(true);
// 将第一个li添加到ul的后面,他又在创建小圆圈的后面,所以不用多创建一个小圆圈
ul.appendChild(first);
// 点击一次右侧按钮,就让图片往右移动一个li的距离
// 让左右按钮和ul图片移动联系起来
var num = 0;
// 定义一个全局变量circle,当点击左右切换按钮时,下面的小圆点也跟着动
var circle = 0;
// 定义一个flag变量,用节流阀来防止图片切换过快的现象
var flag = true;
spanRight.addEventListener('click ', function() {
// 点击按钮后,先让他进入if判断语句执行,进入后把路给他封上,
// 再当所有的动画都执行完毕后,即用回调函数再把路给他打开
if (flag) {
flag = false;
num++;
// num是从0开始的,他最多到ul.children.length-1个,当num=(children.length-1)+1时,
// 说明又得循环一次。 比如有4个li,再加上克隆的,一共有5个。num最大到4(从0开始)
// 当num等于5时,让他的位置迅速的到num= 0的位置(肉眼看不见的移动),此时再让num = 1,再进行
// 一次动画,相当于无缝连接
// 时,返回开头,从0开始无缝滚动
if (num == ul.children.length) {
ul.style.left = 0;
num = 1;
}
// 添加回调函数,等动画都执行完毕再执行回调函数即让他可以点击按钮,切换图片
animate(ul, -num * focus.offsetWidth, function() {
flag = true;
});
// 先++,因为点击后切换到第二个li,给第二个小圆点current才行
// 让左右按钮和下面的小圆圈联系起来
circle++;
// 排他思想
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 一共有四个圈,circle从0开始,最大到3,让他的圈等4时,强制circle等于0,就实现循环
if (circle == ol.children.length) {
circle = 0;
}
// 让第circle+1个圈有橙色的类名
ol.children[circle].className = 'current';
}
});
// 点击一次左边的按钮,先num--如果他等于-1,也就是说一个循环结束,他该换到最后一张图片了
// 就迅速把他的最后一张的ul的left值用style.left的方式赋值给ul,
// 当他迅速(肉眼看不到的速度)切换到最后一张克隆的照片时,让num=最后一张照片的前一个值,
// 再做一次动画,将ul的left值,减少一个li的大小======> 无缝滚动原理
spanLeft.addEventListener('click', function() {
if (flag) {
num--;
if (num == -1) {
// 当num= -1时,让ul迅速到达第5图,即num= 4时<=>ul.children.length - 1
// 再让他往前做一次动画------->无缝连接
ul.style.left = -(ul.children.length - 1) * focus.offsetWidth;
num = ul.children.length - 2;
}
animate(ul, -num * focus.offsetWidth, function() {
flag = true;
});
circle--;
// 排他思想
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
if (circle == -1) {
circle = ol.children.length - 1;
}
ol.children[circle].className = 'current';
}
})
// 自动播放轮播图
var timer = this.setInterval(function() {
// 手动调用点击事件 目标对象.事件类型()
spanRight.click();
}, 1000);
})
详细解析版:
1、 鼠标经过focus区域,左右两边的按钮显示
鼠标离开focus区域,左右两边的按钮隐藏
这一块不是很难,当你想要做轮播图的时候,这就已经很简单了。
window.addEventListener('load', function() {
var spanLeft = document.querySelector('.left');
var spanRight = document.querySelector('.right');
var focus = document.querySelector('.focus');
// 鼠标经过focus区域,左右两边的按钮显示
focus.addEventListener('mouseenter', function() {
spanLeft.style.display = 'block';
spanRight.style.display = 'block';
});
// 鼠标离开focus区域,左右两边的按钮隐藏
focus.addEventListener('mouseleave', function() {
spanLeft.style.display = 'none';
spanRight.style.display = 'none';
});
2、动态创建小圆圈li并将他添加到ol中(ol中的小圆圈的数目不能固定,所以要动态添加)
//获取小圆圈的ol和轮播图中的ul
var ol = this.document.querySelector('ol');
var ul = focus.querySelector('ul');
for (var i = 0; i < ul.children.length; i++) {
// 每循环一次,创建一个li(不能创建一个li添加多次)
var li = document.createElement('li');
ol.appendChild(li);
}
// 先给ol里面的第一个小圆圈一个current属性,让圆圈不点击情况下,默认颜色为橘色
ol.children[0].className = 'current';
3、点击下方的小圆圈,就切换图片(实质是让ul移动相应的距离),当前小圆点的颜色也改变
注意:这个操作可以在上述操作中进行,这步操作在点击之后才会运行,当你点击时,上述操作早已经执行完毕
//获取小圆圈的ol和轮播图中的ul
var ol = this.document.querySelector('ol');
var ul = focus.querySelector('ul');
for (var i = 0; i < ul.children.length; i++) {
// 每循环一次,创建一个li(不能创建一个li添加多次)
var li = document.createElement('li');
ol.appendChild(li);
// 每创建一个li就给他创建一个自定义属性
li.setAttribute('index', i);
// 点击的这个li(不点击不会触发,当点击时上述早已经生成完毕)
// 点击li让ul移动相应的距离
li.addEventListener('click', function() {
// 排他思想,让所有的li的className全消失,让当前的classname出现
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
this.className = 'current';
// 获取被点击li的自定义属性index的值
var index = this.getAttribute('index');
animate(ul, -index * focus.offsetWidth);
});
}
4、为了实现无缝连接,需要深度克隆第一li并将它放到ul最后面的位置
深度克隆:var first = li.cloneNode(true);
在元素后添加:父级.appendChild(子级);
ol.children[0].className = 'current';
// 深度克隆第一个li,为了实现动态的无缝连接
// 克隆的放到生成ol>li的后面,不然就会多生成一个li,影响效果
var first = ul.children[0].cloneNode(true);
// 将第一个li添加到ul的后面,他又在创建小圆圈的后面,所以不用多创建一个小圆圈
ul.appendChild(first);
5、点击左右按钮实现图片的切换效果
// 定义一个flag变量,用节流阀来防止图片切换过快的现象
var flag = true;
spanRight.addEventListener('click', function() {
// 点击按钮后,先让他进入if判断语句执行,进入后把路给他封上,
// 再当所有的动画都执行完毕后,即用回调函数再把路给他打开
if (flag) {
flag = false;
num++;
// num是从0开始的,他最多到ul.children.length-1个,当num=(children.length-1)+1时,
// 说明又得循环一次。 比如有4个li,再加上克隆的,一共有5个。num最大到4(从0开始)
// 当num等于5时,让他的位置迅速的到num= 0的位置(肉眼看不见的移动),此时再让num = 1,再进行
// 一次动画,相当于无缝连接
// 时,返回开头,从0开始无缝滚动
if (num == ul.children.length) {
ul.style.left = 0;
num = 1;
}
// 添加回调函数,等动画都执行完毕再执行回调函数即让他可以点击按钮,切换图片
animate(ul, -num * focus.offsetWidth, function() {
flag = true;
});
// 先++,因为点击后切换到第二个li,给第二个小圆点current才行
// 让左右按钮和下面的小圆圈联系起来
circle++;
// 排他思想
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 一共有四个圈,circle从0开始,最大到3,让他的圈等4时,强制circle等于0,就实现循环
if (circle == ol.children.length) {
circle = 0;
}
// 让第circle+1个圈有橙色的类名
ol.children[circle].className = 'current';
}
});
// 点击一次左边的按钮,先num--如果他等于-1,也就是说一个循环结束,他该换到最后一张图片了
// 就迅速把他的最后一张的ul的left值用style.left的方式赋值给ul,
// 当他迅速(肉眼看不到的速度)切换到最后一张克隆的照片时,让num=最后一张照片的前一个值,
// 再做一次动画,将ul的left值,减少一个li的大小======> 无缝滚动原理
spanLeft.addEventListener('click', function() {
if (flag) {
num--;
if (num == -1) {
// 当num= -1时,让ul迅速到达第5图,即num= 4时<=>ul.children.length - 1
// 再让他往前做一次动画------->无缝连接
ul.style.left = -(ul.children.length - 1) * focus.offsetWidth;
num = ul.children.length - 2;
}
animate(ul, -num * focus.offsetWidth, function() {
flag = true;
});
circle--;
// 排他思想
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
if (circle == -1) {
circle = ol.children.length - 1;
}
ol.children[circle].className = 'current';
}
})
6、创建定时器实现自己滚动
// 自动播放轮播图
var timer = this.setInterval(function() {
// 手动调用点击事件 目标对象.事件类型()
spanRight.click();
}, 1000);
7、当鼠标放到focus时,清除定时器。当鼠标移开focus时,创建定时器。
这一步是在第一步的基础上完成的
// 鼠标经过focus区域,左右两边的按钮显示
focus.addEventListener('mouseenter', function() {
spanLeft.style.display = 'block';
spanRight.style.display = 'block';
// 当鼠标经过focus区域的时候,清除定时器
clearInterval(timer);
timer = null;
});
// 鼠标离开focus区域,左右两边的按钮隐藏
focus.addEventListener('mouseleave', function() {
spanLeft.style.display = 'none';
spanRight.style.display = 'none';
// 离开focus时开启定时器(这里就不用var timer 了,直接给timer赋一个函数即可)
timer = setInterval(function() {
// 手动调用点击事件 目标对象.事件类型()
spanRight.click();
}, 2000)
});
8、让几个步骤联系起来
// 当我们点击了某个li时,就把这个li的索引值index给num
// 让点击的小圆圈和点击左右按钮移动图片联系起来
//不然,如果点击第三个小圆圈,下面的小圆点到第三个,再点击右按钮,
// 他又会按照点击右按钮的算法,给num赋值为2,让小圆点到第二个上去
num = index;
// 当我们点击了某个li时,就把这个li的索引值index给circle
// 让点击的小圆圈和点击左右按钮,下面的小圆点也跟着动联系起来
circle = index;
// 注意ul没有position:absolute;就不能移动,原理就是靠改变绝对定位的值来改变位置的