<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style type="text/css">
#box{height:300px;width:500px;border:solid 10px red;position: relative;margin:20px auto;overflow:hidden;}
#box .imgbox{position:absolute;left:0;top:0;}
.imgbox a{display:block;height:300px;width:500px;float:left;}
.imgbox a img{height:300px;width:500px;}
.btns input{height:30px;width:30px;border:none;background:rgba(200,100,100,0.5);z-index:1;position:absolute;top:135px;}
.btns .left{left:0;}
.btns .right{right:0}
</style>
// 引入外部的js文件
<script src="../move.js"></script>
<body>
<div id="box">
<div class="imgbox">
<a href=""><img src="https://aecpm.alicdn.com/simba/img/TB1JNHwKFXXXXafXVXXSutbFXXX.jpg" alt=""></a>
<a href=""><img src="https://img.alicdn.com/tfs/TB1410CwEz1gK0jSZLeXXb9kVXa-520-280.jpg_q90_.webp" alt=""></a>
<a href=""><img src="https://aecpm.alicdn.com/simba/img/TB1XotJXQfb_uJkSnhJSuvdDVXa.jpg" alt=""></a>
<a href=""><img src="https://img.alicdn.com/tfs/TB1zuTbwa61gK0jSZFlXXXDKFXa-520-280.jpg_q90_.webp" alt=""></a>
// 最后重复使用第一张图片放在所有图片的最后,使轮播图能够达到无缝衔接的效果
<a href=""><img src="https://aecpm.alicdn.com/simba/img/TB1JNHwKFXXXXafXVXXSutbFXXX.jpg" alt=""></a>
</div>
<div class="btns">
<input type="text" class="left"value = "<<<">
<input type="text" class="right" value=">>>">
</div>
</div>
</body>
<script type="text/javascript">
// 轮播图的分析:
// 1.选择元素(属性)
// 2.完善布局(方法)
// 3.绑定事件(方法)
// 4.设置索引(方法)
function Lun(){
// 1.保存属性
this.oImgBox = document.querySelector("#box .imgbox");
this.oA = document.querySelectorAll(".imgbox a");
this.oLeft = document.querySelector(".left");
this.oRight = document.querySelector(".right");
}
// 原型部分:
// 1.完善布局
// var index = 0;
Lun.prototype.Perfect =function(){
//宽度自适应:父元素的宽度 = 子元素的个数 * 某个子元素的宽度
this.oImgBox.style.width = this.oA.length * this.oA[0].offsetWidth + "px";
}
// 2.绑定事件
Lun.prototype.addEvent = function(){
// 在this指向lun时,提前保存,以便下面使用
var that = this;
//4. 拿到索引
var i = that.Index();
this.oLeft.onclick = function(){
//点击左按钮时,先判断当前索引的位置,如果索引为0,
if(i == 0){
//将索引直接设为倒数第二张图片的索引
i =that.oA.length-2;
// 同时将图片的父级距离左边的距离设置为 -(总图片数-1)* 某个图片的宽度(此动作在一瞬间完成)
that.oImgBox.style.left = -(that.oA.length-1) * that.oA[0].offsetWidth + "px";
}else{
i--;
}
move(that.oImgBox,"left",-i * that.oA[0].offsetWidth);
}
this.oRight.onclick = function(){
//点击右按钮时,先判断当前索引的位置,如果索引为最后一张图片的索引,
if(i == that.oA.length-1){
//将索引直接设为第二张图片的索引
i = 1;
// 同时将图片的父级距离左边的距离设置为0
that.oImgBox.style.left =0;
}else{
i++;
}
// 引用外部的js添加动画
move(that.oImgBox,"left",-i * that.oA[0].offsetWidth);
}
}
// 3.设置索引
Lun.prototype.Index = function(){
return this.index = 0;
}
var t = new Lun();
t.Perfect();
t.addEvent();
</script>
</html>
外部的js文件
function move(ele,attr,target){
clearInterval(ele.t);
ele.t = setInterval(()=>{
// 透明度的单独处理:透明度的属性值是一个数值,没有px,而且是从0-1
// 结果不用取整,并且为了统一将来的步长计算,先乘100
if(attr == "opacity"){
var iNow = getStyle(ele,attr)*100;
}else{
var iNow = parseInt(getStyle(ele,attr));
}
let speed = (target - iNow)/10;
speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
if(iNow === target){
clearInterval(ele.t);
}else{
// 透明度的单独设置:因为获取的时候为了统一将来的步长计算,先乘100了;所以这里设置时再除100;
if(attr == "opacity"){
ele.style.opacity = (iNow + speed)/100;
}else{
ele.style[attr] = iNow + speed + "px";
}
}
},30);
}
function getStyle(ele,attr){
if(ele.currentStyle){
return ele.currentStyle[attr];
}else{
// 对象的中括号语法:返回属性值,在执行函数时可以拿到
return getComputedStyle(ele,false)[attr];
}
}
// 执行格式:
// move(oBox1,"left",600);