JS运动函数及其封装

运动函数

封装运动函数

在事件位置调用就可以让位置,长宽,透明度等批量运动

  • 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>Document</title>
    <!-- 给div添加内部样式 -->
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        div{
            width: 100px;
            height: 100px;
            background: springgreen;
            position: absolute;
            top: 100px;
            left: 100px;
            cursor: pointer;
            opacity: 1;
        }
    </style>
</head>
<body>
    <div></div>
</body>
</html> 
  • js代码
// 拿到div标签并且赋值给常量box
const box = document.querySelector("div")
// 给div标签添加一个点击事件
box.onclick = function(){
    // 调用封装的运动函数
    move(this,"left",300)
    move(this,"top",500)
    move(this,"opacity",1)
}
/* 创建一个运动函数,该函数有三个参数为ele(不同的元素),
type(标签的样式类型),target(目标,即运动最后达到的值) */
function move(ele,type,target){
    // 判断样式类型是否为opacity(透明度)
    if(type === "opacity"){
        // 是则让目标放大100倍
        target *= 100
    }
    // 设置一个每16毫秒运行一次的定时器并且储存在变量timer
    let timer = setInterval(() => {
        // 定义变量current用来储存运动的样式现在所在的位置,或者值
        let current
        if(type === "opacity"){
            // 是则将div现在的透明度样式的值放大100倍赋值给current
            current = window.getComputedStyle(ele)[type] * 100
        }else{
            // 不是将转为判定div其他样式现在的值赋给current
            current = parseInt(window.getComputedStyle(ele)[type])
        }
        // 定义变量step储存每一次变换的大小,整体意为每次改变剩余未变换的百分之10
        let step = (target - current) / 10 
        /* 因为上面一句导致在判定运动最后是否到达目标的时候是无
        限接近相等,即最后的step无限小,因此需要将正小数判定时
        候向上取整,负小数向下取整。不理解的可以在控制台打印step
        观察一下step值的变化。 */
        step = step > 0?Math.ceil(step):Math.floor(step)
        if(current == target){
            // 到达目标就可以清空定时器,停止运动
            clearInterval(timer)
            timer = null
        }else{
            if(type === "opacity"){
                // 因为样式不带px所以要单独判断给样式赋值
                ele.style[type] = (current + step) / 100
            }else{
                ele.style[type] = current + step + "px"
            }
        }
    }, 16);
}
  • 最后效果在网页相对浏览器可视区域左上角的向右100px,向下100px的位置看到鼠标箭头变成小手,点击一下左键,方块会由完全透明变的不透明,最终移动到相对浏览器可视区域左上角的向右300px,向下500px。

升级版封装运动函数

上面的运动函数每让一个属性发生改变,即运动,就要调用一次封装函数,非常的麻烦且不银杏化,因此我们对此进行了一点小升级。

  • html方面没有变化,可以继续沿用上面的
  • js代码
const box = document.querySelector("div")
box.onclick = function () {

    /* 多属性移动 => 一次可以移动跟多个属性 */
    moveFn(this, {
        "opacity": 1,
        'width': 600,
        'height': 400,
        'top': 400,
        'left': 600
    })
}
/* 这里参数的元素不变,但是我们发现属性,和属性值
对应的都是同一个元素,那我们为什么不能把一个元素(标签)
的属性以及属性值用对象以key跟value的方式收集起来,
这样传参数的时可以少传一个,调用的时候也可以一次调用多属性 */
function moveFn(ele, moveObj) {
    //定义一个变量
    let count = 0;
    /* 遍历moveObj对象,拿出收集的属性及属性值,
    在对象中key对应属性,value对应属性值 */
    for (let key in moveObj) {
        count ++;
        // 如同上一条注释,一一对应就一一赋值,封装的运动函数其他不变
        let type = key
        let target = moveObj[key]
        if (type == 'opacity') {
            target *= 100;
        }
        let timer = setInterval(() => {
            let current
            if (type == 'opacity') {
                current = window.getComputedStyle(ele)[type] * 100;
            } else {
                current = parseInt(window.getComputedStyle(ele)[type])
            }
            let step = (target - current) / 10
            step = step > 0 ? Math.ceil(step) : Math.floor(step)
            if (current == target) {
                clearInterval(timer)
                timer = null;
                count --
                if(count === 0){
                    console.log("代码执行完毕!");
                }
            } else {
                if (type === 'opacity') {
                    ele.style[type] = (current + step) / 100;
                } else {
                    ele.style[type] = current + step + "px";
                    
                }
            }
        }, 16);
    }
}

小总结

运动函数实现的方法跟思路有很多,这只是其中一种。

在进化版中可能有细心的朋友发现了还增添一个变量 count ,这个变量是用来判定一个元素的运动什么时候执行完毕的。

正常情况下一个元素有几个属性要同时变化,那么在清除定时器的后面添加 console.log("代码执行完毕") 会发现在控制台,这句话有几条属性,就被执行了几次,无法判断元素的一次执行完毕。

因此,在遍历对象前定义一个变量 count 并且赋值为0,当遍历一次对象,让 count 的值加 1 ,当对象中的属性及属性值全部拿出来进入定时器,这时候,每清除一次定时器,再让 count 的值减 1 ,这时候就可以用 count 是否为零来判断一个元素的一次执行完毕。

为什么要加这个东西捏,因为这是在为轮播图的编写做准备。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值