JavaScript - WebAPI - 定时器/延时器/匀速动画/getElementStyle获取全部样式/缓速动画及缓速动画函数封装

定时器作用及语法

💥💥💥💥💥 :定时器的使用与清除定时器,以下 1.1 ~1.3 为验证过程,不推荐使用
推荐使用 🎈🎈🎈 : 1.2缓速动画介绍

1.1-setInterval 定时器

定时器:某一件事(一段代码)并不是马上执行,而是隔一段时间执行

  • setInterval:创建定时器
    • 特点:一旦创建立即计时,必须要手动停止,否则会无限的每隔一段时间执行代码
  • clearInterval(定时器id):清除定时器
    • 一个页面可以创建很多个定时器,通过制定定时器id可以清除特定的定时器
<!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>定时器</title>
        <style>
            .box {
                position: absolute;
                left: 0;
                top: 0;
                width: 100px;
                height: 100px;
                background-color: rgb(235, 12, 49);
            }
        </style>
    </head>
    <body>
        <div class="box"></div>
    </body>
    <script>
        // 定时器:setInterval(回调函数,间隔时间:ms)

        console.log("定时器开始了");

        setInterval(function () {
            console.log("宝,早安");
        }, 1000);

        console.log("定时器结束了");

        // 非定时器代码:叫主代码
        // 主代码一定是先执行(不论时间多长,后草开始定时器的执行(等主代码执行结束后:才开始计时))

        setInterval(function () {
            console.log("晚安");
        }, 1500);

        // 一个页面可以有多个定时器:彼此之间独立,互不影响

        // 动画效果:效果  结合 定时器
        // 点击盒子:盒子每次移动10px,移动到600结束

        document.querySelector(".box").onclick = function () {
            let box = this;

            // 开一个定时器
            setInterval(function () {
                // 判定是否到600
                if (box.offsetLeft < 600) {
                    box.style.left = box.offsetLeft + 10 + "px";
                }
            }, 100);
        };
    </script>
</html>

清除定时器

<!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>定时器 - 清除定时器</title>
        <style>
            .box {
                position: absolute;
                left: 0;
                top: 0;
                width: 100px;
                height: 100px;
                background-color: rgb(235, 12, 49);
            }
        </style>
    </head>
    <body>
        <div class="box"></div>
    </body>
    <script>
        // 需求: 移动到600结束

        // 清理定时器: clearInterval(句柄: 定时器序号)
        // 定时器setInterval()会返回一个句柄: 定时器序号

        const box = document.querySelector(".box");
        console.log(box);

        box.onclick = function () {
            // 动画:必须开启定时器
            let timeId = setInterval(function () {
                console.log("定时器开始了");

                // 动画
                box.style.left = box.offsetLeft + 10 + "px";

                // 判定安全
                if (box.offsetLeft >= 600) {
                    // 清除定时器
                    clearInterval(timeId);
                }
            }, 100);

            console.log(timeId);
            // 清理定时器: clearInterval(句柄: 定时器序号)
            // clearInterval(timeId);
        };

        // 定时器:可以清理(一般是达到条件之后才清理)
    </script>
</html>

1.2-setTimeout 延时器

  • 定时器setTimeout与setInterval唯一的区别是,setTimeout定时器只会执行一次
  • 总结:
    • 1.如果你想让这个代码一段时间后只执行一次,使用setTimeout
    • 2.如果你想让这个代码每隔一段时间执行一次(执行多次),使用setInterval
<!DOCTYPE html>
<html lang="zh-CN">
    <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>延时器 - 广告</title>
        <style>
            .adv {
                position: fixed;
                left: 10%;
                top: 10%;

                width: 80%;
                height: 80%;
                background-color: pink;

                display: none;
            }

            .txt {
                position: absolute;
                left: 40%;
                top: 40%;
            }

            .close {
                position: absolute;
                right: 0;
            }
        </style>
    </head>

    <body>
        <div class="adv">
            <div class="txt">这是一则广告</div>
            <div class="close">
                广告剩余时间<span>5</span><button>X</button>
            </div>
        </div>

        <script>
            // 需求:5秒展开广告, 用户点击关闭, 也可以看20s自动关闭

            // 获取元素
            const adv = document.querySelector(".adv");
            const time = document.querySelector(".close span");
            const btn = time.nextElementSibling;
            console.log(adv, time, btn);

            // 延时器: 5秒钟后开启广告, setTimeout(回调函数,时间间隔)
            setTimeout(function () {
                adv.style.display = "block";

                // 开启定时器:关闭广告
                let timeId = setInterval(function () {
                    time.innerText--;

                    // 判定:清除定时器
                    if (time.innerText == 0) {
                        clearInterval(timeId);
                        adv.style.display = "none";
                    }
                }, 1000);

                // 3.点击关闭
                btn.onclick = function () {
                    // 是会员才行
                    // 结束广告(主动清理定时器)
                    clearInterval(timeId);
                    adv.style.display = "none";
                };
            }, 5000);
        </script>
    </body>
