JavaScript的运动原理1

时间:2019-09-08
本文章向大家介绍JavaScript的运动原理1,主要包括JavaScript的运动原理1使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

运动基础

  1. 在JavaScript中,如何让一个页面元素动起来?
    首先,我们需要了解的是,在JavaScript中如何让一个页面元素动起来。

我们先来实现一个简单的功能,当我们点击按钮之后,让一个元素动起来。并且到达500的边界之后立刻停止下来。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            #d1 {
                width: 100px;
                height: 100px;
                background-color: red;
                position: absolute;
                top:100px;
                left: 200px;
            }
        </style>
    </head>
    <body>
        <button id="btn">点击运动</button>
        <div id="d1"></div>
    </body>
    <script>
        // 点击按钮,让div横向的运动起来
        
        // 1. 获取元素
        let oBtn = document.getElementById('btn');
        let oDiv = document.getElementById('d1');
        let iTimer = null;
        // 点击按钮,让元素一直运动 ,需要使用到的知识点:定时器 
        oBtn.onclick = ()=>{
            
            iTimer = setInterval(()=>{
                // 点击按钮之后,让div的位置在当前的基础之上每次增加10px的距离
                // oDiv.style.left = oDiv.offsetLeft + 10 + 'px';  // 虽然此代码可以让div动起来,但是我们需要div在运动之后到达某个边界就立刻停止,所以需要将此句代码改为一个判断
                if (oDiv.offsetLeft === 500) {
                    // 清除定时器  
                    clearInterval(iTimer);
                }else { // 没有到达边界才能继续运动
                    oDiv.style.left = oDiv.offsetLeft + 10 + 'px'; 
                }
            },30);
            
            
        };
    </script>
</html>

在上面的代码中,我们点击按钮之后,元素已经可以直接进行移动,但是却存在一个问题,什么问题呢?

当我们点击按钮之后,元素始终以10px的匀速进行运动,到达500的临界然后停止。 但是我们的问题是,速度可能会变,例如将速度变为7px,就不能够
准确的到达500的临界值。

例如:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            #d1 {
                width: 100px;
                height: 100px;
                background-color: red;
                position: absolute;
                top:100px;
                left: 200px;
            }
        </style>
    </head>
    <body>
        <button id="btn">点击运动</button>
        <div id="d1"></div>
    </body>
    <script>
        // 点击按钮,让div横向的运动起来
        
        // 1. 获取元素
        let oBtn = document.getElementById('btn');
        let oDiv = document.getElementById('d1');
        let iTimer = null;
        // 点击按钮,让元素一直运动 ,需要使用到的知识点:定时器 
        oBtn.onclick = ()=>{
            
            iTimer = setInterval(()=>{
                // 点击按钮之后,让div的位置在当前的基础之上每次增加10px的距离
                // oDiv.style.left = oDiv.offsetLeft + 10 + 'px';  // 虽然此代码可以让div动起来,但是我们需要div在运动之后到达某个边界就立刻停止,所以需要将此句代码改为一个判断
                if (oDiv.offsetLeft === 500) {
                    // 清除定时器  
                    clearInterval(iTimer);
                }else { // 没有到达边界才能继续运动
                    oDiv.style.left = oDiv.offsetLeft + 7 + 'px';  // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
                }
            },30);
            
            
        };
    </script>
</html>

出现这种情况的原因是因为运动的临界值必须能够被运动的速度(也就是oDiv.offsetLeft + 7 + 'px',表示每次执行移动的距离)整除。

上面的代码当中, 因为临界值不能够被速度整除,所以,最终元素始终达到不了临界值,那么元素就没有办法在到达临界值时停止。

同时在上面的代码中的另外一个问题是,当我们每点击一次运动按钮,元素的速度就会变得更快,原因很简单,就是我们设置的定时器发生了累加。

那么该如何解决定时器累加的问题呢?

我们可以在每次开始运动之前先清楚一次定时器。

oBtn.onclick = ()=>{
            /*
            * 为了防止定时器累加,在每次开始定时器之前,先清楚掉一个定时器  
            * */
            clearInterval(iTimer);
            
            iTimer = setInterval(()=>{
                // 点击按钮之后,让div的位置在当前的基础之上每次增加10px的距离
                // oDiv.style.left = oDiv.offsetLeft + 10 + 'px';  // 虽然此代码可以让div动起来,但是我们需要div在运动之后到达某个边界就立刻停止,所以需要将此句代码改为一个判断
                if (oDiv.offsetLeft === 500) {
                    // 清除定时器  
                    clearInterval(iTimer);
                }else { // 没有到达边界才能继续运动
                    oDiv.style.left = oDiv.offsetLeft + 7 + 'px';  // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
                }
            },30);  
        };

总结:在上面的代码中,是我们一般让一个元素运动起来的基本流程。下面进行一个简单的总结:

  1. 首先是存在的问题:处于匀速运动的元素没有办法进行在不整除的情况下在临界点停止。
  2. 在上面的代码中,可以将整个过程大致分为三个步骤:
    • 清除定时器,保证只有一个定时器在执行
    • 开启定时器
    • 开始运动(需要同时加入一个判断,以便在需要的时候或者满足某个要求时停止运动)

