智能社JavaScript学习笔记——JS运动基础

1. 运动基础

让Div运动起来


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1{width: 200px; height: 200px; background: red; position: absolute; top: 50px; left: 0;}
    style>
    <script>
    function startMove() 
    {
        var oDiv = document.getElementById("div1");

        setInterval(function(){
            var speed = 10;
            oDiv.style.left = oDiv.offsetLeft + speed + 'px';

        }, 30);
    }
    script>
head>
<body>
    <input id="btn1" type="button" value="开始移动" onclick="startMove()" />
    <div id="div1">div>
body>
html>

速度——物体运动的快慢
修改speed的值,越大运动越快

运动中的Bug

  • 不会停止

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1{width: 200px; height: 200px; background: red; position: absolute; top: 50px; left: 0;}
    style>
    <script>
    var timer = null;
    function startMove() 
    {
        var oDiv = document.getElementById("div1");

        timer = setInterval(function(){
            var speed = 10;
            if(oDiv.offsetLeft == 300)
            {
                clearInterval(timer);
            }
            oDiv.style.left = oDiv.offsetLeft + speed + 'px';

        }, 30);
    }
    script>
head>
<body>
    <input id="btn1" type="button" value="开始移动" onclick="startMove()" />
    <div id="div1">div>
body>
html>
  • 速度取某些值会无法停止
    比如,当speed=7时, 将无法停止,因为oDiv.style.left的值:0,7,14,。。。,280,287,294,301,308,,,。所以offsetLeft的值不会等于300,也就不会停止。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1{width: 200px; height: 200px; background: red; position: absolute; top: 50px; left: 0;}
    style>
    <script>
    var timer = null;
    function startMove() 
    {
        var oDiv = document.getElementById("div1");

        timer = setInterval(function(){
            var speed = 10;
            if(oDiv.offsetLeft >= 300) // 改为>=
            {
                clearInterval(timer);
            }
            oDiv.style.left = oDiv.offsetLeft + speed + 'px';

        }, 30);
    }
    script>
head>
<body>
    <input id="btn1" type="button" value="开始移动" onclick="startMove()" />
    <div id="div1">div>
body>
html>
  • 到达位置后再点击还会运动
    当div停住以后,点击按钮后div还会动一下,这是因为定时器要到下一次才会关闭,但当前的oDiv.style.left = oDiv.offsetLeft + speed + ‘px’;还是会执行一次。
    解决办法:将该语句放到else里。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1{width: 200px; height: 200px; background: red; position: absolute; top: 50px; left: 0;}
    style>
    <script>
    var timer = null;
    function startMove() 
    {
        var oDiv = document.getElementById("div1");

        timer = setInterval(function(){
            var speed = 10;
            if(oDiv.offsetLeft >= 300)
            {
                clearInterval(timer);
            }
            else
            {
                oDiv.style.left = oDiv.offsetLeft + speed + 'px';
            }

        }, 30);
    }
    script>
head>
<body>
    <input id="btn1" type="button" value="开始移动" onclick="startMove()" />
    <div id="div1">div>
body>
html>
  • 重复点击速度加快
    当多次点击按钮时,div移动速度加快,因为相当于开了多个定时器。
    解决方法:保证每次只有一个定时器工作。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1{width: 200px; height: 200px; background: red; position: absolute; top: 50px; left: 0;}
    style>
    <script>
    var timer = null;
    function startMove() 
    {
        var oDiv = document.getElementById("div1");

        clearInterval(timer); //将其它定时器关掉!
        timer = setInterval(function(){
            var speed = 10;
            if(oDiv.offsetLeft >= 300)
            {
                clearInterval(timer);
            }
            else
            {
                oDiv.style.left = oDiv.offsetLeft + speed + 'px';
            }

        }, 30);
    }
    script>
head>
<body>
    <input id="btn1" type="button" value="开始移动" onclick="startMove()" />
    <div id="div1">div>
body>
html>

2. 匀速运动

速度不变

3. 运动框架

在开始运动时,关闭已有定时器
把运动和停止隔开(if/else):运动指到达指定位置前,而停止是到达指定位置后,所以这两部分不应该同时执行,要分开。

4. 运动框架实例

例子1:“分享到”侧边栏


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1 {width: 150px; height: 200px; background: green; position: absolute; left: -150px;}
        #div1 span {width: 20px; height: 60px; background: blue; position: absolute; right: -20px; top: 70px;}
    style>

    <script>
    window.onclick = function ()
    {
        var oDiv = document.getElementById("div1");

        oDiv.onmouseover = function ()
        {
            startMove(10, 0);
        };
        oDiv.onmouseout = function ()
        {
            startMove(-10, -150);
        };
    };

    var timer = null;

    function startMove (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);
    }
    script>
head>
<body>
    <div id="div1">
        <span>分享到span>
    div>
body>
html>