</html>

1.2-动画介绍(匀速动画)

  • 需求:点击开始按钮,让div向右移动800px ,动画效果
  • 动画可以理解为物理中的运动,运动三要素:v = s/t (速度 = 距离/时间)
    • 如果没有时间因素,则会造成瞬移效果
  • 1.如果直接修改div的left值就会瞬间移动,没有动画效果
  • 2.动画效果:让div的left值每隔一段时间向右移动一点,直到移动800为止
<!DOCTYPE html>
<html lang="zh-CN">
    <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>匀速效果 - 动画</title>
        <style>
            .box {
                position: absolute;
                left: 0;
                top: 200px;

                width: 100px;
                height: 100px;
                background-color: red;
            }
        </style>
    </head>

    <body>
        <button class="to600">移动到600</button>
        <button class="to0">移动到0</button>

        <div class="box"></div>

        <script>
            // 需求1: 点击移动到600,盒子匀速移动到600(10px/100ms)

            const box = document.querySelector(".box");

            document.querySelector(".to600").onclick = function () {
                // 定时器
                let timeId = setInterval(function () {
                    // 移动10px
                    box.style.left = box.offsetLeft + 10 + "px";

                    // 结束
                    if (box.offsetLeft >= 600) {
                        // 回调: 不能超过600
                        box.style.left = 600 + "px";

                        clearInterval(timeId);
                    }
                }, 20);
            };

            document.querySelector(".to0").onclick = function () {
                // 定时器
                let timeId = setInterval(function () {
                    // 移动10px
                    box.style.left = box.offsetLeft - 10 + "px";

                    // 结束
                    if (box.offsetLeft <= 0) {
                        // 回调: 不能超过0
                        box.style.left = 0 + "px";

                        clearInterval(timeId);
                    }
                }, 20);
            };

            // 总结
            // 1. 匀速运动: 要注意移动的步长是否能够支持刚好走到目标(不是刚好,需要回调)
        </script>
    </body>
</html>

1.3-动画介绍(匀速动画)防抖

<!DOCTYPE html>
<html lang="zh-CN">
    <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>匀速效果 - 动画防抖</title>
        <style>
            .box {
                position: absolute;
                left: 0;
                top: 200px;

                width: 100px;
                height: 100px;
                background-color: red;
            }
        </style>
    </head>

    <body>
        <button class="to600">移动到600</button>
        <button class="to0">移动到0</button>

        <div class="box"></div>

        <script>
            // 需求1: 点击移动到600,盒子匀速移动到600(10px/100ms)

            // 获取相关元素
            const to600 = document.querySelector(".to600");
            const to0 = document.querySelector(".to0");
            const box = document.querySelector(".box");
            console.log(to600, to0, box);

            // 防抖方案1:把保存的定时器变量 全局化 : 只要这个元素有定时器.都共用一个变量保存

            // let timeId;  //  不允许页面存在多个动画(否则需要多个变量)

            // 💥 防抖方案2:把定时器的变量  私有化 :只有自己能访问到,别的元素永远访问不到

            // 元素.tiemId = 定时器  给元素增加一个属性:tiemId 保存定时器

            // 点击 to600 移动盒子  到600 停止动画

            to600.onclick = function () {
                // 清理原来的定时器
                clearInterval(box.timeId);
                // 定时器动画
                box.timeId = setInterval(function () {
                    // 开始移动,移动5px
                    box.style.left = box.offsetLeft + 5 + "px";
                    // 判定
                    if (box.offsetLeft > 600) {
                        // 到达终点,清除定时器
                        clearInterval(box.timeId);
                        box.style.left = "600px";
                    }
                }, 10);
            };

            // 点击 to0 移动盒子  到0 停止动画
            to0.onclick = function () {
                // 清理原来的定时器
                clearInterval(box.timeId);
                // 定时器动画
                box.timeId = setInterval(function () {
                    // 开始动画,移动5px
                    box.style.left = box.offsetLeft - 5 + "px";
                    // 判定
                    if (box.offsetLeft < 0) {
                        // 到达终点,清除定时器
                        clearInterval(box.timeId);
                        box.style.left = "0px";
                    }
                }, 10);
            };

            // box.timeId && clearInterval(box.timeId);

            // 总结
            // 1. 匀速运动: 要注意移动的步长是否能够支持刚好走到目标(不是刚好,需要回调)
        </script>
    </body>