简单运动的封装

为了让我们上面的代码可以具备更高的复用性,下面我们把上面的代码进行一个简单的封装。

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            #d1 {
                width: 100px;
                height: 100px;
                background-color: red;
                position: absolute;
                top:100px;
                left: 200px;
            }
        </style>
    </head>
    <body>
        <button id="btn">点击运动</button>
        <div id="d1"></div>
    </body>
    <script>
        // 点击按钮,让div横向的运动起来
        
        // 1. 获取元素
        let oBtn = document.getElementById('btn');
        let oDiv = document.getElementById('d1');
        let iTimer = null;
        // 点击按钮,让元素一直运动 ,需要使用到的知识点:定时器 
        oBtn.onclick = ()=>{    
            startMove(); 
            // 将运动相关的内容全部放到startMove这个函数中,然后调用既可以让元素进行运动
            function startMove() {
                clearInterval(iTimer);
                iTimer = setInterval(()=>{
                    if (oDiv.offsetLeft === 500) {
                        // 清除定时器  
                        clearInterval(iTimer);
                    }else { // 没有到达边界才能继续运动
                        oDiv.style.left = oDiv.offsetLeft + 10 + 'px';  // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
                    }
                },30);
            }
        };
    </script>
</html>

在上面的代码中,我们将运动相关的内容放到了一个函数startMove中,并且调用了这个函数,下面来根据这个函数进行案例的开发。

案例1:分享到功能

首先,先来实现基本的功能:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            #div1 {
                width: 100px;
                height: 200px;
                background:red;
                position: absolute;
                left: -100px;
                top: 200px;
            }
            #div2 {
                width: 30px;
                height: 70px;
                background: black;
                position:absolute;
                right:-30px;
                top: 70px;;
                color:#fff;
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="div1">
            <div id="div2">分享到</div>
        </div>
    </body>
    <script>
        // 1. 首先获取两个元素
        let oDiv1 = document.getElementById('div1');
        let oDiv2 = document.getElementById('div2');
        let iTimer = null;  
        
        // 给为父级的div绑定mouseover 和 mouseout事件 
        oDiv1.onmouseover = function() {
            this.style.left = 0 + 'px'; // 鼠标移入,让div元素出现
        };
        
        oDiv1.onmouseout = function() {
            this.style.left = -100 + 'px'; // 鼠标移出,让div隐藏
        }; 
        
    </script>
</html>

上面的代码中,我们鼠标移入,元素出现。鼠标移出,元素消失。
下面我们来使用我们的startMove函数,给元素出现和消失加上一个过渡的效果。

我们的startMove函数如下:

function startMove() {
    clearInterval(iTimer);
    iTimer = setInterval(()=>{
        if (oDiv.offsetLeft === 500) {
            // 清除定时器  
            clearInterval(iTimer);
        }else { // 没有到达边界才能继续运动
            oDiv.style.left = oDiv.offsetLeft + 10 + 'px';  // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
        }
    },30);
}

我们想要在分享到功能里使用这个函数,我们需要对我们的函数根据分享到的需求进行一定程度的更改。
首先是,将我们函数中的oDvi更改为oDiv1

其次是我们分享到案例的需求在鼠标移入时需要将元素逐渐的显示,而鼠标移出时,需要将元素逐渐的隐藏。所以我们需要将startMove函数创建两个
,并且当鼠标移出时,速度应该将函数中的+10变为-10

当然,也别忘了去更该元素边界的值。当移出时,边界为0,移入时,边界为-100.

如下:

鼠标移入时调用的startMove1函数:

function startMove1() {
    clearInterval(iTimer);
    iTimer = setInterval(()=>{
        if (oDiv1.offsetLeft === 0) {
            // 清除定时器  
            clearInterval(iTimer);
        }else { // 没有到达边界才能继续运动
            oDiv1.style.left = oDiv.offsetLeft + 10 + 'px';  // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
        }
    },30);
}

鼠标移出时调用的startMove2函数:

function startMove() {
    clearInterval(iTimer);
    iTimer = setInterval(()=>{
        if (oDiv1.offsetLeft === -100) {
            // 清除定时器  
            clearInterval(iTimer);
        }else { // 没有到达边界才能继续运动
            oDiv1.style.left = oDiv.offsetLeft - 10 + 'px';  // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
        }
    },30);
}

