最近参加XX培训公司去培训前端开发,到目前为止已经将近两个月,学了html,css,js,jquery,其中的UI部分被我先行跳过了。学完js给后了一个广告轮播的小项目来练手实现。再到学完jquery后又选择用原来的广告轮播小项目用jquery再实现一次。然后,我就发现了一个非常严重的问题。
因为用原生js实现广告轮播时,是老师带着我们,讲思路,讲代码,几乎是老师手把手教着写的,而在做完这个项目之后,我一直没有进行总结复习,到后来要自己用jquery再实现一遍的时候就两眼一黑,脑中只有残章断片,只记得其中几个小细节的实现,而没法串联起来,甚至连刚开始该如何起步的思路都没了。这也就萌发了我去写博客记录下来的想法,不只是对原来所写的总结和复习,更为以后的回忆和重新拾起做一些保障。
首先,先将实现广告轮播的思路整理一下。
二,广告轮播思路整理
1, 原理
广告的轮播,其实是一个横着存放着数个图片的div左右位移的效果,如下图(略微草率)
而通过把div设置成绝对定位,改变其left即可。
在实现过程中,其实是通过在JS中先将多个图片存放在一个数组中,然后通过操纵数组,再将
数组刷新到页面的方式来改变页面,而所看到的轮播效果,是通过进行div左右位移的动画实现的。
动画效果的实现,JS是通过设置定时器的方式,jQuery是用的万能动画函数
另外,左移和右移时,对图片数组的操作是不同的。
左移时,先进行动画效果展示,然后在数组中将左移出来的图片补到数组的最后,同时重置div的left为0;
最后将图片数组刷到页面上
右移时,先在数组中找到要显示图片,将其与其后的图片(共n个)先补到数组最前面,
然后设置div的left为-n*(单个图片的宽),后再进行动画效果展示,最后将图片数组刷到页面。
2, 广告轮播中的图片放在"#imgs"的ul中,
图片在JS中先用一个数组存储起来,然后用方法将图片刷到ul中去。
例如:
var imgs=[
{"i":0,"img":"images/index/banner_01.jpg"},
{"i":1,"img":"images/index/banner_02.jpg"},
{"i":2,"img":"images/index/banner_03.jpg"},
{"i":3,"img":"images/index/banner_04.jpg"},
{"i":4,"img":"images/index/banner_05.jpg"}
];
HTML代码以及css代码部分(因为重点是在于js的实现,所以只将相关的html和css代码交代出来)
<!DOCTYPE HTML>
<html>
<head>
<title>广告轮播</title>
</head>
<style> <!--样式部分,只引入,js效果中需要用到的-->
#slider #imgs {
position:absolute;
top: 0; left: 0;
height:240px;
}
#slider #imgs li{
float:left;
z-index:0;
}
#slider #indexs li:hover,#slider #indexs li.hover {
background:#b61b1f;
}
</style>
<body>
<div id="slider"> <!--总div包住-->
<ul id="imgs"> <!--存放多张图片-->
</ul>
<ul id="indexs"><!--点击小圆点,广告跳转效果-->
</ul>
<script src="lunbo.js"></script>
<script src="js/jquery-1.11.3.js"></script><!--当用jquery实现时引入-->
</div>
/*封装$*/
window.$=HTMLElement.prototype.$=function(selector){
var elems=(this==window?document:this)
.querySelectorAll(selector);
return elems.length==0?null:elems.length==1?elems[0]:elems;
}
/*广告图片数组*/
var imgs=[
{"i":0,"img":"images/index/banner_01.jpg"},
{"i":1,"img":"images/index/banner_02.jpg"},
{"i":2,"img":"images/index/banner_03.jpg"},
{"i":3,"img":"images/index/banner_04.jpg"},
{"i":4,"img":"images/index/banner_05.jpg"},
];
var adv={
liWidth:670,//每个广告图片的宽度
duration:5000,//动画总时长
wait:3000,//自动轮播之间等待时长
timer:null,//保存当前正在播放的定时器序号
steps:100,//动画移动的步数
canAuto:true,//设置是否可以自动轮播
init:function(){
var self=this;
/*当*/
self.updateView();
$("#slider").addEventListener("mouseover",function(){
self.canAuto=false;
},false);
$("#slider").addEventListener("mouseout",function(){
self.canAuto=true;
//self.autoMove();
},false);
self.autoMove();//初始化时,启动自动轮播
/*为圆点加点击事件*/
$("#indexs").addEventListener("mouseover",function(){
var e=window.event||arguments[0];
var target=e.srcElement||e.target;
if(target.nodeName=="LI"){
var oldi=$("#indexs>.hover").innerHTML;
if(target.innerHTML-1!=imgs[0].i){
$("#indexs>.hover").className="";
target.className="hover";
self.move(target.innerHTML-oldi);
}
}
},false);
},
//移动前后刷新页面
updateView:function(){
//计算ul的总宽度
var ulWidth=this.liWidth*imgs.length+"px";
//遍历imgs中每个对象,并声明lis空数组和dian小圆点空数组,//
var lis=[],dian=[];
for(var i=0,len=imgs.length;i<len;i++){
//在lis中当前位置添加新元素:<li data-i="当前i">
// <img src=""> </li>
lis.push("<li data-i='"+imgs[i].i+"'> <img src='"+
imgs[i].img+"'> </li>");
//加上小圆点
dian[i]="<li>"+(i+1)+"</li>";
}
//(遍历结束后)将lis刷到ul #imgs下,dian刷到index下
$("#imgs").innerHTML=lis.join("");
$("#indexs").innerHTML=dian.join("");
//将小圆点的样式与imgs【0】.i相对应
//找到小圆点为hover,清楚其hover
if($("#indexs>.hover"))
$("#indexs>.hover").className="";
//找到下标为imgs【0】.i的li,设为hover
$("#indexs>li")[imgs[0].i].className="hover";
},
/*ul移动*/
moveStep:function(n){ //n是移动个数,向左为正,向右为负
var self=this;
//计算动画中移动一小步的步长
var step=self.liWidth*n/self.steps;
//找到ul #imgs的style,设置其left=left-step;
var style=getComputedStyle($("#imgs"));
var left=parseFloat(style.left)-step;
$("#imgs").style.left=left+"px";
//n>0&&left>-liWidth*n 或 n<0&&left<0; 就启动下一次一次性定时器
if((n>0&&left>-self.liWidth*n)||(n<0&&left<0)){
self.timer=setTimeout(function(){
self.moveStep(n);
},self.duration/self.steps);
}else{
//否则,及移动完后,将ul的left重置为0,
$("#imgs").style.left=0+"px";
//再次启动自动轮播
self.autoMove();
// n>0,及左移,则从0开始删除原imgs数组中n个,
// 删除结果直接拼接到imgs,刷新页面
if(n>0){
imgs=imgs.slice(n).concat(imgs.slice(0,n));
self.updateView();
}
}
},
/*启动移动,移动任意个li的方法(手动轮播)*/
move:function(n){ //n是移动个数,向左为正,向右为负
var self=this;
//停止正运行的timer动画,将timer释放
clearTimeout(self.timer);
self.timer=null;
//调用moveStep(),传递n
if (n<0) { //右移动
//将imgs数组的-n个元素删除,并拼接到imgs的前面,刷新页面
imgs=imgs.splice(imgs.length+n).concat(imgs);
this.updateView();
//将ul 的left设置为liWidth*(n)
$("#imgs").style.left=n*self.liWidth+"px";
}
self.moveStep(n);
},
/*自动轮播*/
autoMove:function(){
//留住this
var self=this;
//启动一次性定时器,传入匿名函数封装的move方法,
self.timer=setTimeout(function(){
(self.canAuto==true)?self.move(1):self.autoMove();
},self.wait);
//在move方法中传参数1,设置时间间隔为wait
},
}
adv.init();
// /*封装$*/
// window.$=HTMLElement.prototype.$=function(selector){
// var elems=(this==window?document:this)
// .querySelectorAll(selector);
// return elems.length==0?null:elems.length==1?elems[0]:elems;
// }
/*广告图片数组*/
var imgs=[
{"i":0,"img":"images/index/banner_01.jpg"},
{"i":1,"img":"images/index/banner_02.jpg"},
{"i":2,"img":"images/index/banner_03.jpg"},
{"i":3,"img":"images/index/banner_04.jpg"},
{"i":4,"img":"images/index/banner_05.jpg"},
];
var slider={
liWidth:0, //li图片的宽度
Duration:1000,//动画总时长
timer:null,//定时器
Interval:2000,//间隔时间
auto:true,//是否可以自动轮播
init:function(){
this.liWidth=parseFloat($("#slider").css("width"));
this.updateImg();
// this.autoShow();//自动轮播
$("#indexs").on("mouseover","li:not(.hover)",
function(e){
var $ta=$(e.target);
this.move($ta.html()-$ta.siblings(".hover").html());
}.bind(this)
); //手动轮播
$("#slider").hover( //改变能否自动轮播的状态,用于判断自动轮播的进行
function(){this.auto=false; }.bind(this),
function(){this.auto=true; }.bind(this)
);
this.autoShow();//自动轮播
},
updateImg:function(){ //刷新页面
for(var i=0,html="",html2="";i<imgs.length;i++){
html+="<li><img src='"+imgs[i].img+"'></li>";
html2+="<li>"+(i+1)+"</li>";
}
$("#imgs").html(html).css("width",this.liWidth*imgs.length);
$("#indexs").html(html2);
$("#indexs>li:eq("+imgs[0].i+")").attr("class","hover");
},
move:function(n){ //左右位移
clearTimeout(this.timer);
this.timer=null;
$("#imgs").stop();//停止动画,防止叠加
var left=parseFloat($("#imgs").css("left"));
if(n>0){ //ul左移
$("#imgs").animate({left:left-n*this.liWidth+"px"},
this.Duration,this.endMove.bind(this,
n));
}
if(n<0){//ul右移
imgs=imgs.splice(imgs.length+n).concat(imgs);
$("#imgs").css("left",left+n*this.liWidth+"px");
$("#imgs").animate({left:left},this.Duration,this.autoShow.bind(this));
this.updateImg();
}
},
endMove:function(n){ //位移结束后的页面刷新,启动轮播
$("#imgs").css("left",0);
imgs=imgs.concat(imgs.splice(0,n));
this.updateImg();
this.autoShow();
},
autoShow:function(){
this.timer=setTimeout((this.auto==true)?this.move.bind(this,1)
:this.autoShow ,this.Interval);
}
}
slider.init();