</html>

01-getComputedStyle()获取元素一切样式属性

元素属性操作特点应用场景
点语法可以修改任意样式,无法获取行外样式修改元素样式
attribute操作自定义样式操作自定义样式
getComputedStyle()不可以修改样式,可以获取任意样式(行内+行外)获取元素样式
element.currentStyle与getComputedStyle一致(仅限IE8及以前使用)获取元素样式
  • 语法: window.getComputedStyle(元素,伪元素)
    • 返回值:对象类型(存储元素一切样式属性)
<!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>获取全部样式</title>
        <style>
            .box {
                width: 100px;
                height: 200px;
                background-color: #6cf;
                opacity: 0.5;
            }
            .box::after {
                content: "我是伪类信息";
            }
        </style>
    </head>
    <body>
        <div class="box"></div>
    </body>
    <script>
        // 获取全局样式:window.getComputedStyle(元素),是window下的一个方法

        // 全局样式: 具体样式获取   getComputedStyle(元素).具体样式 || getComputedStyle(元素)[具体样式]

        // 如果要拿到伪类样式: getComputedStyle(元素,'伪类') : 此时只能拿到伪类

        // 获取元素
        const box = document.querySelector(".box");

        // 获取元素的全局样式
        // const styles = getComputedStyle(box);
        // console.log(styles);

        // 获取元素的透明度
        let op = getComputedStyle(box)["opacity"];
        op = parseFloat(op);
        // box.style.opacity = op + 0.1;
        // console.log(box.style.opacity);

        // 点击事件
        box.onclick = function () {
            let op = getComputedStyle(box)["opacity"];
            op = parseFloat(op);
            box.style.opacity = op + 0.1;
            console.log(box.style.opacity);
        };
    </script>
</html>

02-缓速动画封装

1.1-缓动动画介绍

  • 缓动动画核心计算公式: 本次需要移动距离 = (目标距离 - 当前距离)/10
<!DOCTYPE html>
<html lang="zh-CN">
    <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>缓速移动</title>
        <style>
            .box {
                position: absolute;
                left: 0;
                top: 200px;

                width: 100px;
                height: 100px;
                background-color: red;
            }
        </style>
    </head>

    <body>
        <button class="to600">移动到600</button>
        <button class="to0">移动到0</button>

        <div class="box"></div>

        <script>
            // 需求1: 点击移动到600,盒子缓速移动到600(先快后慢)
            // 主要逻辑:计算移动距离  (目标 - 当前位置) * 0.1

            // 获取相关元素
            const to600 = document.querySelector(".to600");
            const to0 = document.querySelector(".to0");
            const box = document.querySelector(".box");
            console.log(to600, to0, box);

            // 点击 to600 移动盒子  盒子缓速移动到600

            to600.onclick = function () {
                // // 清理原来的定时器
                // clearInterval(box.timeId);

                // 💥💥💥  短路运算:清理定时器(如果有box.timeId这个函数,就执行 && 后面的代码:清理定时器;如果没有这个函数,就算了~)
                box.timeId && clearInterval(box.timeId);
                // 定时器动画
                box.timeId = setInterval(function () {
                    // 1. 找到当前自己的位置: getComputedStyle()
                    let current = getComputedStyle(box)["left"];
                    // 2. 字符串转数字
                    current = parseInt(current);
                    // console.log(current);
                    // 3. 计算步长 (目标 - 当前位置) * 0.1
                    let step = (600 - current) * 0.1;
                    // 💥 4.让像素一定为整数:不能是小数(往大变化:向上取整)
                    step = Math.ceil(step);
                    console.log(step);
                    // 💥 5. 判定是否达到了目标位置: 达到就清除   不要用目标判定: 用步长
                    if (step == 0) {
                        clearInterval(box.timeId);
                    }
                    // 6. 移动元素:当前位置 + 步长 + 单位
                    box.style.left = current + step + "px";
                }, 10);
            };

            // 点击 to0 移动盒子  到0 停止动画
            to0.onclick = function () {
                // // 清理原来的定时器
                // clearInterval(box.timeId);
                // 💥💥💥  短路运算:清理定时器(如果有box.timeId这个函数,就执行 && 后面的代码:清理定时器;如果没有这个函数,就算了~)
                box.timeId && clearInterval(box.timeId);
                // 定时器动画
                box.timeId = setInterval(function () {
                    // 找到元素当前位置,getComputedStyle()
                    let current = getComputedStyle(box)["left"];
                    // 字符串转数字,方便计算
                    current = parseInt(current);
                    // 计算步长(目标距离 - 当前位置) * 0.1
                    let step = (0 - current) * 0.1;
                    // 💥 像素一定为整数,不能是小数(往下变化;向下取整)
                    step = Math.floor(step);
                    console.log(step);
                    // 判定是否到达目标位置.到达就清除.不要用目标判定 用步长
                    if (step == 0) {
                        clearInterval(box.timeId);
                    }
                    // 移动元素 : 当前位置 + 步长 + 单位
                    box.style.left = current + step + "px";
                }, 10);
            };
        </script>
    </body>
