<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div id="box"></div>
<script src="js/move.js"></script>
<script>
// 点击box,让它的宽和高同时到500
var box = document.getElementById('box');
box.onclick = function () {
move(box, {
width: 500,
height: 300,
opacity: 30,
left: 500,
top: 200
}, function () {
console.log('我到了');
})
}
</script>
</body>
</html>
function getStyle(ele, attr) {
if (window.getComputedStyle) {
// 标准浏览器
return getComputedStyle(ele)[attr];
} else {
// IE8及以下
return ele.currentStyle[attr];
}
}
// 元素 属性 目标 回调
function move(ele, json, callback) {
clearInterval(ele.timer); // 先清
// 再开
ele.timer = setInterval(function () {
var onOff = true; // 建一个开关
// 在for-in的里面,如果某一个属性没有到,则把开关变为假
for (var attr in json) { // 删掉的attr和target又回来了
var target = json[attr];
// 当前位置
if (attr === 'opacity') {
var now = getStyle(ele, 'opacity') * 100;
} else {
var now = parseInt(getStyle(ele, attr));
}
var dir = (target - now) / 10; // 方向 缓冲运动
// 如果大于0,向上取整,否则向下取整
dir = dir > 0 ? Math.ceil(dir) : Math.floor(dir);
now += dir; // 下次应该运动到的位置
if ((now >= target && dir > 0) || (now <= target) && dir < 0) {
now = target;
}
// 设置值
if (attr === 'opacity') {
ele.style.opacity = now / 100;
ele.style.filter = 'alpha(opacity=' + now + ')';
} else {
ele.style[attr] = now + 'px';
}
if (now !== target) {
onOff = false;
}
}
if (onOff) { // 如果开关是真的,则清定时器并执行回调
clearInterval(ele.timer);
callback && callback();
}
}, 30);
}