直接上代码
<!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>
</head>
<style>
.box {
width: 500px;
height: 400px;
border: 1px solid red;
margin: auto;
}
.out {
overflow: hidden;
position: relative;
}
.inner {
width: 2500px;
}
img {
width: 500px;
height: 400px;
display: block;
float: left;
}
</style>
<body>
<div class="box">
<div class="out">
<div class="inner">
<img src="./images/01.jpg" alt="">
<img src="./images/02.jpg" alt="">
<img src="./images/03.jpg" alt="">
<img src="./images/04.jpg" alt="">
<img src="./images/01.jpg" alt="">
</div>
</div>
</div>
<!-- <button>停止</button> -->
</body>
<script>
var out = document.querySelector('.out');
var num = 0;
autoFn()
function move(start, end) {
var startStep = 0;
var endStep = 10;
var speed = (end - start) / endStep;
// console.log(start);
// console.log(end);
var timer1 = setInterval(function() {
out.scrollLeft += speed;
console.log(num);
console.log(out.scrollLeft);
if (out.scrollLeft == out.clientWidth * num) {
clearInterval(timer1)
}
}, 100)
}
function autoFn() {
var timer2 = setInterval(function() {
num++;
if (num == 5) {
num = 1;
out.scrollLeft = 0;
}
move(out.scrollLeft, out.clientWidth * num)
console.log(out.scrollLeft);
}, 2000)
}
</script>
</html>
此方法在我自己版本的谷歌浏览器中可以使用,不同版本的谷歌浏览器可能有差异,但是在QQ浏览器中是不适用的,原因是浮点型小数的精确度问题,以前经常疑惑精确度差异今天打印了一下,终于知道问题出现在哪里了。
仔细观察,我在这里打印了一下num和外部盒子scrollLeft的值,这里是没有什么问题的,没有精确度的问题,在下面if判断里面用全等是可以的,但是在QQ浏览器中:
在QQ浏览器中出现了浮点型小数的精确度的问题,导致轮播图不能轮播,改下if判断条件,在timer1中的判断条件改为:
if (out.scrollLeft >= out.clientWidth * num) {
clearInterval(timer1)
}
自动轮播效果可以实现了,但是又出现了另一个问题:
就是在每一个图片播放完成之后,后面的那一张图片会露出一些,
function move(start, end) {
var startStep = 0;
var endStep = 10;
var speed = (end - start) / endStep;
// console.log(start);
// console.log(end);
var timer1 = setInterval(function() {
out.scrollLeft += speed;
// console.log(num);
console.log(out.scrollLeft);
console.log(out.clientWidth * num);
if (out.scrollLeft >= out.clientWidth * num - 1) {
//1s走500,(图片宽度为500),100ms走50,在QQ浏览器中,通过打印可以知道当out.scrollLeft等于495.多的时候,就应该清除计时器,但实际上由于浮点小数精确度的问题,导致又走了5的长度,才清楚计时器,
// 这样就多走了5长度,需要减去,可见通过走多远的方式计算比较麻烦需要考虑很多,所以采用更简便的方法,用走了多少步来判断,给定一个初始步数为0,给定一个结束步数,结束步数的设置取决于你想要多少步走完一张图片,
// 每次调用计时器的时候,总是让初始步数加1,当初时步数等于结束步数的时候清除定时器,达到停顿的效果。
clearInterval(timer1)
}
}, 100)
}
轮播图成品:
<!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>
</head>
<style>
.box {
position: relative;
width: 500px;
height: 400px;
border: 1px solid red;
margin: auto;
}
.out {
overflow: hidden;
position: relative;
}
.inner {
width: 2500px;
}
img {
width: 500px;
height: 400px;
display: block;
float: left;
}
.previous,
.next {
position: absolute;
width: 40px;
height: 40px;
background-color: wheat;
line-height: 40px;
text-align: center;
top: 180px;
}
.next {
right: 0;
}
dl {
position: absolute;
bottom: 10px;
}
dt {
float: left;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
border: 1px solid red;
cursor: pointer;
}
.current {
background-color: red;
}
</style>
<body>
<div class="box">
<div class="out">
<div class="inner">
<img src="./images/01.jpg" alt="">
<img src="./images/02.jpg" alt="">
<img src="./images/03.jpg" alt="">
<img src="./images/04.jpg" alt="">
<img src="./images/01.jpg" alt="">
</div>
</div>
<div class="previous"><</div>
<div class="next">></div>
<dl>
<dt class="current">1</dt>
<dt>2</dt>
<dt>3</dt>
<dt>4</dt>
</dl>
</div>
<button>停止</button>
</body>
<script>
var out = document.querySelector('.out');
var img = document.querySelector('.inner').querySelectorAll('img');
var btn = document.querySelector('button');
var previous = document.querySelector('.previous');
var next = document.querySelector('.next');
var dtList = document.querySelector('dl').querySelectorAll('dt');
var num = 0;
var startStep
delayTime();
//开始轮播
function move(start, end) {
startStep = 0;
var endStep = 10;
var speed = (end - start) / endStep;
timer1 = setInterval(function() {
startStep++
out.scrollLeft = Math.ceil(out.scrollLeft) //通过打印out.scrollLeft可知,每过1ms,误差就增加一些长度,导致最后轮播图中每个图片都会多走一些长度,
// 把out.scrollLeft向上取整,就会每个1ms,让误差在1个单位之内
out.scrollLeft += speed;
if (startStep == endStep) {
clearInterval(timer1)
// next.onclick = function() {
// console.log(111); //在这里if判断条件不起作用,只要点击next按钮,就会打印111???????
// }
}
}, 100)
}
function autoFn() {
num++
if (num == img.length) {
num = 1;
out.scrollLeft = 0;
}
move(out.scrollLeft, out.clientWidth * num)
changeColor()
}
function delayTime() {
timer2 = setInterval(autoFn, 2000)
btn.addEventListener('click', function() {
clearInterval(timer2)
})
}
//轮播图向右点击
// if(out.scrollLeft == out.clientWidth){
// // next.onclick = function() {
// // console.log(111); //在这里if判断条件不起作用,只要点击next按钮,就会打印111????????
// // }
// }
next.addEventListener('click', function() {
clearInterval(timer2);
autoFn();
delayTime();
})
//轮播图向左点击
previous.addEventListener('click', function() {
num--;
clearInterval(timer2);
if (num < 0) {
num = 3;
out.scrollLeft = out.clientWidth * num
}
move(out.scrollLeft, out.clientWidth * num)
delayTime();
console.log(num);
})
//最下方四个下标
for (let i = 0; i < dtList.length; i++) {
dtList[i].onclick = function() {
for (var j = 0; j < dtList.length; j++) {
dtList[j].className = ''
}
this.className = 'current'
clearInterval(timer2)
num = i;
console.log(num);
move(out.scrollLeft, out.clientWidth * num)
}
}
function changeColor() {
for (var i = 0; i < img.length - 1; i++) {
dtList[i].className = '';
}
var j = num;
if (j == img.length - 1) {
j = 0
}
dtList[j].className = 'current'
console.log(j);
}
</script>
</html>
基本功能已经可以实现,可以重复轮播,但是还有一些问题需要完善。。。。