</html>

1.2 缓速动画函数封装

不限元素 - 不限距离 - 不限方向

<!DOCTYPE html>
<html lang="zh-CN">
    <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>缓速动画 - 函数封装 - 不限元素 - 不限距离 - 不限方向</title>
        <style>
            div {
                width: 100px;
                height: 100px;
                background-color: red;
            }

            .box {
                position: absolute;
                left: 0;
                top: 50px;
            }

            .box1 {
                position: absolute;
                left: 0;
                top: 200px;
                background-color: greenyellow;
            }
        </style>
    </head>

    <body>
        <button class="to600">移动到600</button>
        <button class="to0">移动到0</button>
        <button class="to400">移动到400</button>

        <div class="box"></div>
        <div class="box1"></div>
    </body>
    <script>
        // 获取相关元素
        const to600 = document.querySelector(".to600");
        const to0 = document.querySelector(".to0");
        const to400 = document.querySelector(".to400");

        const box = document.querySelector(".box");
        const box1 = document.querySelector(".box1");

        console.log(to600, to0, to400, box, box1);

        // to600点击事件
        to600.onclick = function () {
            // 调用函数(版本1.)
            // animation();

            // 调用含糊(版本2. : 传入元素)
            // animation(box);

            // 调用函数(版本3. : 传入目标)
            animation(box, 600);
        };

        // to4oo点击事件
        to400.onclick = function () {
            // 调用函数(版本3. 传入元素,传入目标)
            animation(box1, 400);
        };

        // to0点击事件
        to0.onclick = function () {
            // 调用函数(版本3. 传入元素,传入目标)
            // 🎃 再升级,函数内部像素一定为整数, 🎈: 往上变化,向上取整; 🎈: 往下变化,向下取整
            animation(box, 0);
            animation(box1, 0);
        };

        // 代码重复率太高: 封装

        // 定义函数,调用函数; 实现灵活性: 参数
        // 1. 传入参数: 动画元素由外部传入, ele
        // 2. 传入参数: 动画元素目标位置由外部传入, target
        // 3. 修正取整逻辑: 判定step的正负即可(正向上,负向下)

        function animation(ele, target) {
            // 短路运算,清除原来存在的定时器
            ele.timeId && clearInterval(ele.timeId);

            // 定时器动画
            ele.timeId = setInterval(function () {
                // 1. 获取元素当前的位置,获取样式先
                let current = getComputedStyle(ele)["left"];
                current = ele.offsetLeft;

                // 字符串转数字,方便计算
                current = parseInt(current);

                // 2. 计算步长(目标距离 - 当前位置) * 0.1
                let step = (target - current) * 0.1;

                // 像素一定为整数,(往大变化,向上取整)
                // 🎃 再升级,函数内部像素一定为整数, 🎈: 往上变化,向上取整; 🎈: 往下变化,向下取整
                if (step > 0) step = Math.ceil(step);
                else step = Math.floor(step);

                // 3. 判定 是否到达目标位置,到达了就清除  用步长判定
                if (step == 0) {
                    clearInterval(ele.timeId);
                }

                // 4. 开始移动. 最终位置 = 元素当前位置 + 步长 + 单位
                ele.style["left"] = current + step + "px";
            }, 10);
        }
    </script>
</html>

不限属性

