<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul,
li {
list-style: none;
}
#box {
width: 600px;
height: 400px;
overflow: hidden;
border: 10px solid #ccc;
margin: 50px auto;
position: relative;
}
#box ul {
width: 10000px;
height: 400px;
left: 0;
top: 0;
position: absolute;
}
#box ul li {
width: 600px;
height: 400px;
float: left;
}
#box ul li img {
width: 100%;
height: 100%;
}
#box p {
width: 100%;
height: 20px;
position: absolute;
left: 0;
bottom: 20px;
text-align: center;
}
#box p span {
display: inline-block;
width: 20px;
height: 20px;
background-color: #333;
border-radius: 50%;
cursor: pointer;
}
#box p span.active {
background-color: red;
}
#box .left,
#box .right {
position: absolute;
width: 45px;
height: 100px;
top: 150px;
background: url('img/sprite.png') no-repeat;
}
#box .left {
left: 0;
}
#box .right {
right: 0;
background-position: -45px 0;
}
</style>
</head>
<body>
<div id="box">
<ul>
<li><img src="img/t1.png" alt=""></li>
<li><img src="img/t2.png" alt=""></li>
<li><img src="img/t3.png" alt=""></li>
</ul>
<a href="javascript:;" class="left"></a>
<a href="javascript:;" class="right"></a>
<p>
<span class="active"></span>
<span></span>
<span></span>
</p>
</div>
<script src="js/move.js"></script>
<script>
var box = document.getElementById('box');
var ul = document.querySelector('ul');
var li = ul.querySelectorAll('li');
var left = box.querySelector('.left');
var right = box.querySelector('.right');
var span = box.querySelectorAll('span');
// console.log(box,ul,li,left,right,span);
// 无缝轮播:将第一张图赋值一份,添加到最后
ul.appendChild(li[0].cloneNode(true));
var imgW = li[0].clientWidth; // 一张图的宽度
// 给ul设置宽度,一张图的宽度乘以图片数量,图片数量=li的长度
ul.style.width = imgW * (li.length + 1) + 'px';
var count = 0; // 当前展示的是下标为0的这张图
var timer = null; // 设置定时器为空
// 实现步骤:
// 先设置定时器,2秒执行一次,通过count++的改变,使用move(change)函数,改变ul的left值,如果count大于li的长度-1,则立即把count的值改为0,重新回到第一张图
// 一打开就执行定时器
timer = setInterval(auto, 2000);
// 划上box停止定时器
box.onmouseover = function () {
clearInterval(timer);
}
// 划离box重新开启
box.onmouseout = function () {
timer = setInterval(auto, 2000);
}
// right下一张
right.onclick = auto;
// left上一张
left.onclick = function () {
if (count <= 0) {
count = li.length;
ul.style.left = -imgW * count +'px';
}
count--;
change();
}
// 划上分页小按钮
for (var i = 0; i < span.length; i++) {
// 给span第i个自定义index属性并赋值i
span[i].index = i;
span[i].onmouseover = function () {
count = this.index;
change();
}
}
function auto() {
// 无缝轮播的关键是,先判断,再加加
// 如果count等于li的长度,也就是最后一张图的时候,count赋值为0,并且立即改变ul的left值为0,就会回到第一张图的位置
if (count >= li.length) {
count = 0;
ul.style.left = 0;
}
count++;
change();
}
function change() {
move(ul, { left: -imgW * count });
// 图片轮播,改变span的className,count就是第span[i]个
for (var i = 0; i < span.length; i++) {
// 先把span的className清空
span[i].className = '';
}
// 判断count,在给span赋值
if (count >= li.length) {
span[0].className = 'active';
} else {
span[count].className = 'active';
}
}
</script>
</body>
</html>
function getStyle(ele, attr) {
if (window.getComputedStyle) {
// 标准浏览器
return getComputedStyle(ele)[attr];
} else {
// IE8及以下
return ele.currentStyle[attr];
}
}
// 元素 属性 目标 回调
function move(ele, json, callback) {
clearInterval(ele.timer); // 先清
// 再开
ele.timer = setInterval(function () {
var onOff = true; // 建一个开关
// 在for-in的里面,如果某一个属性没有到,则把开关变为假
for (var attr in json) { // 删掉的attr和target又回来了
var target = json[attr];
// 当前位置
if (attr === 'opacity') {
var now = getStyle(ele, 'opacity') * 100;
} else {
var now = parseInt(getStyle(ele, attr));
}
var dir = (target - now) / 10; // 方向 缓冲运动
// 如果大于0,向上取整,否则向下取整
dir = dir > 0 ? Math.ceil(dir) : Math.floor(dir);
now += dir; // 下次应该运动到的位置
if ((now >= target && dir > 0) || (now <= target) && dir < 0) {
now = target;
}
// 设置值
if (attr === 'opacity') {
ele.style.opacity = now / 100;
ele.style.filter = 'alpha(opacity=' + now + ')';
} else {
ele.style[attr] = now + 'px';
}
if (now !== target) {
onOff = false;
}
}
if (onOff) { // 如果开关是真的,则清定时器并执行回调
clearInterval(ele.timer);
callback && callback();
}
}, 30);
}