之前我们做了一个简陋效果的轮播图,但是他有很多BUG,所以这次我们来改进一下,
首先,就是各种功能的封装,将轮播图里的各种功能封装分离,不但便于维护,还有助于我们理清思路,并且让我们更加深刻的了解什么是面向对象:
在做一个轮播图的时候会分为这几个步骤:
1. 获取元素,通过DOM获取到HTML元素,记住,获取到的元素是对象
2. 获取元素的css属性,通过获取元素的css样式来获得它的初始参数,获取得到的css样式同样也是对象
3. 通过js操作css样式从而使元素改变位置,轮播,最基础的就是元素位置的改变,从而使其中图片变换
4. 添加动画效果,通过js添加的动画效果拥有更好的兼容性和灵活性,
通过以上几个步骤,是不是觉得轮播图瞬间容易了不少?其实DOM都是这几步:先获取,再操作,将其中的功能分离出来逐个击破,
1. 获取元素:
获取元素的方法有很多:
通过id获取:document.getElementById();
通过标签名获取:document.getElementsByTagName();
通过类名获取:document.getElementsByClassName();
这些方法各有优缺点,我选择了下面的这种方法:
document.querySelectorAll()
//获取元素节点对象
//获取到的是一个类数组函数,所以使用时要进行遍历
function $(selector){//css选择器
return document.querySelectorAll(selector);
}
2. 获取css样式:为了更方便的使用,我选择获取内联或外部样式,用以下方法:
getComputedStyle()
是现在常用的方法,它的作用是一个元素的style属性,注意,style属性也是一个对象
这个函数在IE8中不兼容,所以对IE8需要使用currentStyle
方法
为了方便,直接将其写成一个兼容函数让他自动判断
//获取一个元素的css内联或外部样式
function getStyle(el,attr){//元素节点对象,样式名
if (typeof getComputedStyle == "undefined") {
return el.currentStyle[attr];
}else{
return getComputedStyle(el,null)[attr];
}
}
3.操作样式,添加动画:这个是最复杂的功能,我在这里需配合着获取css样式的getStyle()函数使用
现在最新的设置js动画的方法,不在用一个值叠加距离,而是通过动画运动的时间和路程,直接将元素放在每一刻它应该在的位置
得到起始位置b
得到运动次数d
设置当前次数t
得到总路程c
结果就是每一刻元素应该在c/d*t+b的位置上
这种方法计算得出的动画效果更好,且规避了一些用距离叠加的方法产生的问题
//设置动画效果
function animate(el,option,allTime,callback){//元素节点对象,要设置的样式的对象集合,过渡时间,执行完毕后要执行的函数
//得到起始位置
var start = {};
for(var attr in option){
start[attr] = parseInt(getStyle(el,attr));
}
var d = parseInt(allTime/17);//得到运动次数
var t = 0;//得到当前次数
clearInterval(el.time);
el.time = setInterval(function(){
t++;
for(var attr in option){
var b = start[attr];
var c = option[attr] - b;//得到总路程
if (t > d) {
clearInterval(el.time);
callback?callback():null;
}else{
el.style[attr] = c/d*t+b+"px";
}
}
},17)
}
这个功能不止可以移动元素,之前说过,js动画的特点就是灵活,所以这个函数可以做很多事情,如:
改变位置:animate(obj,{left:400,top:300},300)
:将obj在0.3秒内移动到left为400px,top为300px的位置
改变大小:animate(obj,{height:400},300)
:将obj的高度在0.3秒内增加或减小到400px
以上三个功能都做好并理解之后,就可以思考怎样做轮播图了,
完成轮播图:
看十遍不如做一遍,将相应代码复制到编辑器中试一下,了解各行代码功能后再试着自己写一遍看看
我设置的HTML页面:
注意:类名和css样式一定要一致,
1
2
3
我设置的内联css样式:
注意:将其放在style标签中或者放在外部引用
.box{
width: 400px;height: 200px;position: relative;
border: 2px solid #000;box-shadow: 0px 0px 5px red;
margin: 100px auto;
}
.lise{
width: 1200px;height: 100%;position: absolute;top: 0px;
}
.img{
width: 400px;height: 200px;float: left;
color: #fff;text-align: center;font-size: 50px;line-height: 200px;
}
.btn{
position: absolute;bottom: 10px;left: 50%;transform: translateX(-50%);
}
.item{
width: 15px;height: 15px;display: block;float: left;outline: none;
background: #fff;margin: 0px 10px;border-radius: 50%;
}
.bgcolor{
background: #999;
}
.btn1{
width: 40px;height: 100px;background: rgba(0,0,0,0.5);position: absolute;
color: #fff;top: 50%;transform: translateY(-50%);outline: none;
}
.onLeft{
left: 0px;
}
.onRigth{
right:0px;
}
用来设置轮播图的JS代码:
注意:JS代码应该写在script标签中,上面写好的三个功能记得添加进来,如果写在外部,记得引用进来,引用的script标签一定要写在轮播图的script标签前面
具体的各行代码的介绍都在注释里,为了简化代码所以将重复的代码放在函数中调用,如果不明白可以将其重新放入函数调用的位置测试,
var item = $(".item"),box = $(".box"),lise = $(".lise"),onLeft = $(".onLeft"),onRight = $(".onRigth");
//自动轮播
var time = setInterval(next,3000);
box[0].onmouseover = function(){//鼠标进入
clearInterval(time);//关闭定时器
};
box[0].onmouseout = function(){//鼠标移出
time = setInterval(next,3000);//重新开启定时器
};
//div的动画
num = 0;//用来判断是第几张图
onLeft[0].onclick = function () {//点击向左
num = num<=0?2:--num;
move();//调用下面的move函数
};
onRight[0].onclick = function () {//点击向右
num = num>=2?0:++num;
move();
};
for (var i = 0; i < item.length; i++) {//点击小圆点
item[i].index = i;
item[i].onclick = function (){
num = this.index;//为了保证深色小圆点是当前图片,将下标给num
move();
};
}
function next(){
num = num>=2?0:++num;
move();
}
function move(){//将各事件中重复的代码放在一个函数中以供调用
for(var j = 0;j