<!DOCTYPE html>
<html lang="zh-CN">
    <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>缓速动画 - 函数封装 - 不限属性</title>
        <style>
            div {
                width: 100px;
                height: 100px;
                background-color: red;
            }

            .box {
                position: absolute;
                left: 0;
                top: 50px;
            }

            .box1 {
                position: absolute;
                left: 0;
                top: 200px;
                background-color: greenyellow;
            }
        </style>
    </head>

    <body>
        <button class="to600">移动到600</button>
        <button class="to0">移动到0</button>
        <button class="to400">移动到400</button>

        <div class="box"></div>
        <div class="box1"></div>
    </body>
    <script src="./js/animat.js"></script>
    <script>
        // 获取相关元素
        const to600 = document.querySelector(".to600");
        const to0 = document.querySelector(".to0");
        const to400 = document.querySelector(".to400");

        const box = document.querySelector(".box");
        const box1 = document.querySelector(".box1");

        console.log(to600, to0, to400, box, box1);

        // to600点击事件
        to600.onclick = function () {
            animation(box, 1200, "left"); // 传入动画属性: 需要引号
        };

        // to4oo点击事件
        to400.onclick = function () {
            // top方向变化
            animation(box1, 400, "top");
            // 宽度变化
            // animation(box1, 400, "width");
        };

        // to0点击事件
        to0.onclick = function () {
            animation(box, 0, "left");
        };
    </script>
</html>

缓速动画函数封装 js文件

// // 代码重复率太高: 封装

//         // 定义函数,调用函数; 实现灵活性: 参数
//         // 1. 传入参数: 动画元素由外部传入, ele
//         // 2. 传入参数: 动画元素目标位置由外部传入, target
//         // 3. 修正取整逻辑: 判定step的正负即可(正向上,负向下)
//         // 传入参数:动画的属性(left/top/width/height)由外部传入,style:所有以px为单位的都可以使用

//         function animation(ele, target,style) {
//             // 短路运算,清除原来存在的定时器
//             ele.timeId && clearInterval(ele.timeId);

//             // 定时器动画
//             ele.timeId = setInterval(function () {
//                 // 1. 获取元素当前的位置
//                 let current = getComputedStyle(ele)[style];

//                 // 字符串转数字,方便计算
//                 current = parseInt(current);

//                 // 2. 计算步长(目标距离 - 当前位置) * 0.1
//                 let step = (target - current) * 0.1;

//                 // 像素一定为整数,(往大变化,向上取整)
//                 // 🎃 再升级,函数内部像素一定为整数, 🎈: 往上变化,向上取整; 🎈: 往下变化,向下取整
//                 if (step > 0) step = Math.ceil(step);
//                 else step = Math.floor(step);

//                 // 3. 判定 是否到达目标位置,到达了就清除  用步长判定
//                 if (step == 0) {
//                     clearInterval(ele.timeId);
//                 }

//                 // 4. 开始移动. 最终位置 = 元素当前位置 + 步长 + 单位
//                 ele.style[style] = current + step + "px";
                
//                 // 但凡不是独立的:一定是属性
//                 // ele.style  :  元素ele的行内样式
//                 // [style] : 独立一定代表变量 
//             }, 10);
//         }







// 代码重复率太高: 封装

        // 定义函数,调用函数; 实现灵活性: 参数
        // 1. 传入参数: 动画元素由外部传入, ele
        // 2. 传入参数: 动画元素目标位置由外部传入, target
        // 3. 修正取整逻辑: 判定step的正负即可(正向上,负向下)
        // 传入参数:动画的属性(left/top/width/height)由外部传入,style:所有以px为单位的都可以使用

        function animation(ele, target,style,fn) {
            // 短路运算,清除原来存在的定时器
            ele.timeId && clearInterval(ele.timeId);

            // 定时器动画
            ele.timeId = setInterval(function () {
                // 1. 获取元素当前的位置
                let current = getComputedStyle(ele)[style];

                // 字符串转数字,方便计算
                current = parseInt(current);

                // 2. 计算步长(目标距离 - 当前位置) * 0.1
                let step = (target - current) * 0.1;

                // 像素一定为整数,(往大变化,向上取整)
                // 🎃 再升级,函数内部像素一定为整数, 🎈: 往上变化,向上取整; 🎈: 往下变化,向下取整
                if (step > 0) step = Math.ceil(step);
                else step = Math.floor(step);

                // 3. 判定 是否到达目标位置,到达了就清除  用步长判定
                if (step == 0) {
                    clearInterval(ele.timeId);

                    // 调用函数即可
                    // console.log(fn);
                    // fn()

                    // 上述方式直接调用:如果用户没有传入回调函数,代码报错
                    // 安全处理:是函数才调用
                    console.log(typeof fn);  // typeof 可以判定函数:function字符串

                    if(typeof fn === 'function')  fn()
                }

                // 4. 开始移动. 最终位置 = 元素当前位置 + 步长 + 单位
                ele.style[style] = current + step + "px";
                
                // 但凡不是独立的:一定是属性
                // ele.style  :  元素ele的行内样式
                // [style] : 独立一定代表变量 
            }, 10);
        }

