当前位置: 首页 > news >正文

学js的第十七天

1.平滑运动

  • 需求:点击起飞 盒子开始移动 移动到1000px 盒子停止

<body>
    <button>起飞</button>
    <div></div>
    <script>
        /* 
            需求:点击起飞按钮  红色盒子开始移动  移动到1000px的位置开始停止
        */
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        //添加点击事件
        btn.onclick = function () {
           var timer =  setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left")) + 10;
                if(current==1000){
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + "px";
            }, 50)
​
        }
    </script>

2.缓冲动画基础功能

  • 需求:目标值是500和目标值是1000 所花费的时间是一样的

<body>
    <button>起飞</button>
    <div></div>
    <script>
        /* 
            需求:目标值是500和目标值是1000 所花费的时间是一样的
            速速 = 路程 / 时间
        */
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        //添加点击事件
        btn.onclick = function () {
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left"));
                var speed = (500 - current) / 10;// speed  速度/步长
                console.log(current);//永远达不到目标值
                if (current == 500) {
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + speed + "px";
            }, 50)
​
        }
    </script>
  • 问题1:永远到不了目标值

    • 原因:当current是491的时候 speed=0.9 left值=parseInt(491.9px) =491 所以current的值始终在491

    • 解决方法:让speed向上取整 Math.ceil

<body>
    <button>起飞</button>
    <div></div>
    <p></p>
    <script>
        /* 
             问题1:永远达不到目标值
             原因:当current是491的时候 speed=0.9 left值=parseInt(491.9px) =491 所以current的值始终在491
             解决方法:让speed向上取整  Math.ceil
        */
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        //添加点击事件
        btn.onclick = function () {
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left"));
                var speed = (500 - current) / 10; // speed  速度/步长
                speed = Math.ceil(speed);
                console.log(speed);
                if (current == 500) {
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + speed + "px";
            }, 50)
​
        }
    </script>
</body>

3缓冲动画来回运动

  • 需求:从left值是1000的位置 缓冲到500的位置

  • 问题2:往回运动的时候 永远无法达到目标值

    • 分析:current是509的时候 speed的值是-0.9 Math.ceil之后就成了-0 speed的值最终是0 left值还是509 导致目标值永远都是509

    • 解决:让speed向下取整 Math.floor

<body>
    <button>起飞</button>
    <div></div>
    <p></p>
    <script>
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        /* 
            问题2:往回运动的时候  永远无法达到目标值
            分析:current是509的时候  speed的值是-0.9 Math.ceil之后就成了-0 speed的值最终是0   left值还是509 导致目标值永远都是509
            解决:让speed向下取整  Math.floor
        */
        //添加点击事件
        btn.onclick = function () {
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left"));
                var speed = (500 - current) / 10; // speed  速度/步长
                speed = Math.floor(speed);
                console.log(current);
                if (current == 500) {
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + speed + "px";
            }, 50)
​
        }
    </script>
</body>
​
  • 来回运动speed值的问题

    • 0-500 speed的值正数 Math.ceil

    • 1000-500 speed的值是负数 Math.floor

<body>
    <button>起飞</button>
    <div></div>
    <p></p>
    <script>
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        /* 
           speed值的问题
             0-500  speed的值正数   Math.ceil
             1000-500 speed的值是负数  Math.floor
        */
        //添加点击事件
        btn.onclick = function () {
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left"));
                var speed = (500 - current) / 10; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == 500) {
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + speed + "px";
            }, 50)
​
        }
    </script>
</body>

4.来回运动函数封装

<body>
    <button>起飞</button>
    <div></div>
    <p></p>
    <script>
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        /* 
           speed值的问题
             0-500  speed的值正数   Math.ceil
             1000-500 speed的值是负数  Math.floor
        */
        //添加点击事件
        btn.onclick = function () {
​
            buffMove(oDiv, "left", 500, 20);
        }
​
        function buffMove(elem, attr, target, time) {
            /* elem 缓冲的元素 attr 需要缓冲的样式  target是目标值 time是缓冲时间 */
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(elem, attr));
                var speed = (target - current) / time; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == target) {
                    // 清除定时器
                    clearInterval(timer)
                }
                elem.style[attr] = current + speed + "px";
            }, 50)
        }
    </script>
</body>

5.透明度缓冲

  • 问题3:缓冲透明度从1到0 没有缓冲动画

    • 分析:current是1的时候 speed的值-0.1 用Math.floor取整之后变成-1 opacity的值是0

    • 解决:是因为透明度的值太小了 将透明度的值放大n倍 放大100倍

<body>
    <div></div>
    <script>
        /* 
            问题3:缓冲透明度从1到0 没有缓冲动画
            分析:current是1的时候 speed的值-0.1 用Math.floor取整之后变成-1 opacity的值是0   
            解决:是因为透明度的值太小了  将透明度的值放大n倍 放大100倍
        */
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function () {
            // 更改透明度  1-0
            buffMove(oDiv, "opacity", 0.2, 10)
        }
