效果
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.content {
width: 400px; /*轮播图的宽度*/
height: 250px; /*轮播图的高度*/
border: 1px solid #ccc;
margin: 100px auto;
/* padding: 10px; */
}
.slideContainer{
width: 400px;
height: 250px;
position: relative;
overflow: hidden;
}
.slideContainer ul {
height: 400px;
width: 250px; /*在js中重新计算 宽度应为其中所有li的宽度之和*/
position: absolute;
list-style: none;
left:0;
top: 0;
}
.slideContainer ul li {
float: left;
width: 400px;
height: 250px;
}
.slideContainer ul li img{
height: 100%;
width: 100%;
}
.bar {
position: absolute;
height: 20px;
bottom: 20px;
left: 0;
right: 0;
text-align: center;
padding: 5px;
}
.bar li{
display: inline-block;
width: 20px;
height: 20px;
border-radius: 10px;
line-height: 20px;
background-color: rgb(141, 143, 146);
cursor: pointer;
}
ol .current{
background-color: white;
}
#change{
display: none;
}
#change span{
width: 40px;
height: 40px;
position: absolute;
left: 5px;
top: 50%;
margin-top: -20px;
background: #fff;
cursor: pointer;
line-height: 40px;
text-align: center;
font-weight: bold;
font-family: '黑体';
font-size: 30px;
color: #000;
opacity: 0.5;
border: 1px solid #fff;
}
#change #right {
right: 5px;
left: auto;
}
</style>
</head>
<body>
<div class="content">
<div class="slideContainer">
<!--轮播图-->
<ul>
<li><a href="#"><img src="images/1.jpg" alt=""></a></li>
<li><a href="#"><img src="images/2.jpg" alt=""></a></li>
<li><a href="#"><img src="images/3.jpg" alt=""></a></li>
<li><a href="#"><img src="images/4.jpg" alt=""></a></li>
</ul>
<ol class="bar">
<li index="1">1</li>
<li index="2">2</li>
<li index="3">3</li>
<li index="4">4</li>
</ol>
<!--左右焦点-->
<div id="change">
<span id="left">
<
</span>
<span id="right">
>
</span>
</div>
</div>
</div>
<script>
/* 定义一些全局变量 获取dom节点 */
var slideContainer=document.querySelector('.slideContainer');
var imgUlNode=document.querySelector('.slideContainer ul');
// var imgLiNodes = imgUlNode.querySelectorAll('li'); // 这样不行
var imgLiNodes=imgUlNode.children; // 要这样 因为后面会往ul中添加一个li
var buttonOlNode=document.querySelector('.bar');
var buttonLiNodes = document.querySelectorAll('.bar li')
var change=document.querySelector('#change');
// const width = imgLiNodes[0].style.width // 这个只能读写内联样式 所以不行
var imgWidth=slideContainer.offsetWidth;
var right=document.querySelector('#right');
var left=document.querySelector('#left');
var pic=0; // 全局变量 标识当前显示的图片
/* 初始设置 */
buttonOlNode.children[0].className = "current"; // 设置第一个小圆点样式
// 为了实现从最后一张图无缝过渡到第一张图 在最后追加一张第一张图
imgUlNode.appendChild(imgUlNode.children[0].cloneNode(true)); // 克隆一个ul中第一个li,加入到ul中的最后
imgUlNode.style.width = imgLiNodes.length*imgWidth + 'px' // 设置图片容器的宽度
/* 启动轮播图 */
var timeId=setTimeout(onmouseclickHandle,1000);
function onmouseclickHandle() {
clearTimeout(timeId)
// 如果当前在显示最后一张图(实际相当于显示第一张图)需要瞬间(无过渡)切换到第一张图
// 因为第一张图和最后一张图是一样的
if (pic == imgLiNodes.length - 1) {
pic = 0; // 先设置pic=0
imgUlNode.style.transition = ''; // 取消过渡
imgUlNode.style.left = 0 + "px"; // 设置为第一张图
// 这里设置100ms是因为页面的修改是异步的 并不是我们在上面设置了left的值 页面马上就会改变
// 而是会在浏览器下次页面重绘的时候才修改 所以这里设置100ms再进行操作
timeId=setTimeout(onmouseclickHandle, 100);
}
else {
pic++;
imgUlNode.style.transition = 'left 1s' // 其他情况下是有过渡的
imgUlNode.style.left = -pic*imgWidth + 'px'
if (pic == imgLiNodes.length - 1) {
// 小圆点样式设置
buttonLiNodes[buttonLiNodes.length - 1].className = "";
buttonLiNodes[0].className = "current";
timeId=setTimeout(onmouseclickHandle,900); // 注意这里是900ms 900ms+100ms=1000ms
} else {
// 小圆点样式设置
for (var i = 0; i < buttonLiNodes.length; i++) {
buttonLiNodes[i].removeAttribute("class");
}
buttonLiNodes[pic].className = "current";
timeId=setTimeout(onmouseclickHandle,1000);
}
}
}
/* 绑定交互事件 */
// 为小圆点绑定点击事件
for(var i=0;i<buttonLiNodes.length;i++){
//为按钮注册mouseover事件
buttonLiNodes[i].onclick=function () {
//先清除所有按钮的样式
for (var j=0;j<buttonLiNodes.length;j++){
buttonLiNodes[j].removeAttribute("class");
}
this.className="current";
pic=this.getAttribute("index");
imgUlNode.style.left = -pic*imgWidth + 'px'
}
}
// 鼠标移入轮播图暂停轮播
slideContainer.onmouseover=function () {
change.style.display="block";
clearTimeout(timeId);
};
// 鼠标移出轮播图重启轮播
slideContainer.onmouseout=function () {
change.style.display="none";
clearTimeout(timeId)
timeId=setTimeout(onmouseclickHandle, 1000);
};
// 点击右边的bar
right.onclick=onmouseclickHandle;
// 点击左边的bar
left.onclick=function () {
if (pic==0){
pic=imgLiNodes.length-1;
imgUlNode.style.left=-pic*imgWidth+"px";
}
pic--;
imgUlNode.style.left = -pic*imgWidth + 'px'
for (var i = 0; i < buttonOlNode.children.length; i++) {
buttonOlNode.children[i].removeAttribute("class");
}
buttonOlNode.children[pic].className = "current";
};
</script>
</body>
</html>
关键部分
使用setTimeout来对left值进行修改,然后在回调函数中又启动另一次的setTimeout。
并且配合css3的过渡实现滑动的效果。只需要注意怎么从最后一张图片滑到第一张,方案是将第一张图片拷贝一个结点放到最后。
还需要通过js修改样式后,实际不是马上更新的,而是再下一次重绘的时机做的更新,页面重绘的频率一般可以认为是60ms。