通过目标点,计算速度值


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1 {width: 150px; height: 200px; background: green; position: absolute; left: -150px;}
        #div1 span {width: 20px; height: 60px; background: blue; position: absolute; right: -20px; top: 70px;}
    style>

    <script>
    window.onclick = function ()
    {
        var oDiv = document.getElementById("div1");

        oDiv.onmouseover = function ()
        {
            startMove(0);
        };
        oDiv.onmouseout = function ()
        {
            startMove(-150);
        };
    };

    var timer = null;

    function startMove (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>
    div>
body>
html>

例子2:淡入淡出的图片
用变量存储透明度 (var alpha = 30;)


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style type="text/css">
    #div1 {width: 200px; height: 200px; background: red; filter:alpha(opacity=30); opacity: 0.3; }
    style>

    <script type="text/javascript">
    window.onload = function ()
    {
        var oDiv = document.getElementById("div1");

        oDiv.onmouseover = function ()
        {
            startMove(100);
        };
        oDiv.onmouseout = function () 
        {
            startMove(30);
        };
    };

    timer = null;
    var alpha = 30; //用变量存储透明度

    function startMove(iTarget) 
    {
        var oDiv = document.getElementById("div1");

        clearInterval(timer);
        timer = setInterval(function (){
            var speed = 0;
            if(alpha10;
            }
            else
            {
                speed = -10;
            }

            if(alpha == iTarget)
            {
                clearInterval(timer);
            }
            else
            {
                alpha += speed;

                oDiv.style.filter = "alpha(opacity="+alpha+")";
                oDiv.style.opacity = alpha/100;
            }
        }, 30);
    }
    script>
head>
<body>
    <div id="div1">div>
body>
html>

5. 缓冲运动

逐渐变慢,最后停止 (当距离终点越远,速度越大,即速度与距离成正比。)

  • 速度由距离决定
  • 速度 = (目标值-当前值)/缩放系数

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1{width: 100px; height: 100px; background: red; position: absolute; top: 50px; left: 0;}
    style>
    <script>
    function startMove() 
    {
        var oDiv = document.getElementById("div1");

        setInterval(function(){

            var speed = (300-oDiv.offsetLeft)/10;

            oDiv.style.left = oDiv.offsetLeft + speed + 'px';
        }, 30);
    }
    script>
head>
<body>
    <input id="btn1" type="button" value="开始移动" onclick="startMove()" />
    <div id="div1">div>
body>
html>

例子:缓冲菜单


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1 { width: 100px; height: 100px; background: red; position: absolute; top: 50px; left: 0; }
        #div2 { width: 1px; height: 300px; background: black; position: absolute; top: 0; left: 300px; }
    style>
    <script>
    function startMove() 
    {
        var oDiv = document.getElementById("div1");

        setInterval(function(){

            var speed = (300-oDiv.offsetLeft)/10;

            oDiv.style.left = oDiv.offsetLeft + speed + 'px';

            document.title = oDiv.offsetLeft+", "+speed;

        }, 30);
    }
    script>
head>
<body>
    <input id="btn1" type="button" value="开始移动" onclick="startMove()" />
    <div id="div1">div>
    <div id="div2">div>
body>
html>

智能社JavaScript学习笔记——JS运动基础_第1张图片
- Bug:速度取整

setInterval(function(){

            var speed = (300-oDiv.offsetLeft)/10;

            speed = Math.ceil(speed); // 向上取整

            oDiv.style.left = oDiv.offsetLeft + speed + 'px';

            document.title = oDiv.offsetLeft+", "+speed;

        }, 30);

当div从右向左运动时,用ceil取整又会出现问题,而应该用floor取整,因此,修改如下:

    function startMove() 
    {
        var oDiv = document.getElementById("div1");

        setInterval(function(){

            var speed = (300-oDiv.offsetLeft)/10;

            //speed = Math.ceil(speed); // 向上取整
            speed = (speed>0) ? Math.ceil(speed) : Math.floor(speed);

            oDiv.style.left = oDiv.offsetLeft + speed + 'px';

            document.title = oDiv.offsetLeft+", "+speed;

        }, 30);
    }

注意: 凡是用到缓冲运动时,一定不能忘了取整!


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1 { width: 100px; height: 100px; background: red; position: absolute; right: 0; bottom: 0; }
    style>
    <script>
    window.onscroll = function (){
        var oDiv = document.getElementById("div1");
        var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;

        //改变滚动条位置时,使div始终显示在浏览器的右下角
        oDiv.style.top = document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop + "px";
    };
    script>
head>
<body style="height: 2000px">
    <div id="div1">div>
body>
html>

上面这种方法实现的侧边栏当滚动条移动很快时会跳动。

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

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1 { width: 100px; height: 100px; background: red; position: absolute; right: 0; bottom: 0; }
    style>
    <script>
    window.onscroll = function (){
        var oDiv = document.getElementById("div1");
        var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;

        //改变滚动条位置时,使div始终显示在浏览器的右下角
        //oDiv.style.top = document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop + "px";
        startMove(document.documentElement.clientHeight - oDiv.offsetHeight + scrollTop );
    };

    var timer = null;

    function startMove (iTarget){
        var oDiv = document.getElementById("div1");

        clearInterval(timer);

        timer = setInterval(function (){
            var speed = (iTarget-oDiv.offsetTop)/5;
            speed = speed>0 ? Math.ceil(speed) : Math.floor(speed);

            if(oDiv.offsetTop == iTarget)
            {
                clearInterval(timer);
            }
            else
            {
                oDiv.style.top = oDiv.offsetTop + speed + "px";
            }
        }, 30);
    }
    script>
head>
<body style="height: 2000px">
    <div id="div1">div>
body>
html>
  • 潜在问题:目标值不是整数时

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1 { width: 100px; height: 100px; background: red; position: absolute; right: 0; bottom: 0; }
    style>
    <script>
    window.onscroll = function (){
        var oDiv = document.getElementById("div1");
        var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;


        //oDiv.style.top = (document.documentElement.clientHeight - oDiv.offsetHeight)/2 + scrollTop + "px";
        startMove((document.documentElement.clientHeight - oDiv.offsetHeight)/2 + scrollTop );
    };

    var timer = null;

    function startMove (iTarget){
        var oDiv = document.getElementById("div1");

        clearInterval(timer);

        timer = setInterval(function (){
            var speed = (iTarget-oDiv.offsetTop)/5;
            speed = speed>0 ? Math.ceil(speed) : Math.floor(speed);

            if(oDiv.offsetTop == iTarget)
            {
                clearInterval(timer);
            }
            else
            {
                oDiv.style.top = oDiv.offsetTop + speed + "px";

                document.getElementById("txt1").value = oDiv.style.top;
                document.title = iTarget;
            }
        }, 30);
    }
    script>
head>
<body style="height: 2000px">
    <div id="div1">div>
    <input id="txt1" type="text" style="position:fixed; right: 0; top: 0;"/>
body>
html>

智能社JavaScript学习笔记——JS运动基础_第2张图片
div会在中间位置抖动,因为div的top值在487和488之间变换。
修改如下:

startMove(parseInt((document.documentElement.clientHeight - oDiv.offsetHeight)/2 + scrollTop ));
    };