连续动画

<!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>缓速动画 - 函数封装 - 连续动画</title>
        <style>
            .box {
                position: absolute;
                left: 0;
                top: 50px;

                width: 200px;
                height: 200px;
                background-color: rgb(0, 255, 255);
            }
        </style>
    </head>
    <body>
        <button>转个圈</button>
        <div class="box"></div>
    </body>
    <script src="./js/animation.js"></script>
    <script>
        const box = document.querySelector(".box");
        const btn = document.querySelector("button");

        btn.onclick = function () {
            // 1. 让盒子移动到600 left
            animation(box, 600, "left", function () {
                // 2. 让盒子移动到400 top
                animation(box, 400, "top", function () {
                    // 3. 让盒子移动到 0 left
                    animation(box, 0, "left", function () {
                        // 4. 让盒子移动到 50   top
                        animation(box, 50, "top"); //  可以无限套娃
                    });
                });
            });
        };
    </script>
</html>

函数封装 - 淡入淡出动画

<!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>缓速动画 - 函数封装 - 淡入淡出动画</title>
        <style>
            img {
                opacity: 1;
            }
        </style>
    </head>
    <body>
        <img src="./images/slidepic2.jpg" alt="" />
    </body>
    <script>
        // 需求:点击一下图片,图片透明度降低到0.3(慢慢降低)
        // 然后切换一张图片, 重新透明度变成1

        // 需要额外封装一个函数

        document.querySelector("img").onclick = function () {
            let that = this;
            // 透明底降低到0.3
            fadeTo(this, 0.3, function () {
                that.src = "./images/slidepic3.jpg";
                fadeTo(that, 1);
            });
        };

        // 封装函数
        // 1.传入参数:ele,要变化的元素
        // 2.传入参数:opacity,要变的目标
        // 3.传入参数:fn,回到函数

        function fadeTo(ele, opacity, fn) {
            // 1.清除原来的定时器
            ele.timeId && clearInterval(ele.timeId);
            // 2.绑定定时器
            ele.timeId = setInterval(function () {
                // 3.获取元素当前的透明度(转数字)
                let current = parseFloat(getComputedStyle(ele).opacity);

                // 4.计算步长:放d大一百倍
                let step = (opacity * 100 - current * 100) / 100;
                if (step > 0) step = Math.ceil(step);
                else step = Math.floor(step);

                // 5.给元素重新赋值
                ele.style.opacity = (current * 100 + step) / 100;
                console.log(step);

                // 6. 清理定时器
                if (step == 0) {
                    clearInterval(ele.timeId);

                    if (typeof fn === "function") fn();
                }
            }, 10);
        }
    </script>
</html>

js - 淡入淡出动画
// 封装函数
// 1. 传入参数: ele,要变化的元素
// 2. 传入参数: opacity,要变到的目标
// 3. 传入参数: fn, 回调函数
function fadeTo(ele, opacity, fn) {
    // 渐变: 定时器

    // 1. 清理定时器
    ele.timeId && clearInterval(ele.timeId)
    // 2. 绑定定时器
    ele.timeId = setInterval(function () {
        // 2.1 获取原始透明度(转成数字)
        let current = parseFloat(getComputedStyle(ele).opacity)
        // 2.2 计算步长: 放到一百倍
        let step = (opacity * 100 - current * 100) * 0.1
        // console.log(current, step)
        if (step > 0) step = Math.ceil(step)
        else step = Math.floor(step)

        // 2.3 给元素重新赋值
        ele.style.opacity = (current * 100 + step) / 100

        console.log(step)
        // 2.4 清理定时器
        if (step == 0) {
            clearInterval(ele.timeId)

            if (typeof fn === 'function') fn()
        }
    }, 20)
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Henry_ww

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值