实现动画效果可以用jQuery提供的animate方法,或一些插件来实现,但是随着前端组件化开发的流行,
jQuery大量的DOM操作已经显得十分多余,正在逐渐从前端技术栈中被淘汰,下面我们使用原生js实现简单的匀速动画效果和缓动效果
匀速动画实现水平移动
css样式
<style>
#box {
width: 100px;
height: 100px;
background-color: pink;
position: absolute;
top: 100px;
left: 0px;
}
.line400 {
width: 1px;
height: 100px;
background-color: red;
position: absolute;
left: 400px;
top: 100px;
}
.line800 {
width: 1px;
height: 100px;
background-color: red;
position: absolute;
left: 800px;
top: 100px;
}
</style>
html结构和js代码
<body>
<div id="box"></div>
<div class="line400"></div>
<div class="line800"></div>
<input type="button" value="右移400" id="r1">
<input type="button" value="右移800" id="r2">
<script>
var box = document.getElementById("box");
var box2 = document.getElementById("box2");
var btnR1 = document.getElementById("r1");
var btnR2 = document.getElementById("r2");
btnR1.onclick = function () {
Animation(box, 400);
};
btnR2.onclick = function () {
Animation(box, 800);
};
// 封装动画函数
function Animation(ele, target) {
// 先清除动画
clearInterval(ele.tid);
// 获取当前位置
var currentLeft = ele.offsetLeft;
// 判断左移右移
var isLeft = (currentLeft < target);
// 开启定时器
ele.tid = setInterval(function () {
// 移动
currentLeft = isLeft ? currentLeft + 10 : currentLeft - 10;
ele.style.left = currentLeft + "px";
// 边界检测
if (isLeft ? currentLeft >= target : currentLeft <= target) {
// 停止运动
clearInterval(ele.tid);
// 元素复位
ele.style.left = target + "px";
}
}, 50)
}
</script>
</body>
缓速运动 : 每次移动的距离 = (目标位置 - 当前位置) / 10
特点:没有误差,准确到达目标位置后期接近目标都是1px移动 不会有误差,但还需要清除定时器 终点检测
还是上面的样式结构
js代码
<body>
<div id="box"></div>
<div class="line400"></div>
<div class="line800"></div>
<input type="button" value="缓速移动400" id="r1">
<input type="button" value="缓速移动800" id="r2">
<script>
var box = document.getElementById("box");
var btn1 = document.getElementById("r1");
var btn2 = document.getElementById("r2");
btn1.onclick = function () {
slowMove(box, 400);
}
btn2.onclick = function () {
slowMove(box, 800);
}
// 缓动距离方法
function slowMove(ele, target) {
clearInterval(ele.tid);
// 获取元素当前位置
var currentLeft = ele.offsetLeft;
ele.tid = setInterval(function () {
// 缓速速度
var speed = (target - currentLeft) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
// 缓速移动
currentLeft += speed;
// 设置元素的位置
ele.style.left = currentLeft + "px";
// 终点检测
if (currentLeft == 400) {
clearInterval(ele.tid);
}
}, 10)
}
</script>
</body>
效果:
以上动画方法只能实现简单的属性(带px单位)动画
要实现其他属性的动画要先了解一个获取属性的方法
getComputedStyle() : 获取元素所有样式 全局方法(IE8不支持)
参数1: 要获取样式的对象
参数2: 伪元素 ,一般不传 默认为null
返回值: 样式对象
特点:
1.可以获取行内样式,也可以获取行外样式
2.获取的是string类型 带单位
3.获取的元素只读,不可修改
ie8使用currentStyle属性
这里做一下兼容
// 获取元素属性的IE8兼容
/**
@param ele 需要查询的元素
@param attr 需要获取到的属性 string类型
*/
function getEleStyle(ele,attr){
if(window.getComputedStyle){ // 标准
var style = getComputedStyle(ele,null);
return style[attr];
}else{ // ie8
return ele.currentStyle[attr];
}
}
实现多属性缓动效果封装函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: pink;
position: absolute;
top: 100px;
left: 0px;
}
#box1{
width: 100px;
height: 100px;
background-color: #000;
position: absolute;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<div id="box"></div>
<div id="box1"></div>
<input type="button" value="缓速移动属性" id="r2">
<script src="animation.js"></script>
<script>
var box = document.getElementById("box");
var btn1 = document.getElementById("r1");
var btn2 = document.getElementById("r2");
btn2.onclick = function () {
slowMove(box, {
width: 200,
height: 300
}, function () {
slowMove(box, {
width: 100,
height: 100
}, function () {
slowMove(box, {
left: 200,
zIndex:2
},function(){
slowMove(box,{
opacity:0
},function(){
slowMove(box,{
opacity:1
})
})
})
})
});
}
// 缓动属性方法
function slowMove(obj, attrs, callback) {
clearInterval(obj.tid);
// 开启定时器
obj.tid = setInterval(function () {
// 所有属性是否到达终点变量
var isAll = true; // 1.提出假设
// 遍历所有属性
for (var key in attrs) {
var attr = key; // 属性名
var target = attrs[key]; // 属性值
if (attr == "zIndex" || attr == "backgroundColor") {
obj.style[attr] = target;
} else if (attr == "opacity") {
// 透明度是小数 不适合运算 所以扩大100倍
var current = parseFloat(getEleStyle(obj, attr)) * 100;
var speed = (target * 100 - current) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
current += speed;
obj.style[attr] = current / 100;
if (current != target) {
isAll = false;
}
} else {
// 获取元素当前位置 getComputedStyle方法获取到的是带单位的字符串
var current = parseInt(getEleStyle(obj, attr));
// 缓速速度 (目标位置 - 当前位置) / 10
var speed = (target - current) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
// 缓速移动
current += speed;
// 设置元素的位置
obj.style[attr] = current + "px";
// 终点检测
if (current != target) { // 2.验证假设
isAll = false;
}
}
}
// 当所有属性都到达终点时再清除定时器
if (isAll) { // 3.根据变量结果做出操作
clearInterval(obj.tid);
// 调用回调函数
if (callback) {
setTimeout(function () {
callback();
}, 1000)
}
}
}, 10)
}
// 获取元素属性的IE8兼容
/**
@param ele 需要查询的元素
@param attr 需要获取到的属性 string类型
*/
function getEleStyle(ele, attr) {
if (window.getComputedStyle) { // 标准
var style = getComputedStyle(ele, null);
return style[attr];
} else { // ie8
return ele.currentStyle[attr];
}
}
</script>
</body>
</html>