iqianduan.js
/*
名称:iqianduan.js
版本:1.0
用途:运动函数、获取计算后样式
修改:
*/
// 封装运动函数
function animate(obj,jieshuJson,time){
//准备三个数据,开始的JSON,结束的JSON,还有步长JSON
//开始JSON有多少个属性,由jieshuJson决定
//给开始JSON添加新属性,来源于jieshuJson。
var kaishiJson = {};
for(var k in jieshuJson){
//通过赋初始值,用到计算后样式,将字符串转数字
//结束后的样式名k
kaishiJson[k] = parseFloat(getStyle(obj,k));
}
//console.log(kaishiJson);
//步长JSON = (jieshuJson - kaishiJson) / 总次数
//总次数 = 总时间 / 间隔时间
var interval = 50;
var zongcishu = time / interval;
//获得步长JSON
var buchangJson = {};
for(var k in jieshuJson){
//避免输入的是字符串,先转数字
jieshuJson[k] = parseFloat(jieshuJson[k]);
buchangJson[k] = (jieshuJson[k] - kaishiJson[k]) / zongcishu;
}
// console.log(buchangJson);
//============三个JSON都准备完了===============
//程序部分
//全局信号量接收初始值,每次的步长
//定义信号量JSON
var xinhaoliangJson = {};
for(var k in kaishiJson){
xinhaoliangJson[k] = kaishiJson[k];
}
//执行次数等于总次数,停止运动
//累加器
var cishu = 0;
var timer ;
timer = setInterval(function(){
//每执行一次,次数增加
cishu++;
//信号量JSON每次加一个步长
for(var k in xinhaoliangJson){
xinhaoliangJson[k] += buchangJson[k];
}
//验收,停止定时器
if(cishu >= zongcishu){
//拉终停表
for(var k in xinhaoliangJson){
xinhaoliangJson[k] = jieshuJson[k];
}
clearInterval(timer);
}
//赋值,如果是透明度属性,需要单独设置
for(var k in xinhaoliangJson){
if(k == "opacity"){
obj.style.opacity = xinhaoliangJson[k];
obj.style.filter = "alpha(opacity=" + xinhaoliangJson[k] * 100 +")";
}else{
obj.style[k] = xinhaoliangJson[k] + "px";
}
}
},interval);
}
//传入一个对象、和属性名,输出这个对象的对应的属性值
function getStyle(obj,property){
//兼容高版本和低版本浏览器,能力测试
if(window.getComputedStyle){
//属性名必须是css写法,人为规范输入的属性名
property = property.replace(/([A-Z])/g,function(match,$1){
return "-" + $1.toLowerCase();
});
return window.getComputedStyle(obj)[property];
}else if(obj.currentStyle){
//属性名必须是驼峰写法,人为规范输入的属性名
property = property.replace(/\-([a-z])/gi,function(match,$1){
return $1.toUpperCase();
});
return obj.currentStyle[property];
}
}
iqianduan-2.0.js
/*
名称:iqiansuan.js
版本:1.0
用途:运动函数、获取计算后样式
修改:加入回调函数,指定回调函数的this
*/
// 封装运动函数
function animate(obj,jieshuJson,time,callback){
//准备三个数据,开始的JSON,结束的JSON,还有步长JSON
//开始JSON有多少个属性,由jieshuJson决定
//给开始JSON添加新属性,来源于jieshuJson。
var kaishiJson = {};
for(var k in jieshuJson){
//通过赋初始值,用到计算后样式,将字符串转数字
//结束后的样式名k
kaishiJson[k] = parseFloat(getStyle(obj,k));
}
//console.log(kaishiJson);
//步长JSON = (jieshuJson - kaishiJson) / 总次数
//总次数 = 总时间 / 间隔时间
var interval = 50;
var zongcishu = time / interval;
//获得步长JSON
var buchangJson = {};
for(var k in jieshuJson){
//避免输入的是字符串,先转数字
jieshuJson[k] = parseFloat(jieshuJson[k]);
buchangJson[k] = (jieshuJson[k] - kaishiJson[k]) / zongcishu;
}
// console.log(buchangJson);
//============三个JSON都准备完了===============
//程序部分
//全局信号量接收初始值,每次的步长
//定义信号量JSON
var xinhaoliangJson = {};
for(var k in kaishiJson){
xinhaoliangJson[k] = kaishiJson[k];
}
//执行次数等于总次数,停止运动
//累加器
var cishu = 0;
var timer ;
timer = setInterval(function(){
//每执行一次,次数增加
cishu++;
//信号量JSON每次加一个步长
for(var k in xinhaoliangJson){
xinhaoliangJson[k] += buchangJson[k];
}
//验收,停止定时器
if(cishu >= zongcishu){
//拉终停表
for(var k in xinhaoliangJson){
xinhaoliangJson[k] = jieshuJson[k];
}
clearInterval(timer);
//回调函数
callback.call(obj);
}
//赋值,如果是透明度属性,需要单独设置
for(var k in xinhaoliangJson){
if(k == "opacity"){
obj.style.opacity = xinhaoliangJson[k];
obj.style.filter = "alpha(opacity=" + xinhaoliangJson[k] * 100 +")";
}else{
obj.style[k] = xinhaoliangJson[k] + "px";
}
}
},interval);
}
//传入一个对象、和属性名,输出这个对象的对应的属性值
function getStyle(obj,property){
//兼容高版本和低版本浏览器,能力测试
if(window.getComputedStyle){
//属性名必须是css写法,人为规范输入的属性名
property = property.replace(/([A-Z])/g,function(match,$1){
return "-" + $1.toLowerCase();
});
return window.getComputedStyle(obj)[property];
}else if(obj.currentStyle){
//属性名必须是驼峰写法,人为规范输入的属性名
property = property.replace(/\-([a-z])/gi,function(match,$1){
return $1.toUpperCase();
});
return obj.currentStyle[property];
}
}
iqianduan-3.0.js
/*
名称:iqiansuan.js
版本:3.0
用途:运动函数、获取计算后样式
修改:加入回调函数,指定回调函数的this,函数节流
修改:参数名字
*/
// 封装运动函数
/*
运动函数一共传入4个参数
para1 : 运动元素对象
para2 : 运动的结束JSON
para3 : 运动总时长
para4 :回调函数
功能,让元素在规定时间内进行运动到结束位置
*/
function animate(obj,endJson,time,callback){
//先去检测输入的数据类型,模拟函数重载
//根据传入的参数个数去模拟
if(arguments.length < 3 || typeof arguments[0] != "object" || typeof arguments[1] != "object" || typeof arguments[2] != "number" ){
//要么参数个数不够,要么类型不对
throw new Error("参数最少输入3个,且前两个是对象型,第三个必须是数字");
}else if(arguments.length == 3){
callback = null;
}else{
switch(typeof arguments[3]){
case "string":
case "number":
callback = null;
break;
case "function":
case "object":
callback = arguments[3];
}
}
// 控制函数节流,能走到这个位置说明运动正常开始
obj.isAnimated = true;
//自定义时间间隔
var interval = 50;
// 运动的总次数,总时间除以间隔时间
var maxCount = time / interval;
//累加器,次数执行
var count = 0;
//需要四个JSON,开始位置的JSON,结束位置的JSON,步长JSON,信号量JSON
// 结束JSON已经有了,根据它来确定其他的JSON
var startJson = {};
var stepJson = {};
var semJson = {};
for(var k in endJson){
//endJSON转数字
endJson[k] = parseFloat(endJson[k]);
startJson[k] = parseFloat(getStyle(obj,k));
// 信号量初始值与开始位置一致
semJson[k] = startJson[k];
//求步长,需要总次数
stepJson[k] = (endJson[k] - startJson[k]) / maxCount;
}
// console.log(endJson);
// console.log(semJson);
// console.log(stepJson);
//定时器变量
var timer;
timer = setInterval(function(){
//增加信号量JSON,每次加一个步长,顺便将属性赋值给元素属性
for(var k in semJson){
semJson[k] += stepJson[k];
//赋值
//判断是否为透明度
if(k == "opacity"){
obj.style.opacity = semJson[k];
obj.style.filter = "alpha(opacity="+semJson[k]*100+")";
}else{
obj.style[k] = semJson[k] + "px";
}
}
//次数都要增加
count++;
if(count >= maxCount){
//拉终停表
//直接将属性值都拖到endJSON的部分
for(var k in endJson){
if(k == "opacity"){
obj.style.opacity = endJson[k];
obj.style.filter = "alpha(opacity="+endJson[k]*100+")";
}else{
obj.style[k] = endJson[k] + "px";
}
}
//停止定时器
clearInterval(timer);
//运动结束,函数节流的锁可以打开了
obj.isAnimated = false;
//回调函数,运动停止之后要做的事儿
// 回调函数没有,不执行回调函数
callback && callback.call(obj);
}
},interval);
}
//传入一个对象、和属性名,输出这个对象的对应的属性值
function getStyle(obj,property){
//兼容高版本和低版本浏览器,能力测试
if(window.getComputedStyle){
//属性名必须是css写法,人为规范输入的属性名
property = property.replace(/([A-Z])/g,function(match,$1){
return "-" + $1.toLowerCase();
});
return window.getComputedStyle(obj)[property];
}else if(obj.currentStyle){
//属性名必须是驼峰写法,人为规范输入的属性名
property = property.replace(/\-([a-z])/gi,function(match,$1){
return $1.toUpperCase();
});
return obj.currentStyle[property];
}
}
使用回调函数
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<!-- 调用外部js -->
<script src="iqianduan-2.0.js"></script>
<!-- 使用js库内的方法需要另写一个script -->
<script>
var box1 = document.getElementById("box1");
animate(box1,{"left":400},1000,function(){
//运动执行完,回调函数内执行的语句
box1.style.background = "#0f0";
animate(box1,{"top":400},800,function(){
box1.style.background = "#00f";
});
});
</script>
</body>
</html>
使用外部js文件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
opacity: 0.3;
filter: alpha(opacity=30);
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<h1></h1>
<div class="box" id="box1"></div>
<div class="box box1" id="box2"></div>
<div class="box box2" id="box3"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<!-- 调用外部js -->
<script src="iqianduan.js"></script>
<!-- 使用js库内的方法需要另写一个script -->
<script>
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
var start = document.getElementsByTagName("input")[0];
animate(box1,{"width":400,"left":500,"height":400,"opacity":1},2000);
animate(box2,{"width":200,"left":500,"height":200,"opacity":1,"top":300},1000);
animate(box3,{"width":300,"left":400,"height":300,"opacity":1,"top":400},2000);
</script>
</body>
</html>
同步和异步
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
opacity: 0.3;
filter: alpha(opacity=30);
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<h1></h1>
<div class="box" id="box1"></div>
<div class="box box1" id="box2"></div>
<div class="box box2" id="box3"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<!-- 调用外部js -->
<script src="iqianduan.js"></script>
<!-- 使用js库内的方法需要另写一个script -->
<script>
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
var start = document.getElementsByTagName("input")[0];
animate(box1,{"width":400,"left":500,"height":400,"opacity":1},2000);
animate(box2,{"width":200,"left":500,"height":200,"opacity":1,"top":300},1000);
animate(box3,{"width":300,"left":400,"height":300,"opacity":1,"top":400},2000);
</script>
</body>
</html>
函数内部 this
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<!-- 调用外部js -->
<script src="iqianduan-2.0.js"></script>
<!-- 使用js库内的方法需要另写一个script -->
<script>
var box = document.getElementById("box1");
// animate(box,{"left":300},1000,function(){
// console.log(this);
// });
function move(){
console.log(this);
}
// move();
</script>
</body>
</html>
函数内部this-call和apply
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<!-- 调用外部js -->
<script src="iqianduan-2.0.js"></script>
<!-- 使用js库内的方法需要另写一个script -->
<script>
var box = document.getElementById("box1");
// animate(box,{"left":300},1000,function(){
// console.log(this);
// });
function move(){
console.log(this);
}
//作用:第一个执行函数,第二个指定this。
move.call(box);
move.apply(box);
</script>
</body>
</html>
call 和apply的区别
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<!-- 调用外部js -->
<script src="iqianduan-2.0.js"></script>
<!-- 使用js库内的方法需要另写一个script -->
<script>
var box = document.getElementById("box1");
function sum(a,b,c){
console.log(this);
console.log(a + b + c);
}
// call方法直接传递
sum.call(box,1,2,3);
//apply必须将参数放在一个数组
sum.apply(box,[2,3,4]);
</script>
</body>
</html>
使用回调函数-this
eg1:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<!-- 调用外部js -->
<script src="iqianduan-2.0.js"></script>
<!-- 使用js库内的方法需要另写一个script -->
<script>
var box1 = document.getElementById("box1");
move(box1);
function move(obj){
animate(obj,{"left":400},1000,function(){
//运动执行完,回调函数内执行的语句
this.style.background = "#0f0";
animate(this,{"top":400},1000,function(){
this.style.background = "#00f";
//在调用运动函数
animate(this,{"left":0},1000,function(){
this.style.background = "#0ff";
//在调用运动函数
animate(this,{"top":100},1000,function(){
this.style.background = "#f00";
move(this);
});
});
});
});
}
</script>
</body>
</html>
eg2:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<!-- 调用外部js -->
<script src="iqianduan-2.0.js"></script>
<!-- 使用js库内的方法需要另写一个script -->
<script>
var box1 = document.getElementById("box1");
move(box1);
function move(obj){
animate(obj,{"left":400},1000,function(){
//停止这一次的定时器后执行我内部的函数
this.style.background = "#0f0";
});
}
</script>
</body>
</html>
延时器
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<script>
console.log(1);
console.log(2);
console.log(3);
setTimeout(function(){
console.log("booom shakalaka");
},1000);
console.log(4)
</script>
</body>
</html>
函数节流
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="开始" />
<input type="button" value="结束" />
<script>
var btn = document.getElementsByTagName("input")[0];
//给函数上一把锁,锁开的时候,执行函数的语句,锁关上之后,不能执行函数
var lock = true ; //表示锁是开的能够执行事件函数
btn.onclick = function(){
//如果锁开着可以执行后面的语句,如果关闭,直接return返回,不执行后面的代码
if(lock == false){
return;
}
//给函数上一把锁
lock = false;
//隔一段时间打开锁
setTimeout(function(){
lock = true;
},2000);
console.log(Math.random());
}
</script>
</body>
</html>
测试
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 100px;
left: 0;
/*opacity: 0.3;
filter: alpha(opacity=30);*/
}
.box1{
background: #0f0;
}
.box2{
background: #00f;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<input type="button" value="向左" />
<input type="button" value="向下" />
<script src="iqianduan-3.0.js"></script>
<script>
var box = document.getElementById("box1");
var btn1 = document.getElementsByTagName("input")[0];
var btn2 = document.getElementsByTagName("input")[1];
// animate(box,{"left":200,"opacity":1},1000,function(){
// this.style.background = "#0f0";
// });
// 添加点击事件
//元素运动过程中,不能再添加其他运动函数
btn1.onclick = function(){
//判断它是否在运动,如果运动就直接return
if(box.isAnimated){
return;
}
animate(box,{"left":400},2000);
}
btn2.onclick = function(){
//判断它是否在运动,如果运动就直接return
if(box.isAnimated){
return;
}
animate(box,{"top":400},2000);
}
</script>
</body>
</html>