​
        function buffMove(elem, attr, target, time) {
            /* elem 缓冲的元素 attr 需要缓冲的样式  target是目标值 time是缓冲时间 */
            target = target * 100
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(elem, attr) * 100);
                var speed = (target - current) / time; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == target) {
                    // 清除定时器
                    clearInterval(timer)
                }
                // 其他属性
                // elem.style[attr] = current + speed + "px";
                // 透明度opacity
                elem.style[attr] = (current + speed) / 100;
            }, 50)
        }
    </script>
</body>

6.缓冲任意属性

<body>
    <div></div>
    <script>
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function () {
            // buffMove(oDiv,"width",500,10)
            buffMove(oDiv,"opacity",0.2,10)
        }
        function buffMove(elem, attr, target, time) {
        /* elem 缓冲的元素 attr 需要缓冲的样式  target是目标值 time是缓冲时间 */
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                if (attr == 'opacity') { // 透明度属性
                    var current = parseInt(getStyle(elem, attr) * 100);
                    // opacity target的取值范围是0-1  才需要*100   其他属性大于1 不需要*100
                    target = target > 1 ? target : target * 100
                } else {//其他属性
                    var current = parseInt(getStyle(elem, attr));
                }
                var speed = (target - current) / time; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == target) {
                    // 清除定时器
                    clearInterval(timer)
                }
                if (attr == "opacity") {
                    // 透明度opacity
                    elem.style[attr] = (current + speed) / 100;
                } else {
                    // 其他属性
                    elem.style[attr] = current + speed + "px";
                }
            }, 50)
        }
    </script>
</body>

7.抽屉式运动

  • 问题1:在移入事件的缓冲动画没有完成之前就移除 会造成盒子抽搐

    • 分析:是因为定时器累计的问题

    • 解决:在定义一个新的定时器之前就清除原先的定时器 确保只有一个定时器

  • 问题2:同时运动多个盒子 盒子无法达到目标值

    • 分析:多个盒子都是调用buffMove函数 一进入这个函数就将之前的定时器清除掉了 共用了一个定时器的缘故

    • 解决:给每个盒子都单独定义一个timer,将每个盒子的定时器id都存储到元素的自定义属性timer上

<body>
    <div>1</div>
    <div>2</div>
    <script>
        var oDiv = document.getElementsByTagName("div");
        oDiv[0].onmouseover = function(){
                // 200px-500px
                buffMove(oDiv[0],"width",500,10)
        }
        oDiv[0].onmouseout = function(){
               // 500px-200px
               buffMove(oDiv[0],"width",200,10)
​
        }
        oDiv[1].onmouseover = function(){
             //200-500px;
             buffMove(oDiv[1],"width",500,10)
        }
        oDiv[1].onmouseout = function(){
             //500px-200px
            buffMove(oDiv[1],"width",200,10)
​
        }
        // var timer;
        function buffMove(elem, attr, target, time) {
            /* elem 缓冲的元素 attr 需要缓冲的样式  target是目标值 time是缓冲时间 */
            clearInterval(elem.timer);
            //将每个盒子的定时器id都存储到元素的自定义属性timer上
            elem.timer = setInterval(function () { 
                //在当前left值的基础上+10
                if (attr == 'opacity') { // 透明度属性
                    var current = parseInt(getStyle(elem, attr) * 100);
                    // opacity target的取值范围是0-1  才需要*100   其他属性大于1 不需要*100
                    target = target > 1 ? target : target * 100
                } else {//其他属性
                    var current = parseInt(getStyle(elem, attr));
                }
                var speed = (target - current) / time; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == target) {
                    // 清除定时器
                    clearInterval(elem.timer)
                }
                if (attr == "opacity") {
                    // 透明度opacity
                    elem.style[attr] = (current + speed) / 100;
                } else {
                    // 其他属性
                    elem.style[attr] = current + speed + "px";
                }
            }, 50)
        }
    </script>
</body>

8.多属性运动

  • 问题1:运动多个属性的时候,无法多次调用buffMove函数,因为后者会覆盖前者

    • 解决:buffMove只能调用一次 可以每次传值的时候一个对象,对象存储格式为{"width":500,"height":500} {"样式名":目标值}

    <script>
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function () {
            // 想同时运动多个属性 buffMove只能调用一次 可以每次传值的时候传多个 参数{"width":500,"height":500}
            buffMove(oDiv, { "width": 500, "height": 500 }, 10)
        }
        //需求:同时运动width和height
        function buffMove(elem, attrObj, time) {
            /* elem 缓冲的元素 attrObj同时运动属性的对象{样式名:目标值}*/
            clearInterval(elem.timer);
            elem.timer = setInterval(function () {
                 // name变量中存储的是width height 也就是要缓冲的样式
                 // 目标值attrObj[name]   原先的目标值target需要替换成attrObj[name]
                for (var name in attrObj) {
                    //在当前left值的基础上+10
                    if (name == "opacity") {
                        // name是opacity
                        var current = parseInt(getStyle(elem, name) * 100);
                        // target的值是0-1 更改的是透明度,透明度需要*100   target>1 其他属性的值 不需要*100
                        attrObj[name] = attrObj[name] > 1 ? attrObj[name] : attrObj[name] * 100  //
                    } else {
                        // name是其他属性
                        var current = parseInt(getStyle(elem, name));
                    }
                    var speed = (attrObj[name] - current) / time; // speed  速度/步长
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                    console.log(current);
                    if (current == attrObj[name]) {
                        // 清除定时器
                        clearInterval(elem.timer)
                    }
                    if (name == "opacity") {
                        // 透明度opacity
                        elem.style[name] = (current + speed) / 100;
                    } else {
                        // 其他属性
                        elem.style[name] = current + speed + "px";
                    }
                }
            }, 50)
        }
    </script>
  • 问题2:如果多个属性的目标值不一致,个别属性无法到达目标点

    • 分析:如果某一个属性达到目标值 就会进到if(current==attrObj[name]) 就会清除定时器 导致剩余属性无法继续执行

    • 解决:

    1.假设所有属性都达到目标点再去清除定时器 var tag = true

    2.验证你假设的情况 一个一个属性的去验证

    3.验证之后你会得到一个结论 你的假设要么成立 要么不成立 如果成立清除定时器

