定时器的应用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>定时器应用一</title>
<style>
* {
padding: 0;
margin: 0;
}
#box1 {
width: 100px;
height: 100px;
background-color: skyblue;
position: absolute;
left: 0;
}
#box2 {
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
left: 0;
top: 200px;
}
#cut {
height: 1000px;
border-left: 2px solid black;
position: absolute;
left: 800px;
top: 0;
}
</style>
<script async src="compatibility.js"></script>
<script>
window.onload = function () {
/**
* 希望实现一个功能,div随时间水平位移
*/
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var btn01 = document.getElementById("btn01");
var btn02 = document.getElementById("btn02");
var btn03 = document.getElementById("btn03");
var btn04 = document.getElementById("btn04");
btn01.onclick = function () {
slowMove(box1, "left", 800, 10);
};
btn02.onclick = function () {
slowMove(box1, "left", 0, 10, function () {
alert("动画执行完毕");
});
};
btn03.onclick = function () {
slowMove(box2, "left", 800, 10, function () {
alert("动画执行完毕");
});
};
btn04.onclick = function () {
slowMove(box2, "width", 800, 10, function () {
slowMove(box2, "height", 400, 10, function () {
slowMove(box2, "top", 0, 10, function () {
alert("动画执行完毕");
});
});
});
};
};
/**
* 定义外部的定时器标志
* 全局变量有隐患,如果有多个盒子移动,
* 那么下边那个会关闭上边那个
*/
//var timer = null;
/**
* slowMove函数,用来处理简单动画效果
* 参数的定义:
* 1.obj:要执行动画的对象
* 2.attr:要执行动画的样式,比如left、height,right、top等
* 3.target:执行动画的目标位置(只是数值不加px)
* 4.speed:移动的速度(为正值)
* 5.callback:回调函数,将会在动画执行完毕执行
* 可以在回调函数中再次写入该函数,如此往复可以依次执行不同的特效。
*
*/
function slowMove(obj, attr, target, speed, callback) {
//关闭上一个定时器,防止多开
clearInterval(obj.timer);
//获取元素目前的位置
var current = parseInt(getStyle(obj, attr));
//判断速度的正负值
//如果从0移向target。则speed为正
//如果从target移向0。则speed为负
if (current > target) {
speed = -speed;
}
//开启一个定时器,用来执行动画
//向执行动画的对象中添加一个timer属性,用来保存自己定时器标识
obj.timer = setInterval(function () {
//获取box1原来的left值,parseInt可以提取字符串中的整数
var oldValue = parseInt(getStyle(obj, attr));
//定义移动后的left值
var newValue = oldValue + speed;
//让其能稳定停靠在target
//向左移动,需判断newValue是否小于target
//向右移动,需判断newValue是否大于target
if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
newValue = target;
}
//将新值赋给box1
obj.style[attr] = newValue + "px";
//将元素移动到target时停止动画
if (newValue === target) {
clearInterval(obj.timer);
//动画执行完毕,如果传入回调函数则执行,没有不执行
callback && callback();
}
}, 10);
}
</script>
</head>
<body>
<!--div写在前边会盖住button,button是行内元素-->
<button id="btn01">点我box1向右移动</button>
<button id="btn02">点我box1向左移动</button>
<button id="btn03">点我box2向右移动</button>
<button id="btn04">点我box2终极动画</button>
<div id="box1"></div>
<div id="box2"></div>
<div id="cut"></div>
</body>
</html>
getStyle这个函数:
/**
* 兼容ie8和其他浏览器同时可以使用的函数
* 同于获取元素样式,只读
* 参数:
* obj 要获取样式元素
* name 要获取的样式名
*/
function getStyle(obj, name) {
//ie中css里没有写的属性,默认返回auto
/**
* 对象.属性和对象[属性]的区别
* .一般作为静态存取属性使用,[]一般作为动态存取属性时使用
* [name],name可以是字符串变量,它会直接去name变量中寻找属性
* .name,只会静态的查找叫name的属性
*/
if (window.getComputedStyle) {
/*如果只写getComputedStyle,会先在函数内找这个变量,没有就去全局找
* 这个变量,而window是一个对象,
* 添加对象,getComputedStyle就变成一个属性了
*/
//正常浏览器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//ie8的方式,有currentStyle属性
return obj.currentStyle[name];
}
// return window.getComputedStyle?getComputedStyle(obj,null)[name]:obj.currentStyle[name];
}
注意点:
1,。如果同一个定时器按钮多次点击会开启多个定时器,需要每次点击关闭上一个定时器。
2.box1左右移动按钮两个定时器的标志需要被不断替换,点击左移就把标志换成左移的,右移就换成右移的,不要设置全局变量。如果加入第二个盒子,它的标志也会修改box1的标志,将这个标志加入box中,即box1.timer.
3,大篇幅的重复代码,要学会提取出共性来用参数来代替实际的值,增加灵活性,减少代码值。
4.回调函数只会执行一次,再回调函数中设置回调函数,可以递归执行,完成多个特效。