• 第八节 JS运动基础


    运动基础

      让Div运动起来

      速度——物体运动的快慢

      运动中的Bug

        不会停止

        速度取某些值会无法停止

        到达位置后再点击还会运动

        重复点击速度加快

    匀速运动(速度不变)

    运动框架及应用:

      运动框架:

        在开始运动时,关闭已有定时器

        把运动和停止隔开(if/else)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>JS运动基础</title>
        <style>
            #div1{
                width: 200px;
                height: 200px;
                background: yellow;
                position: absolute;
                top: 50px;
                left: 0px;
            }
        </style>
        <script>
            var timer=null;     //用于存储定时器
    
            function startMove() {
                var oDiv=document.getElementById('div1');
    
                clearInterval(timer);   //不管之前有没有定时器,都先关闭,然后下面开启定时器,以保证每次点击该事件时只有一个定时器在工作,
    
                timer=setInterval(function () {
                    var speed=7;    //控制物体运动的快慢
    
                    //注意此时,速度为7,而距离300不能整除7,所以当到达294时直接跳过300,而直接到301,所以物体就不会停止,而是继续向下运动,
                    // if (oDiv.offsetLeft==300){      //当离左边的距离为300像素的时候,关掉定时器,使其停止运动
                    if (oDiv.offsetLeft>=300){      //解决不会停止的办法,此时停在的301px的位置,但是问题又来了,如果再次点击按钮,
                        // 则物体会运动7像素,再点击一下,有运动7像素,一直点击,一直运动7的倍数个像素
                        //这是因为,每次点击按钮时,都会重新开一个定时器,所以每次点击就会运动一下,解决办法如下else中语句
                        clearInterval(timer);   //到达终点以后要做的事情
                    } else {
                        oDiv.style.left=oDiv.offsetLeft+speed+'px';     //到达终点之前要做的事情
                    }
                    // oDiv.style.left=oDiv.offsetLeft+speed+'px';     //offsetleft就是取div的位置; speed控制运动速度
                }, 30);
            }
        </script>
    </head>
    <body>
        <input id="btn1" type="button" value="开始运动" onclick="startMove()"/>
        <div id="div1"></div>
    
    </body>
    </html>
    View Code

    运动框架实例:

      例1:“分享到”侧边栏(通过目标点,计算速度值)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>侧边隐藏栏</title>
        <style>
            *{margin: 0px;padding: 0px;}
            #div1{
                width: 150px;
                height: 150px;
                background: green;
                position: absolute;
                top: 100px;
                left: -150px;
            }
            #div1 span{
                width: 20px;
                height: 60px;
                line-height: 20px;
                position: absolute;
                background: blue;
                right: -20px;
                top: 20px;
            }
        </style>
        <script>
            window.onload=function () {
                var oDiv=document.getElementById('div1');
                // oDiv.onmouseover=function () {
                //     InOut1(10, 0);   //传入参数speed, iTarget
                // };
                // oDiv.onmouseout=function () {
                //     InOut1(-10, -150);   //传入参数speed, iTarget
                // };
                oDiv.onmouseover=function () {
                    InOut2(0);   //传入参数iTarget
                };
                oDiv.onmouseout=function () {
                    InOut2(-150);   //传入参数iTarget
                };
            };
    
            var timer=null;
            // function Out() {
            //     var oDiv=document.getElementById('div1');
            //     clearInterval(timer);
            //     timer=setInterval(function () {
            //         if (oDiv.offsetLeft == 0) {
            //             clearInterval(timer);
            //         } else {
            //             oDiv.style.left=oDiv.offsetLeft+10+"px";
            //         }
            //     }, 30);
            // }
            //
            // function In() {
            //     var oDiv=document.getElementById('div1');
            //     clearInterval(timer);
            //     timer=setInterval(function () {
            //         if (oDiv.offsetLeft == -150) {
            //             clearInterval(timer);
            //         } else {
            //             oDiv.style.left=oDiv.offsetLeft-10+"px";
            //         }
            //     }, 30);
            // }
            
            //代码合并,把要发生变动的“量”定义为参数,调用时直接传入
            // function InOut1(speed, iTarget) {
            //     var oDiv=document.getElementById('div1');
            //     clearInterval(timer);
            //     timer=setInterval(function () {
            //         if (oDiv.offsetLeft == iTarget) {
            //             clearInterval(timer);
            //         } else {
            //             oDiv.style.left=oDiv.offsetLeft+speed+"px";
            //         }
            //     }, 30);
            // }
            
            //代码简化,尽量少传入参数
            function InOut2(iTarget) {
                var oDiv=document.getElementById('div1');
                clearInterval(timer);
                timer=setInterval(function () {
                    var speed=0;
                    if (oDiv.offsetLeft>iTarget){
                        speed=-10;      //当当前位置大于预设目标位置,向左移动
                    } else {
                        speed=10;       //当当前位置小于预设目标位置,向右移动
                    }
                    
                    if (oDiv.offsetLeft == iTarget) {
                        clearInterval(timer);
                    } else {
                        oDiv.style.left=oDiv.offsetLeft+speed+"px";
                    }
                }, 30);
            }
        </script>
    </head>
    <body>
        <div id="div1">
            <span>分享到</span>
            <a>hhhhhh</a>
        </div>
    </body>
    </html>
    View Code

      例2:淡入淡出的图片(用变量存储透明度)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>内容淡入淡出-透明度的变换</title>
        <style>
            #div1{
                width: 200px;
                height: 200px;
                background: red;
                filter:alpha(opacity:30);   /*IE透明度*/
                opacity: 0.3;   /*Chrome Firefox透明度*/
            }
        </style>
        <script>
            window.onload = function () {
                var oDiv = document.getElementById('div1');
    
                oDiv.onmouseover=function () {
                    Fade_In_Out(100);   //淡入
                };
                oDiv.onmouseout=function () {
                    Fade_In_Out(30);    //淡出
                };
            };
    
            var alpha = 30;     //因为没有offsetAlpha该参数,所以我们改变透明度时,需要自定义变量
            var timer = null;
            function Fade_In_Out(iTarget) {
                var oDiv = document.getElementById('div1');
                clearInterval(timer);
                timer = setInterval(function () {
                    var speed = 0;      //变化速度
                    if (alpha < iTarget){
                        speed = 10;
                    } else {
                        speed = -10;
                    }
    
                    if (alpha == iTarget){
                        clearInterval(timer);
                    } else {
                        alpha += speed;
                        oDiv.style.filter = 'alpha(opacity:'+alpha+')';   //IE改变透明度,其中“:”可以换位“=”
                        oDiv.style.opacity = alpha/100;   //Chrome FireFox
                    }
                }, 30);
            }
        </script>
    </head>
    <body>
        <div id="div1">
    
        </div>
    </body>
    </html>
    View Code

    缓冲运动

      逐渐变慢,最后停止

      距离越远速度越大:速度由距离决定(距离越大,速度越快;距离越小,速度越慢),速度=(目标值-当前值)/缩放系数

      例子:缓冲菜单

        Bug:速度调整(所以当用到缓冲运动时,切记一定要用到取整,否则会有误)    

    // alert(Math.ceil(3.01));     //返回值为4,表示向上取整
    // alert(Math.floor(3.999));   //返回值为3,表示向下取整   
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>速度调整</title>
        <style>
            #div1{
                width: 100px;
                height: 100px;
                background: red;
                position: absolute;
                left: 0px;    /*向右运动*/
                /*left: 600px;    !*向左运动*!*/
                top: 50px;
            }
            #div2{
                width: 1px;
                height: 300px;
                position: absolute;
                background: black;
                left: 300px;
                top: 0px;
            }
        </style>
        <script>
            // alert(Math.ceil(3.01));     //返回值为4,表示向上取整
            // alert(Math.floor(3.999));   //返回值为3,表示向下取整
    
            function startMove() {
                var oDiv = document.getElementById('div1');
                setInterval(function () {
                    //不断计算left的值,首先是(300-0)/15,之后是(300-x)/15,而x不断增大,速度也就逐渐变慢
                    var speed = (300-oDiv.offsetLeft)/15;
    
                    // speed = Math.ceil(speed);   //当div1向有运动时,速度向上取整
                    // speed = Math.floor(speed);     //当div1向左运动时,速度向下取整
                    speed = speed>0?Math.ceil(speed):Math.floor(speed);     //上面两句代码的合并
    
                    oDiv.style.left = oDiv.offsetLeft+speed+'px';
    
                    document.title = oDiv.offsetLeft+','+speed;     //把主题title转换为left和speed的值,方便观察变化
                }, 30);
            }
        </script>
    </head>
    <body>
        <button onclick="startMove()">开始运动</button>
        <div id="div1"></div>
        <div id="div2"></div>
    </body>
    </html>
    View Code

        跟随页面滚动的缓冲侧边栏

          潜在问题:目标值不是整数时;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>右侧悬浮框</title>
        <style>
            body{height: 2000px;    /*为了呈现出滚动条*/}
            #div1{
                width: 100px;
                height: 150px;
                background: red;
                position: absolute;
                right: 0px;
                bottom: 318px;
            }
        </style>
        <script>
            //onscroll滚动
            window.onscroll = function(){
                var oDiv = document.getElementById('div1');
                var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
    
                // oDiv.style.top = (document.documentElement.clientHeight-oDiv.offsetHeight+scrollTop)/2+'px';
                //此时存在的问题是,在滑动滚动条的时候,div1的变化“有跳动”,跳一下才变换到正确位置,所以我们注释掉,解决方法为:
                startMove(parseInt((document.documentElement.clientHeight-oDiv.offsetHeight)/2+scrollTop));
                //(可视区的高-div的高)/2 表示把需要悬浮的框,悬浮在靠右中间的位置;
                // 其中parseInt() 表示避免“除以2”时出现0.5的像素值(屏幕没有半个像素的情况),此时悬浮框会出现上下抖动的情况,而用parseInt()取整后就不会出现这种情况了。
            };
    
            var timer=null;
            function startMove(iTarget) {
                var oDiv = document.getElementById('div1');
                clearInterval(timer);
                timer = setInterval(function(){
                    var speed = (iTarget-oDiv.offsetTop)/6;
                    speed = speed>0?Math.ceil(speed):Math.floor(speed);     //取整
    
                    if (oDiv.offsetTop==iTarget){
                        clearInterval(timer);
                    } else {
                        document.getElementById('txt1').value = oDiv.offsetTop;   //调整悬浮框的位置,以便观察
                        oDiv.style.top = oDiv.offsetTop+speed+'px';
                    }
                }, 30);
            }
        </script>
    </head>
    <body>
        <input type="txt1" id="txt1" style="position: fixed; right: 0px; top: 0px;"/>
        <div id="div1"></div>
    </body>
    </html>
    View Code

    匀速运动的停止条件

      运动终止条件:

        匀速运动:距离足够近

        缓冲运动:两点重合

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>匀速运动停止条件</title>
        <style>
            #div1{
                width: 100px;
                height: 100px;
                background: red;
                position: absolute;
                left: 0px;    /*向右运动*/
                /*left: 600px;    !*向左运动*!*/
                top: 50px;
            }
            #div2{
                width: 1px;
                height: 300px;
                position: absolute;
                background: black;
                left: 300px;
                top: 0px;
            }
            #div3{
                width: 1px;
                height: 300px;
                position: absolute;
                background: black;
                left: 100px;
                top: 0px;
            }
        </style>
        <script>
            // alert(Math.abs(-6));    //返回值为6,abs()表示绝对值
    
            var timer = null;
            function startMove(iTarget) {
                var oDiv = document.getElementById('div1');
    
                clearInterval(timer);
                timer = setInterval(function () {
                    var speed = 0;
                    if (oDiv.offsetLeft<iTarget){
                        speed = 7;  //故意找一个不能整除的数字,以便发现问题
                    } else {
                        speed = -7;
                    }
                    //问题出现,由于最终结果不为0,所以会因为有一定的偏差而相对抖动,我们所能够解决的是在存在偏差的情况下,结束抖动,解决办法如下:
                    if (Math.abs(iTarget-oDiv.offsetLeft)<=7){
                        clearInterval(timer);
    
                        //因为上面偏差是不能消除的,此时我们为了消除偏差,强行令left值等于目标值
                        oDiv.style.left = iTarget+'px';    //由于程序运行的速度较快,这种强行赋值使用肉眼是观察不到的
                    } else {
                        oDiv.style.left = oDiv.offsetLeft+speed+'px';
                    }
                }, 30);
            }
        </script>
    </head>
    <body>
        <button onclick="startMove(100)">到100px</button>
        <button onclick="startMove(300)">到300px</button>
        <div id="div1"></div>
        <div id="div2"></div>
        <div id="div3"></div>
    </body>
    </html>
    View Code
  • 相关阅读:
    Stream流之三级查询
    SpringBoot日期格式的设置
    el表达式
    SpringMV+HuTool之验证码登录
    Spring注解详解
    @ResponseBody注解使用(返回字符串并不跳转)
    每日leetcode-数组-589. N 叉树的前序遍历
    python apply函数
    剑指offer-JZ6 旋转数组的最小数字
    torch.manual_seed()函数
  • 原文地址:https://www.cnblogs.com/han-bky/p/10197866.html
Copyright © 2020-2023  润新知