我们先来将这两个函数放在代码中,进行测试。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            #div1 {
                width: 100px;
                height: 200px;
                background:red;
                position: absolute;
                left: -100px;
                top: 200px;
            }
            #div2 {
                width: 30px;
                height: 70px;
                background: black;
                position:absolute;
                right:-30px;
                top: 70px;;
                color:#fff;
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="div1">
            <div id="div2">分享到</div>
        </div>
    </body>
    <script>
        // 1. 首先获取两个元素
        let oDiv1 = document.getElementById('div1');
        let oDiv2 = document.getElementById('div2');
        let iTimer = null;  
        
        // 给为父级的div绑定mouseover 和 mouseout事件 
        oDiv1.onmouseover = function() {
            // this.style.left = 0 + 'px'; // 鼠标移入,让div元素出现
            startMove1();
        };
        
        oDiv1.onmouseout = function() {
            // this.style.left = -100 + 'px'; // 鼠标移出,让div隐藏
            startMove2();
        }; 
        
        function startMove1() {
            clearInterval(iTimer);
            iTimer = setInterval(()=>{
                if (oDiv1.offsetLeft === 0) {
                    // 清除定时器  
                    clearInterval(iTimer);
                }else { // 没有到达边界才能继续运动
                    oDiv1.style.left = oDiv1.offsetLeft + 10 + 'px';  // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
                }
            },30);
        }
        function startMove2() {
            clearInterval(iTimer);
            iTimer = setInterval(()=>{
                if (oDiv1.offsetLeft === -100) {
                    // 清除定时器  
                    clearInterval(iTimer);
                }else { // 没有到达边界才能继续运动
                    oDiv1.style.left = oDiv1.offsetLeft - 10 + 'px';  // 一旦将每次的移动距离变为7px ,那么将不能停的下来.元素会一直运动
                }
            },30);
        }
    </script>
</html>

上面的代码中,我们通过创建两个startMove函数,并且对相应的参数进行修改,从而实现了给我们的分享到功能添加了过渡效果。

进一步升级:
当然,我们上面的代码中使用的函数其实是非常不灵活的,所以我们下面要做到事就是对之前的函数进行升级,从而让我们的函数具备更强的实用性。

首先我们再回过头来看下我们刚才写的两个函数,你会发现,大部分的代码其实都是相同的,只有个别的值是不同的,例如元素移动的边界,例如元素
单位时间内移动的距离。

我们将上面的两个函数合并成一个函数,只需要将不一样的值提取出来当做参数即可。

下面是合并之后的函数:

function startMove(iTarget,iSpeed) {
    clearInterval(iTimer);
    iTimer = setInterval(()=>{
        if (oDiv1.offsetLeft === iTarget) {
            // 清除定时器  
            clearInterval(iTimer);
        }else { // 没有到达边界才能继续运动
            oDiv1.style.left = oDiv1.offsetLeft +  iSpeed + 'px';  
        }
    },30);
}

上面的函数升级完成之后,我们在重新的将这个函数应用到我们的分享到功能的代码当中去。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            #div1 {
                width: 100px;
                height: 200px;
                background:red;
                position: absolute;
                left: -100px;
                top: 200px;
            }
            #div2 {
                width: 30px;
                height: 70px;
                background: black;
                position:absolute;
                right:-30px;
                top: 70px;;
                color:#fff;
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="div1">
            <div id="div2">分享到</div>
        </div>
    </body>
    <script>
        // 1. 首先获取两个元素
        let oDiv1 = document.getElementById('div1');
        let oDiv2 = document.getElementById('div2');
        let iTimer = null;  
        
        // 给为父级的div绑定mouseover 和 mouseout事件 
        oDiv1.onmouseover = function() {
            // this.style.left = 0 + 'px'; // 鼠标移入,让div元素出现
            startMove(0,10);
        };
        
        oDiv1.onmouseout = function() {
            // this.style.left = -100 + 'px'; // 鼠标移出,让div隐藏
            startMove(-100,-10);
        }; 
        
        function startMove(iTarget,iSpeed) {
            clearInterval(iTimer);
            iTimer = setInterval(()=>{
                if (oDiv1.offsetLeft === iTarget) {
                    // 清除定时器  
                    clearInterval(iTimer);
                }else { // 没有到达边界才能继续运动
                    oDiv1.style.left = oDiv1.offsetLeft +  iSpeed + 'px';  
                }
            },30);
        }
    </script>
</html>

上面的代码中,我们顺利的通过我们的startMove函数给分享到功能添加了过渡的效果。

图片的淡入淡出效果:

下面我们再来看另外的一个效果,图片的淡入淡出,还是通过我们上面定义好的startMove函数来实现效果。

首先,我们上面的函数当中,只是针对oDiv1,为了让我们的函数可以处理任意的元素,我们将oDiv1替换成函数的形参。

例如:

function startMove(oDom,iTarget,iSpeed) {
    clearInterval(iTimer);
    iTimer = setInterval(()=>{
        if (oDom.offsetLeft === iTarget) {
            // 清除定时器  
            clearInterval(iTimer);
        }else { // 没有到达边界才能继续运动
            oDom.style.left = oDom.offsetLeft +  iSpeed + 'px';  
        }
    },30);
}

上面的代码当中,我们将函数操作的元素提取出来,变成了函数的形参,这样做之后,我们就可以让我们的函数针对任意的元素。

原文地址:https://www.cnblogs.com/jhflyfish/p/11488850.html