运动终止条件
匀速运动:距离足够近
例子:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1 { width: 100px; height: 100px; background: red; position: absolute; top: 50px; left: 600px; }

        #div2 { width: 1px; height: 300px; background: black; position: absolute; top: 0; left: 100px; }
        #div3 { width: 1px; height: 300px; background: black; position: absolute; top: 0; left: 300px; }
    style>
    <script>

    var timer = null;

    function startMove(iTarget) 
    {
        var oDiv = document.getElementById("div1");

        clearInterval(timer);
        setInterval(function(){

            var speed = 0;

            if(oDiv.offsetLeft7;
            }
            else
            {
                speed = -7;
            }

            if(oDiv.offsetLeft == iTarget)
            {
                clearInterval(timer);
            }
            else
            {
                oDiv.style.left = oDiv.offsetLeft + speed + 'px';
            }
        }, 30);
    }
    script>
head>
<body>
    <input type="button" value="移动到100" onclick="startMove(100)" />
    <input type="button" value="移动到300" onclick="startMove(300)" />
    <div id="div1">div>
    <div id="div2">div>
    <div id="div3">div>
body>
html>

以上这种情况下,div停不下来,修改如下:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
    <style>
        #div1 { width: 100px; height: 100px; background: red; position: absolute; top: 50px; left: 600px; }

        #div2 { width: 1px; height: 300px; background: black; position: absolute; top: 0; left: 100px; }
        #div3 { width: 1px; height: 300px; background: black; position: absolute; top: 0; left: 300px; }
    style>
    <script>

    var timer = null;

    function startMove(iTarget) 
    {
        var oDiv = document.getElementById("div1");

        clearInterval(timer);
        timer = setInterval(function(){

            var speed = 0;

            if(oDiv.offsetLeft7;
            }
            else
            {
                speed = -7;
            }

            //if(oDiv.offsetLeft == iTarget)
            if(Math.abs(oDiv.offsetLeft - iTarget) <= 7)
            {
                clearInterval(timer);

                oDiv.style.left = iTarget + "px";
            }
            else
            {
                oDiv.style.left = oDiv.offsetLeft + speed + 'px';
            }
        }, 30);
    }
    script>
head>
<body>
    <input type="button" value="移动到100" onclick="startMove(100)" />
    <input type="button" value="移动到300" onclick="startMove(300)" />
    <div id="div1">div>
    <div id="div2">div>
    <div id="div3">div>
body>
html>

缓冲运动:两点重合

你可能感兴趣的:(JavaScript)