要点:
1.这个例子中的数组操作的四个方法,都是在进行运算之后,都有返回值,而这些返回值有所不同。执行删除相关的操作时,返回的是被删除的值,而追加到数组对象中,返回的是被操作后的整个数组。
2.关键点是,在点击切换按钮后,原来图片数组对应的图片发生了改变,但是通过js获取到的多个li标签组成的伪数组的每个li的样式并没有改变,需要重新将样式改变一下。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="css22.css">
</head>
<body>
<div class="wrap" id="wrap">
<div class="slide" id="slide">
<ul>
<li><a href="#"><img src="images22/slidepic1.jpg"></a></li>
<li><a href="#"><img src="images22/slidepic2.jpg"></a></li>
<li><a href="#"><img src="images22/slidepic3.jpg"></a></li>
<li><a href="#"><img src="images22/slidepic4.jpg"></a></li>
<li><a href="#"><img src="images22/slidepic5.jpg"></a></li>
</ul>
<div class="arrow" id="arrow">
<a href="javascript:;" class="prev" id="arrLeft"></a>
<a href="javascript:;" class="next" id="arrRight"></a>
<!-- 图片两侧的大箭头,通过prev和next两个类进行定义 -->
</div>
</div>
</div>
<script type="text/javascript">
function myGet(id){
return document.getElementById(id);
}
window.onload = function(){
var liObjs = myGet("slide").getElementsByTagName("LI");
// 标签的返回值,一般是标签名的大写,也大写较好
var flag = true;
// 控制动画,一次执行完再点切换才能实现切换
function assign(){
for(var i=0;i<liObjs.length;i++){
animate(liObjs[i],config[i],function(){
flag = true;
// 当点击按钮时候,已经被赋值为flase不会执行函数,动画函数执行完成了,再将flag设为true
});
// config[]数组提前写好样式,内部由多个json对象构成
}
}
assign();
// assign:分配
myGet("arrRight").onclick = function(){
if(flag){
flag = false;
// 首先将flag改为false不会将点击事件储存
config.push(config.shift());
assign();
// 通过这两组数组操作的方法,都会返回一个处理完成之后的数组
}
}
myGet("arrLeft").onclick = function(){
if(flag){
flag = false;
config.unshift(config.pop());
assign();
// 原来显示的图片的顺序,通过assign()操作完成之后,原来通过数组遍历的数组的图片还是原来一样
}
}
myGet("wrap").onmouseover = function(){
animate(myGet("arrow"),{"opacity":1});
// 鼠标放上后透明度逐渐为1
}
myGet("wrap").onmouseout = function(){
animate(myGet("arrow"),{"opacity":0});
// 鼠标离开后透明度逐渐为0,达到隐藏的效果,而不是直接设置显示或隐藏,这样会体验更好
}
}
var config = [
{
width: 400,
top: 20,
left: 50,
opacity: 0.2,
zIndex: 2
},//0
{
width: 600,
top: 70,
left: 0,
opacity: 0.8,
zIndex: 3
},//1
{
width: 800,
top: 100,
left: 200,
opacity: 1,
zIndex: 4
},//2
{
width: 600,
top: 70,
left: 600,
opacity: 0.8,
zIndex: 3
},//3
{
width: 400,
top: 20,
left: 750,
opacity: 0.2,
zIndex: 2
}//4
];
function animate(element,json,fn){
clearInterval(element.intervalName);
// 清理定时器
element.intervalName = setInterval(function(){
var flag = true;
// 哈哈哈,又是这个,因为遍历for循环遍历有先后顺序,要都到达指定位置才能清理计时器
for(var attr in json){
if(attr == "zIndex"){
// css中的属性中间是连字符的属性,在js操作中,将下划线去掉同驼峰原则
// 层级的操作,直接赋值即可不需要其他的操作
element.style[attr] = json[attr];
}else if(attr == "opacity"){
var current = getStyle(element,attr)*100;
var target = json[attr]*100;
// 将attr对应的值获取到,直接通过对象的键值获取,这个参数没有单位直接获取值
var step = (target - current)/10;
step = step>0 ? Math.ceil(step) : Math.floor(step);
current += step;
element.style[attr] = current/100;
// 透明度不需要其他的参数,前面放大100倍,变回来
}else{
// 其他不同的属性
// 遍历json数组对象,每次将遍历的数组对象属性进行设置
var current = parseInt(getStyle(element,attr));
var target = json[attr];
// 将attr对应的值获取到,直接通过对象的键值获取
var step = (target - current)/10;
// 将从当前位置到目标距离,每次走十分之一
step = step>0 ? Math.ceil(step) : Math.floor(step);
// Math.ceil()和Math.floor()分别是向上和向下取整
current += step;
element.style[attr] = current + "px";
}
if(current != target){
flag = false;
// 也是类似于多线程,只有每个都为true才能到达指定位置
}
}
if(flag){
clearInterval(element.intervalName);
// 所有的动画执行完成之后,可以再执行一个函数
if(fn){
fn();
}
// 这里调用的函数,也可以是本身这个函数,还可以 进行多次动画
}
},30)
}
function getStyle(element,attr){
return window.getComputedStyle ? window.getComputedStyle(element,null)[attr]
: element.currentStyle[attr];
// 将原来的if-else语句进行判断也兼容代码的方式,进行简化,写成三目运算符的方式
// 属性后面的[attr]是跟点语法的作用是一样的,但是这里不能使用点语法获取attr的对象属性,因为attr是变量只有用[]接收不同类型字符串
// 获取的计算后的样式都是带有单位的
}
</script>
</body>
</html>
效果: