一、匀速运动
封装一个匀速运动的animate方法,要用到定时器,先清除定时器,一个盒子只能有一个定时器,这样的话,不会和其他盒子出现定时器冲突。而定时器本身会成为盒子的一个属性。
//ele为要操作的对象,target为要运动到的位置
function animate(ele,target){
clearInterval(ele.timer);
//我们要求盒子既能向前又能向后,那么我们的步长就得有正有负
//目标值如果大于当前值取正,目标值如果小于当前值取负
var speed = target>ele.offsetLeft?10:-10;
ele.timer = setInterval(function () {
//在执行之前就获取当前值和目标值之差
var val = target - ele.offsetLeft;
ele.style.left = ele.offsetLeft + speed + "px";
//目标值和当前值只差如果小于步长,那么就不能在前进了
//因为步长有正有负,所有转换成绝对值来比较
if(Math.abs(val)<Math.abs(speed)){
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},30)
}
二、左右焦点图
效果图:
需求:鼠标放到盒子上,显示左右切换的图片。点击左则按钮,图片(ul)向右移动,点击相反的按钮向左移动。
思路:获取两个按钮,点击左侧按钮移动ul向右走(每次只走一张)(计数器从0开始)。利用计数器模拟index值,点右侧自增,点击左侧自减来移动盒子。此处用到上例封装的animate方法。
实现步骤:
1.鼠标放上去显示,移开隐藏。(绑定相应的事件)
2.点击右侧盒子图片向左移动并用计数器模拟index值。
3.点击左侧盒子,同理。
//1.鼠标放上去显示移开以藏
var box = document.getElementById("box");
var imgWidth = box.children[0].offsetWidth;
var ul = box.children[0].children[0];
var boxLeftRight = box.children[1];
var btnArr = boxLeftRight.children;
//鼠标放上去显示,移开隐藏
box.onmouseover = function () {
boxLeftRight.style.display = "block";
}
box.onmouseout = function () {
boxLeftRight.style.display = "none";
}
//2.点击右侧盒子图片向做移动并用计数器模拟index值。
//定义计数器
var index = 0;
btnArr[1].onclick = function(){
index++;
//我们要对index的值进行约束。index的值必须在[0,4]
if(index>ul.children.length-1){
index = ul.children.length-1;
//alert("到头了!");
}
//点击盒子以后移动图片(ul,和目标位置)
animate(ul,-index*imgWidth);
}
//3,点击左侧盒子,同理。
btnArr[0].onclick = function () {
index--;
if(index<0){
index = 0;
//alert("第一张!");
}
//点击盒子以后移动图片(ul,和目标位置)
animate(ul,-index*imgWidth);
}
function animate(ele,target){
clearInterval(ele.timer);
var speed = target>ele.offsetLeft?10:-10;
ele.timer = setInterval(function () {
var val = target - ele.offsetLeft;
ele.style.left = ele.offsetLeft + speed + "px";
if(Math.abs(val)<Math.abs(speed)){
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},10)
}
三、无缝轮播图(带定时)
效果图:
需求:我们鼠标放到li上,指定图片播放。加定时器,一秒钟动一次。
思路:复制第一张图片放到ul的最后,当图片切换到第五张的时候,直接切换到第六张。当要切换到第二张图时,瞬间切回第一张,再滑动至第二张。
相比较上一个案例,增加了两个定时器,一个记录小方块的定时切换,一个记录图片的定时切换,另外小方块的index值要和大图片的索引值一致。
window.onload = function () {
//1、获取事件源及相关元素。
var all = document.getElementById("all");
var screen = all.children[0];
var imgWidth = screen.offsetWidth;
var ul = screen.children[0];
var ol = screen.children[1];
var arr = screen.lastElementChild || screen.lastChild;
var spanArr = arr.children;
//2、复制第一张图片的li,添加到ul最后面。
var ulNewLi = ul.children[0].cloneNode(true);
ul.appendChild(ulNewLi);
//3、给ol中添加li,ul中li的个数-1个,并点亮第一个按钮。
for(var i = 0; i<ul.children.length-1; i++){
var olNewLi = document.createElement("li");
olNewLi.innerHTML = i+1;
ol.appendChild(olNewLi);
}
var olLiArr = ol.children;
olLiArr[0].className = "current";
//4、鼠标放到ol的li上切换图片
for(var i = 0;i<olLiArr.length;i++){
//自定义属性,把索引值绑定到元素的index属性上
olLiArr[i].index = i;
olLiArr[i].onmouseover = function() {
//排他思想
for(var j = 0; j<olLiArr.length;j++) {
olLiArr[j].className = "";
}
this.className = "current";
//鼠标放到小方块时,索引值和key以及square要同步
key = square = this.index;
//移动盒子
animate(ul,-this.index*imgWidth);
}
}
//5、添加定时器
var timer = null;
timer = setInterval(autoPlay,1000);
//固定向右切换图片
//(两个定时器,一个记录图片,一个记录小方块)
var key = 0;
var square = 0;
function autoPlay(){
key++;
square++;
if(key>5){ //转到第一张,再滑动到第二张
key=1;
ul.style.left = 0+ 'px';
}
animate(ul,-key*imgWidth);
square = square > olLiArr.length-1? 0:square; //对square的最大值进行约束
for(var i=0;i<olLiArr.length;i++){
olLiArr[i].className = "";
}
olLiArr[square].className = "current";
}
//鼠标放上去清除定时器,移开后再开启定时器
all.onmouseover = function () {
arr.style.display = "block";
clearInterval(timer);
}
all.onmouseout = function () {
arr.style.display = "none";
timer = setInterval(autoPlay,1000);
}
//6、左右切换图片(鼠标放上去显示左右按钮,移开隐藏)
spanArr[0].onclick = function(){
key--;
square--;
if(key<0){
key=olLiArr.length-1;
ul.style.left = -olLiArr.length*imgWidth+ 'px';
}
animate(ul,-key*imgWidth);
square = square <0 ? 4:square; //对square的最大值进行约束
for(var i=0;i<olLiArr.length;i++){
olLiArr[i].className = "";
}
olLiArr[square].className = "current";
//console.log(key+" " + square);
}
spanArr[1].onclick = function(){
autoPlay();
}
function animate(ele,target){
clearInterval(ele.timer);
var speed = target>ele.offsetLeft?10:-10;
ele.timer = setInterval(function () {
var val = target - ele.offsetLeft;
ele.style.left = ele.offsetLeft + speed + "px";
if(Math.abs(val)<Math.abs(speed)){
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},10)
}
}
相应的html代码如下:
<div class="all" id='all'>
<div class="screen" id="screen">
<ul id="ul">
<li><img src="images/001.jpg" width="500" height="200" /></li>
<li><img src="images/002.jpg" width="500" height="200" /></li>
<li><img src="images/003.jpg" width="500" height="200" /></li>
<li><img src="images/004.jpg" width="500" height="200" /></li>
<li><img src="images/005.jpg" width="500" height="200" /></li>
</ul>
<ol></ol>
<div id="arr">
<span id="left"><</span>
<span id="right">></span>
</div>
</div>
</div>
本文的CSS样式未上传,可以自行按照要求设置。
总结了一下基本的JS编写轮播图的案例,温习一下之前学过的内容,后期基本都是用框架实现这些效果,但是用原生JS代码如何去实现这些,还是很多面试会考察的内容。