<body>
    <div></div>
    <script>
        /* 
             问题1:如果多个属性目标值不一致的话  个别属性无法达到目标点
             分析:如果某一个属性达到目标值 就会进到if(current==attrObj[name]) 就会清除定时器 导致剩余属性无法继续执行
             解决:
                 1.假设所有属性都达到目标点再去清除定时器  var tag = true  
                 2.验证你假设的情况  一个一个属性的去验证
                 3.验证之后你会得到一个结论  你的假设要么成立  要么不成立   如果成立清除定时器
        
        */
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function () {
            
            buffMove(oDiv, { "width": 1, "height": 1000 }, 10)
        }
   
        function buffMove(elem, attrObj, time) {
            /* elem 缓冲的元素 attrObj同时运动属性的对象{样式名:目标值}*/
            clearInterval(elem.timer);
            elem.timer = setInterval(function () {
                var tag = true;// 初始值定义为true  假设所有的属性都达到了目标点
                for (var name in attrObj) {
                    //在当前left值的基础上+10
                    if (name == "opacity") {
                        // name是opacity
                        var current = parseInt(getStyle(elem, name) * 100);
                        // target的值是0-1 更改的是透明度,透明度需要*100   target>1 其他属性的值 不需要*100
                        attrObj[name] = attrObj[name] > 1 ? attrObj[name] : attrObj[name] * 100  //
                    } else {
                        // name是其他属性
                        var current = parseInt(getStyle(elem, name));
                    }
                    var speed = (attrObj[name] - current) / time; // speed  速度/步长
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                    
                    //2.去验证假设的情况
                    if(current!=attrObj[name]){
                        tag = false
                    }
                   
                    if (name == "opacity") {
                        // 透明度opacity
                        elem.style[name] = (current + speed) / 100;
                    } else {
                        // 其他属性
                        elem.style[name] = current + speed + "px";
                    }
                }
                // 3.判断结论是否成立
                if(tag){
                    clearInterval(elem.timer)
                }
            }, 50)
        }
    </script>
</body>

相关文章:

  • 搭建自己的云存储空间|FastDFS分布式文件系统考虑一下?
  • <哈希及模拟实现>——《C++高阶》
  • 【力扣】两数之和 II - 输入有序数组
  • 懒人方案--半天搞定一个SpringBoot单体项目
  • 【JAVA数据结构】JAVA数据结构必备知识:泛型与包装类
  • 微服务项目:尚融宝(40)(核心业务流程:申请借款额度(3))
  • 将web前端项目部署到github,在hbuilderx中部署github中的项目、对Github加速
  • Pytorch优化器全总结(二)Adadelta、RMSprop、Adam、Adamax、AdamW、NAdam、SparseAdam
  • MFI不告诉你的秘密
  • 【RocketMq 系列】RocketMq 消息重试机制、死信队列
  • 该从什么角度思考npm、yarn与pnpm的区别
  • 分库分表一:ShardingSphere介绍和入门实战
  • Linux内存管理(三十一):页面回收总结
  • 微信小程序│ 游戏开发 │连连看游戏
  • Python每日一练(牛客数据分析篇新题库)——第34天:数据清洗
  • ES6指北【2】—— 箭头函数
  • @angular/forms 源码解析之双向绑定
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 08.Android之View事件问题
  • Docker下部署自己的LNMP工作环境
  • ES2017异步函数现已正式可用
  • HTML-表单
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • JavaScript创建对象的四种方式
  • JavaScript异步流程控制的前世今生
  • js面向对象
  • maven工程打包jar以及java jar命令的classpath使用
  • React16时代,该用什么姿势写 React ?
  • VUE es6技巧写法(持续更新中~~~)
  • Vue 动态创建 component
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 关于字符编码你应该知道的事情
  • 记一次和乔布斯合作最难忘的经历
  • 技术发展面试
  • 京东美团研发面经
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 蓝海存储开关机注意事项总结
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 力扣(LeetCode)21
  • 利用DataURL技术在网页上显示图片
  • 免费小说阅读小程序
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 一些css基础学习笔记
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​水经微图Web1.5.0版即将上线
  • #QT(串口助手-界面)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务