动画函数优化,为任意元素添加任意多个属性

注释:

  本篇文章封装了两个函数,

  ① 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按钮:

  

 

 

 

 

 

 

  

posted @ 2019-07-26 15:32  小小飞郭  阅读(271)  评论(0编辑  收藏  举报