动画函数优化,为任意元素添加任意多个属性
注释:
本篇文章封装了两个函数,
① getStyle 方法:获取任意元素任意一个属性的值,兼容谷歌,火狐,IE浏览器
② variableSpeedAnimate 方法:为任意元素添加任意多个属性,引入了回调函数,可在动画结束后,执行新的操作。
注意:
parseInt("128px") = 128
如果设置的属性是 “opacity”,为了取得整数值,避免计算机的精度问题,可以采用“放大缩小”策略,即当前值和目标值放大相同倍数,设置属性值时,缩小相同倍数
如果设置的属性是“zIndex”,不用直接渐变,直接将zIndex值设置成目标值即可
属性值是“zIndex”而不是“z-index”是因为浏览器计算后的样式是“zIndex”,驼峰式命名法
一、代码
/** * 封装缓动动画,变速,为任意元素添加任意多个属性 * @param {*} element 元素 * @param {*} json css属性键值对,例如{"width":200,"height":100,"zIndex":100,"opacity":0.3} * @param {*} fn 回调函数,动画结束,调用回调函数 */ function variableSpeedAnimate(element, json, fn) { clearInterval(element.timeId); element.timeId = setInterval(function () { var reachTarget = true; for (const attr in json) { if (attr == "zIndex") { element.style[attr] = json[attr]; } else if (attr == "opacity") { var current = getStyle(element, attr) * 100; var target = json[attr] * 100; var step = (target - current) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); current += step; element.style[attr] = current / 100; if (current != target) { reachTarget = false; } } else { var current = parseInt(getStyle(element, attr)); var target = json[attr]; var step = (target - current) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); current += step; element.style[attr] = current + "px"; if (current != target) { reachTarget = false; } } } if (reachTarget) { clearInterval(element.timeId); if (fn) { fn(); } } }, 20) }
二、测试deno
<!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> div { width: 200px; height: 100px; position: absolute; left: 0px; top: 0; border: 1px solid yellow; background-color: pink; z-index: 0; } input { position: relative; z-index: 99; } </style> </head> <body> <input type="button" value="400px" id="btn" /> <input type="button" value="800px" id="btn1" /> <div id="dv"></div> <script src="./js/common.js"></script> <script> // 400按钮点击事件 my$("btn").onclick = function () { var json = {"width":400,"left":200,"top":150,"opacity":0.6}; animate(my$("dv"), json,function(){ var json1 = { "width":400,"left":500,"top":250,"opacity":0.3}; animate(my$("dv"), json1,function(){ var json2 = {"width":200,"left":0,"top":0,"opacity":1,"zIndex":100}; animate(my$("dv"), json2); }) }); }; // 800按钮点击事件 my$("btn1").onclick = function () { animate(my$("dv"), {'left':800}); }; // 封装动画缓冲函数,变速 function animate(element, json, fn) { clearInterval(element.timeId); element.timeId = setInterval(function () { var reachTarget = true; for (const attr in json) { if (attr == "zIndex") { element.style[attr] = json[attr]; } else if (attr == "opacity") { var current = getStyle(element, attr) * 100; var target = json[attr] * 100; var step = (target - current) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); current += step; element.style[attr] = current / 100; if (current != target) { reachTarget = false; } } else { var current = parseInt(getStyle(element, attr)); var target = json[attr]; var step = (target - current) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); current += step; element.style[attr] = current + "px"; if (current != target) { reachTarget = false; } } } if (reachTarget) { clearInterval(element.timeId); if (fn) { fn(); } } }, 20) } </script> </body> </html>
三、common.js
/*根据id获取元素对象*/ function my$(id) { return document.getElementById(id); } /** * 获取任意一个元素的任意一个属性值 * @param {*} element 元素 * @param {*} attr 属性值,字符串格式,例如'width'... */ function getStyle(element, attr) { return window.getComputedStyle ? window.getComputedStyle(element, null)[attr] : element.currentStyle[attr]; }
四、效果图
初始图:
点击400px按钮:
点击800px按钮: