链式运动框架、
回调函数
运动停止时,执行函数
运动停止时,开始下一次运动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>运动框架</title>
<style>
#div1{
width: 100px;
height: 100px;
background: red;
filter: alpha(opacity:30);
opacity: 0.3;
}
</style>
<script src="32.js"></script>
<script>
window.onload = function(){
var oDiv = document.getElementById('div1'); //链式运动——收缩展开运动
oDiv.onmouseover = function(){
startMove(oDiv, 'width', 300, function(){
// alert('宽度已变大!');
startMove(oDiv, 'height', 300, function () {
startMove(oDiv, 'opacity', 100);
});
});
};
oDiv.onmouseout = function(){
startMove(oDiv, 'opacity', 30, function(){
// alert('宽度已变大!');
startMove(oDiv, 'height', 100, function () {
startMove(oDiv, 'width', 100);
});
});
};
};
</script>
</head>
<body>
<div id="div1"></div>
</body>
</html>
function getStyle(obj, name) {
if (obj.currentStyle) {
return obj.currentStyle[name];
} else {
return getComputedStyle(obj, false)[name];
}
} function startMove(obj, attr, iTarget, fnEnd) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
var cur = 0; if (attr == 'opacity') {
cur = Math.round(parseFloat(getStyle(obj, attr))*100); //乘以100符合咱们平时对opacity的设置
} else {
cur = parseInt(getStyle(obj, attr));
} var speed = (iTarget-cur)/6;
speed = speed>0?Math.ceil(speed):Math.floor(speed); if (cur==iTarget) {
clearInterval(obj.timer); if (fnEnd) fnEnd();//当参数传进来且运动结束后被调用
} else {
if (attr == 'opacity') {
obj.style.filter = 'alpha(opacity:'+(cur+speed)+')'; //IE透明度
obj.style.opacity = (cur+speed)/100; var oTxt = document.getElementById('txt1');
oTxt.value = obj.style.opacity;
} else {
obj.style[attr] = cur+speed+'px';
} }
}, 30);
}
32.js
例子:土豆天气预报弹窗(已下架) 由于图片没有调好就没有写,有兴趣可根据上述代码自行写出
完美运动框架
多个值同时变化(首先是出错情况)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>运动框架小问题</title>
<style>
#div1{width: 100px;
height: 100px;
background: red;
}
</style>
<script src="32.js"></script>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn1');
var oDiv = document.getElementById('div1'); oBtn.onclick = function () {
startMove(oDiv, 'width', 300);
startMove(oDiv, 'height', 300);
};
//问题来了,如果不加此句“startMove(oDiv, 'height', 300);” 则div变宽,好像没什么问题;
//但是如果加上此句“startMove(oDiv, 'height', 300);” div只变长了,而未变宽,所以也就是说,
//不能让多个值同时变化,否则会出错,解决办法是:用json循环来修改运动框架
};
</script>
</head>
<body>
<input id="btn1" type="button" value="运动"/>
<div id="div1"></div>
</body>
</html>
setStyle同时设置多个属性
参数传递:JSon的使用,for in遍历属性
var json = {a:12, b:5};
for (var i in json){ //json循环
alert(i+'='+json[i]);
}
运用到运动框架
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>运动框架小问题</title>
<style>
#div1{width: 100px;
height: 100px;
background: red;
filter: alpha(Opacity=30);
opacity: 0.3;
}
</style>
<script src="33.js"></script>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn1');
var oDiv = document.getElementById('div1'); oBtn.onclick = function () {
// startMove(oDiv, 'width', 300);
// startMove(oDiv, 'height', 300);
startMove(oDiv, {width: 300, height: 300, opacity: 100}); //此时长和宽是同时运动的
};
//问题来了,如果不加此句“startMove(oDiv, 'height', 300);” 则div变宽,好像没什么问题;
//但是如果加上此句“startMove(oDiv, 'height', 300);” div只变长了,而未变宽,所以也就是说,
//不能让多个值同时变化,否则会出错,解决办法是:用json循环来修改运动框架,解决如上
};
</script>
</head>
<body>
<input id="btn1" type="button" value="运动"/>
<div id="div1"></div>
</body>
</html>
function getStyle(obj, name) {
if (obj.currentStyle) {
return obj.currentStyle[name];
} else {
return getComputedStyle(obj, false)[name];
}
} //32.js的改进版,json循环的使用
//startMove(oDiv, {width: 400, height: 400}) function startMove(obj, json, fnEnd) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
for (var attr in json) {
var cur = 0; if (attr == 'opacity') {
cur = Math.round(parseFloat(getStyle(obj, attr))*100); //乘以100符合咱们平时对opacity的设置
} else {
cur = parseInt(getStyle(obj, attr));
} var speed = (json[attr]-cur)/6;
speed = speed>0?Math.ceil(speed):Math.floor(speed); if (cur==json[attr]) {
clearInterval(obj.timer); if (fnEnd) fnEnd();//当参数传进来且运动结束后被调用
} else {
if (attr == 'opacity') {
obj.style.filter = 'alpha(opacity:'+(cur+speed)+')'; //IE透明度
obj.style.opacity = (cur+speed)/100; var oTxt = document.getElementById('txt1');
oTxt.value = obj.style.opacity;
} else {
obj.style[attr] = cur+speed+'px';
} }
}
}, 30);
}
33.js
说“33.js”是一个完美运动框架,那是因为在一般应用情况下,该运动框架是不会出现什么错误,但是若我们把“startMove(oDiv, {width: 300, height: 300, opacity: 100});”改为“startMove(oDiv, {width: 101, height: 300, opacity: 100});”也就是说,宽度只增加一个像素,高度仍然增加200像素,此时运行时,高度的增加会出现一些小错误,即不会增加到300px,原因是,系统不会自己搜索每个状态是不是已经达到目标值,而是只要有一个达到目标值,系统就把定时器关掉了,所以才会出现错误,改进方法如下:(其中改进版的“33-1.js”,才是真正意义上的完美运动框架)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>完美运动框架</title>
<style>
#div1{width: 100px;
height: 100px;
background: red;
filter: alpha(Opacity=30);
opacity: 0.3;
}
</style>
<script src="33-1.js"></script>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn1');
var oDiv = document.getElementById('div1'); oBtn.onclick = function () {
startMove(oDiv, {width: 101, height: 300, opacity: 100}, function () { //此时长、宽和透明度同时运动
alert("定时器已全部关闭!"); //该函数是检验程序是否运行完成的。
});
};
};
</script>
</head>
<body>
<input id="btn1" type="button" value="运动"/>
<div id="div1"></div>
</body>
</html>
function getStyle(obj, name) {
if (obj.currentStyle) {
return obj.currentStyle[name];
} else {
return getComputedStyle(obj, false)[name];
}
} function startMove(obj, json, fnEnd) {
clearInterval(obj.timer);
obj.timer = setInterval(function () { var bStop = true; //假设所有的值都已经到了 for (var attr in json) {
var cur = 0; if (attr == 'opacity') {
cur = Math.round(parseFloat(getStyle(obj, attr))*100); //乘以100符合咱们平时对opacity的设置
} else {
cur = parseInt(getStyle(obj, attr));
} var speed = (json[attr]-cur)/6;
speed = speed>0?Math.ceil(speed):Math.floor(speed); if (cur != json[attr]) //如果有一个值不等于目标值
bStop = false; // if (cur==json[attr]) {
// clearInterval(obj.timer);
//
// if (fnEnd) fnEnd();//当参数传进来且运动结束后被调用
// } else { // 改进提前关定时器的代码如下,先把之前关定时器的代码注释掉
if (attr == 'opacity') {
obj.style.filter = 'alpha(opacity:'+(cur+speed)+')'; //IE透明度
obj.style.opacity = (cur+speed)/100;
} else {
obj.style[attr] = cur+speed+'px';
} obj.style[attr] = cur+speed+'px';
// }
} if (bStop) { //如果bStop还是保持为true的话
clearInterval(obj.timer); if (fnEnd) fnEnd();
}
}, 30);
}
33-1.js
检测运动停止(标志变量) 例子:伸缩同时淡入淡出的菜单,如上
运动框架总结:
运动框架的演变过程:
startMove(iTarget) 运动框架 //学习入门
startMove(obj, iTarget) 多物体 //多出的参数“obj”可以任意指定让那个物体动起来
startMove(obj, attr, iTarget) 任意值 //可以任意指定一个物体动起来
startMove(obj, attr, iTarget, fn) 链式运动 //参数“fn”为当 前一次 运动结束之后,我们可以用“fn”再做一次运动
startMove(obj, json) 多值运动 //可以把多个值同时运动
startMove(obj, json, fn) 完美运动框架 //可以多值、多物体同时运动了
运动框架应用:
例:幻灯片
思想是:overflow=hidden,当显示 第0张图片时,top=0;当显示第1张图片时,第0张的top=-150;……当显示第n张图片时,第0张的top=-150*n;
链式运动:新浪微博
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>li淡出淡入</title>
<style>
*{margin: 0; padding: 0;}
#ul1{
width: 400px;
height: 400px;
border: 1px solid black;
margin: 10px auto;
overflow: hidden;
}
#ul1 li{
border-bottom: 1px #999 dashed;
padding: 4px;
list-style: none;
overflow: hidden;
filter: alpha(opacity:0);
opacity: 0;
}
</style>
<script src="33-1.js"></script>
<script>
window.onload = function () {
var oBtn = document.getElementById('btn1');
var oUl = document.getElementById('ul1');
var oTxt = document.getElementById('txt1'); oBtn.onclick = function () {
var oLi = document.createElement('li'); oLi.innerHTML = oTxt.value;
oTxt.value = ''; if (oUl.children.length>0){
oUl.insertBefore(oLi, oUl.children[0]);
} else {
oUl.appendChild(oLi);
} //运动
var iHeight = oLi.offsetHeight;
//先让高度展开
oLi.style.height = '0'; //链式运动的应用
startMove(oLi, {height: iHeight}, function () { //先是高度展开,然后淡出
startMove(oLi, {opacity: 100});
}); };
};
</script>
</head>
<body>
<textarea id="txt1" rows="4" cols="40"></textarea>
<button id="btn1">发布</button>
<ul id="ul1">
<li>asldfjkba</li>
</ul>
</body>
</html>