// 1. css样式
div {
width: 100px;
height: 100px;
background: olivedrab;
position: absolute;
left: 0px;
opacity: 1;
}
.top {
top: 100px;
}
.bottom {
top: 300px;
}
// html和JavaScript代码
<div class="top">div> <div class="bottom" style="background-color: coral;">div> <script> // 多物体多值链式运动框架 // 获取对象样式相对应属性的值 var targetObj = { width: 400, height: 400, opacity: 50, left: 300, top: 200 } // 获取对应的HTML元素 oDivArray = document.getElementsByTagName('div'); // 调用函数 oDivArray[0].onclick = function() { startMove(this, targetObj, function() { startMove(oDivArray[1], targetObj); }); } // 获取元素样式对应的属性值 function getStyle(obj, attr) { if (obj.currentStyle) { return obj.currentStyle[attr]; } else { return window.getComputedStyle(obj, false)[attr]; } } // 封装动画函数 function startMove(obj, json, callback) {
// 清除目标对象的定时器,而非全局 clearInterval(obj, timer);
// iSpeed:动画速度,iCur:当前样式属性的值,timer:定时器对象 var iSpeed, iCur, timer; obj.timer = setInterval(function() { var bStop = true; // 标志位,上一个对象的动画是否完成 for (var attr in json) { if (attr === 'opacity') { // 如果获取的是opacity,则乘100倍,否则正常获取值 iCur = parseFloat(getStyle(obj, attr)) * 100; } else { iCur = parseInt(getStyle(obj, attr)); } iSpeed = (json[attr] - iCur) / 7; iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); //设置动画速度 if (attr == 'opacity') { obj.style.opacity = (iCur + iSpeed) / 100; // 乘100的值还原回去 } else { obj.style[attr] = iCur + iSpeed + 'px'; } if (iCur != json[attr]) { // 如果当前属性的值不等于用户穿进来的对象里的属性对应的值,则继续执行动画 bStop = false; } else { // 达到期待的目标,设置标志位为真,即可以停止 bStop = true; } } if (bStop) { clearInterval(obj.timer); //如果标志位为真,则达到用户期待的动画效果 typeof callback == 'function' ? callback() : '';// 判断用户是否有传入回调函数,有则执行,无则结束。链式动画执行框架 } }, 30) } script>
end