通过学习,我理解了图片轮播原理,学习了setTimeout()、setInterval()函数设置定时器与清除定时器clearInterval()函数,使用函数递归实现图片滑动切换,采用辅助图片实现图片无限滚动等编程技巧。
一、焦点图轮播特效之原理
这个焦点图轮播特效将运用到了平时学习中的知识,例如,DOM操作、定时器、事件处理、JS动画、函数递归还有无线滚动等等。
其实焦点图轮播特效的原理十分简单,就是通过控制存放图片的列表里面的left值来显示图片。
HTML结构大致分为以下部分:
<div id="container">
<div id="list" style="left:-600px;">
![](img\5.jpg)
![](img\1.jpg)
![](img\2.jpg)
![](img\3.jpg)
![](img\4.jpg)
![](img\5.jpg)
![](img\1.jpg)
</div>
<div id="buttons">
<span index="1" class="on"></span>
<span index="2"></span>
<span index="3"></span>
<span index="4"></span>
<span index="5"></span>
</div>
<a href="javascript:;" id="prev" class="arrow"><</a><!--javascript:是一个伪协议,是表示在触发<a>默认动作时,执行一段javascript代码,而javascript:;表示什么都不执行,这样点击<a>标签没有任何反应-->
<a href="javascript:;" id="next" class="arrow">></a>
</div>
- 一个父容器container,父容器里面有一个图片列表list还有一个按钮buttons,再加上两个代表左右箭头的a标签;
- javascript: 是一个伪协议,是是表示在触发a标签默认动作时,执行一段javascript代码,而javascript:;表示什么都不执行,这样点击a标签没有任何反应;
- 为了实现无限滚动,在第一张图片之前加入第五张图片的附属图,在第五张图片之后加入第一张图片的附属图,实得在滚动的过程中,不会出现延迟现象;
二、焦点图轮播特效之样式布局
具体的CSS代码如下:
<style>
*{
margin:0;
padding:0;
text-decoration:none;
}
body{
padding:20px;
}
#container{
width:600px;
height:400px;
border:3px solid #333;
overflow:hidden;
position:relative;
}
#list{
width:4200px;
height:400px;
position:absolute;
z-index:1;
}
#list img{
float:left;
}
#buttons{
position:absolute;
height:10px;
width:100px;
bottom:20px;
left:250px;
z-index:2;
}
#buttons span{
cursor:pointer;
float:left;
border:1px solid #fff;
width:10px;
height:10px;
border-radius:50%;
background:#333;
margin-right:5px;
}
#buttons .on{
background:orangered;
}
.arrow{
cursor:pointer;
display:none;
line-height:39px;
text-align:center;
font-size:36px;
font-weight:bold;
width:40px;
height:40px;
position:absolute;
z-index:2;
top:180px;
background-color:RGBA(0,0,0,.3);
color:#fff;
}
.arrow:hover{
background-color:RGBA(0,0,0,.7);
}
#container:hover .arrow{
display:block;
}
#prev{
left:20px;
}
#next{
right:20px;
}
</style>
- 其中将父容器里面的overflow属性设置为:hidden,并且将position设置为:relative,因为子元素list和buttons都是相对于父容器来定位的;
- 其中里面涉及到了z-index属性:设置元素的堆叠顺序。元素可拥有负的z-index属性值,z-index仅仅能在定位元素上奏效,拥有更高层叠顺序的元素总是位于更低元素的前面;
三、焦点图轮播特效之箭头切换
接下来就进入JS部分的编写,首先必须是页面加载完毕才能执行相关的JS代码,所以必须写在window.onload = function(){}中,接下来先取得相关的容器和标签,如下:
window.onload = function(){
var container = document.getElementById("container");
var list = document.getElementById("list");
var buttons = document.getElementById("buttons").getElementsByTagName("span");
var prev = document.getElementById("prev");
var next = document.getElementById("next");
}
然后要做到点击箭头就能切换,就必须给箭头元素绑定一个点击事件,通过点击箭头,来改变list里面style属性中的left值,从而实现图片的切换
prev.onclick = function(){
list.style.left = parseInt(list.style.left) - 600 + 'px';
}
next.onclick = function(){
list.style.left = parseInt(list.style.left) + 600 + 'px';
}
因为两个点击事件里面的语句十分相似,所以就将它们封装在一个名为animate()的函数中,只需要传进一个偏移量就可以了,如下
function animate(offset) {
list.style.left = parseInt(list.style.left) + offset + 'px';
}
prev.onclick = function(){
animate(-600);
}
next.onclick = function(){
animate(600);
}
四、焦点图轮播特效之无限滚动
在上一节,我们已经实现了箭头的切换,但是会有一个问题,当切换到最左边,或者最右边时,会出现空白页,因为当滚动到第五张图片的附属图时,此时的left值为0,当继续往左切换时,就会大于0,当滚动到第一张图片的附属图时,此时的left值为-4200,当继续往右切换时,就会小于-4200,所以会出现空白现象;我们要达到的效果是,当滚动到第一张图片的附属图时,此时将它的left值设置回-600,当滚动到第五张图片的附属图时,将left值设置回-3000,才能达到无限滚动的效果,具体代码如下:
function animate(offset) {
var newLeft = parseInt(list.style.left) + offset;
list.style.left = newLeft + 'px';
if(newLeft > -600) {
list.style.left = -3000 + 'px';
}
if(newLeft < -3000) {
list.style.left = -600 + 'px';
}
}
此时就可以实现无限滚动的效果了,这个时候,我们还需要加上小圆点的切换功能,这时候我们需要再引进一个变量index,来显示当前显示的是第几张图片,初始值为1;并且增加一个函数专门来亮起小圆点,如下:
function showButtons(){
buttons[index-1].className = "on";
}
每点击一下左箭头,index的值就要减1,每点击一下右箭头,index的值就加1,如下:
prev.onclick = function(){
index -= 1;
showButtons();
animate(-600);
}
next.onclick = function(){
index += 1;
showButtons();
animate(600);
}
但是这个时候会发现,以前的按钮没有关闭,而是全都亮了起来,此时就要改进一下showButtons()函数,在亮起当前按钮的同时,将之前的按钮至灰色,代码如下:
function showButtons(){
for(var i = 0; i < buttons.length; i++) {
if(buttons[i].className == "on") {
buttons[i].className = "";
break;
}
}
buttons[index-1].className = "on";
}
还需要对index的值进行限制,不能让它无限的减下去,或者加上去,修改后的代码如下:
prev.onclick = function(){
if(index == 5) {
index = 1;
} else {
index -= 1;
}
showButtons();
animate(-600);
}
next.onclick = function(){
if(index == 1) {
index = 5;
} else {
index += 1;
}
showButtons();
animate(600);
}
五、焦点图轮播特效之按钮切换
实现完了箭头的切换,接下来就要实现按钮的切换了,就是要分别给buttons数组里面的每个元素添加一个点击事件,跟箭头切换不同的是,按钮切换的偏移量需要计算,有可能跨几幅图片切换,还有,每张图片里面有个index属性,显示自己是第几张图片,如下:
for(var i = 0; i< buttons.length; i++) {
buttons[i].onclick = function() {
var myIndex = parseInt(this.getAttribute('index'));
var offset = -600 * (myIndex - index);
animate(offset);
index = myIndex;//更新index值
showButton();
}
}
- 这里面有一个点需要注意,span标签里面index属性是属于自定义属性,不能通过点表示法来取得,所以要使用getAttribute()方法来获取,即能取自定义属性,又能取自身有的属性;
此时还有一些需要优化的地方,当我位于当前图片的时候,再点击当前按钮,后台还会执行,但是我们的理想情况应该是,位于当前图片的时候,再点击当前按钮,就应该不做任何事情,加一个判断语句,优化后的代码如下:
for(var i = 0; i< buttons.length; i++) {
buttons[i].onclick = function() {
if(this.className == 'on') {
return;
}
var myIndex = parseInt(this.getAttribute('index'));
var offset = -600 * (myIndex - index);
animate(offset);
index = myIndex;//更新index值
showButton();
}
}
六、焦点轮播图之动画函数
在进行图片的切换过程中,图片是缓慢的移动切换的,而不是一张图片一张图片的切换过去,这不是我们想要的效果,这里就涉及到了javascript中的动画效果和函数;
它的原理是在切换的过程中,不断地进行一小段的位移,直到达到目标值,清楚了原理,接下来就来写代码:
我们增加了位移总时间的变量、位移间隔还有计算出每次的位移量,并且定义了一个位移函数go(),当每次的位移量小于0并且left大于新的left目标值时,还有一种情况是,每次的位移量大于0并且left小于新的left目标值时,left值就等于left加上每次的位移量,然后调用setTimeout函数不断地递归调用,直到达到目标值;
function animate(offset){
animated = true;
var newLeft = parseInt(list.style.left) + offset;
var time = 300;//位移总时间
var interval = 10; //位移间隔
var speed = offset/(time/interval);//每次位移量
function go(){
if ((speed < 0 && parseInt(list.style.left) > newLeft) || (speemd >0 && parseInt(list.style.left) < newLeft)) {
list.style.left = parseInt(list.style.left) + speed + 'px';
setTimeout(go,interval);
}
else{
animated = false;
list.style.left = newLeft + 'px';
if(newLeft > -600){
list.style.left = -3000 + 'px';
}
if(newLeft < -3000){
list.style.left = -600 + 'px';
}
}
}
go();
}
- 这里要注意的是,setTimeout()方法接受两个参数,一个执行的函数代码,一个间隔,函数会在这个间隔后执行一次,不会重复执行,但是因为调用的是自身,所以相当于递归不断地重复执行;
七、焦点图轮播特效之自动播放
我们会注意到,当我们把鼠标移出图片列表时,图片会自动切换,当把鼠标移进去时,就会停止自动切换,这里,我们就需要引入两个函数:play()还有stop()函数,并且为container父容器添加两个事件:onmouseover还有onmouseout,具体的代码如下:
function play(){
timer = setInterval(function(){
next.onclick();
},1500);
}
function stop(){
clearInterval(timer);
}
container.onmouseover = stop;
container.onmouseout = play;
play();
还重新定义了一个时间变量timer,并且执行setInterval方法,经过间隔时间不断地执行函数代码,然后停止函数里面,就清楚调这个时间变量timer;