動畫函數優化,爲任意元素添加任意多個屬性

註釋:javascript

  本篇文章封裝了兩個函數,css

  ① getStyle 方法:獲取任意元素任意一個屬性的值,兼容谷歌,火狐,IE瀏覽器html

  ② variableSpeedAnimate 方法:爲任意元素添加任意多個屬性,引入了回調函數,可在動畫結束後,執行新的操做。java

  注意:json

   parseInt("128px") = 128瀏覽器

   若是設置的屬性是 「opacity」,爲了取得整數值,避免計算機的精度問題,能夠採用「放大縮小」策略,即當前值和目標值放大相同倍數,設置屬性值時,縮小相同倍數函數

   若是設置的屬性是「zIndex」,不用直接漸變,直接將zIndex值設置成目標值便可測試

   屬性值是「zIndex」而不是「z-index」是由於瀏覽器計算後的樣式是「zIndex」,駝峯式命名法動畫

1、代碼ui

/**
 * 封裝緩動動畫,變速,爲任意元素添加任意多個屬性
 * @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)
}

2、測試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>

3、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];
}

4、效果圖

  初始圖:

    

  點擊400px按鈕:

    

    

 

  

  點擊800px按鈕:

  

相關文章
相關標籤/搜索