【JavaScript从入门到精通】第十五课 JS运动基础-01

此内容来自开课吧石川微信公众号

这节课开始我们来讲解JS的运动。在前面关于定时器的内容里,我们已经对JS运动有了一定的了解,接下来几节课我们将慢慢深入,逐渐解析JS运动的知识和原理。

运动基础

我们列举一个我们已经写过的最简单的例子:

function startMove(){
    var oDiv=document.getElementById('div1');
    setInterval(function(){
        oDiv.style.left=oDiv.offsetLeft+10+'px';
    },30);
}

现在我们希望这个运动可以停下来,因此我们加入以下判断:当div1的offsetLeft等于300时,我们将定时器关掉。

function startMove(){
    var oDiv=document.getElementById('div1');
    timer=setInterval(function(){
      if(oDiv.offsetLeft==300)
      {
        clearInterval(timer);
      }
      oDiv.style.left=oDiv.offsetLeft+10+'px';
    },30);
}

效果如下:

【JavaScript从入门到精通】第十五课 JS运动基础-01

这里我们可以用一个变量储存定时器的时间,通过修改变量的值,可以改变div块的运行速度,但修改变量的值(比如修改为7),我们会发现div块有可能不会在我们规定的位置停下,原因是我们判断关闭定时器的条件是oDiv.offsetLeft==300,但有些数值并不能整除300,因此不会判断定时器关闭。所以这里,我们将条件改为

oDiv.offsetLeft>=300,就可以解决这个问题。

运动停止后我们尝试多次点击开始运动按钮,可以发现每点击一次按钮,div块都会前进一步,这是因为每次点击都会执行一遍定时器里的函数,而关闭定时器是从下一次开始执行的,当前函数还会完整执行一次。为了避免这种情况,我们将运动的代码也加入判断:当oDiv.offsetLeft>=300时,关闭定时器,<300时执行运动效果。

function startMove(){
    var oDiv=document.getElementById('div1');
    timer=setInterval(function(){
      if(oDiv.offsetLeft==300)
      {
        clearInterval(timer);
      }
      else {
        oDiv.style.left=oDiv.offsetLeft+10+'px';
      }
    },30);
}

当物体还在运动时,我们如果点击按钮,会发现,随着点击次数的增加,div块的运动速度会越来越快。试想,当我们每点击一次按钮,就会开一个定时器,随着点击次数的增多同时打开的定时器也会增加并且效果叠加,自然速度会变快。因此,我们有必要保证同一时刻只有一个定时器在工作。达成这个目的非常简单,在定时器运行之前,我们将之前所有定时器关掉即可。

function startMove(){
    var oDiv=document.getElementById('div1');
    clearInterval(timer);
    timer=setInterval(function(){
      if(oDiv.offsetLeft==300)
      {
        clearInterval(timer);
      }
      else {
        oDiv.style.left=oDiv.offsetLeft+10+'px';
      }
    },30);    
}

现在,我们就拥有了一套比较完整的运动程序,在我们以后设计运动的时候,都要考虑到这几个可能会出现bug的因素:

  • 不会停止
  • 速度取某些值会无法停止
  • 到达位置后再点击还会运动
  • 重复点击速度加快

运动框架及应用之侧边栏

我们将刚才那一套完整的运动程序成为运动框架,使用运动框架的流程基本上可以搞定大部分的运动,在后面的学习中我们会不断地完善运动框架。在运动框架中,主要遵循这么两个原则:

  • 在开始运动时,关闭已有定时器(避免定时器同时工作)
  • 把运动和停止隔开(if/else)(后者到达终点以后执行,前者到达终点前执行)

在有了一个简单的运动框架后,我们就可以做一个小例子了。这里我们试着写一个在网页上随处可见的例子——侧边栏。其具体功能为,当我们将鼠标移入侧边栏的提示时侧边栏逐渐出现,鼠标移出时侧边栏逐渐消失。

我们依旧是从布局开始分析,我们在网页中放入一个div块并在里面放入一个span标签,并添加文字提示内容。css布局如下:

#div1 {width:150px; height:200px; background:green; position:absolute;}
#div1 span {position:absolute; width:20px; height:60px; line-height:20px; background:blue; right:-20px; top:70px;}

为了让这个侧框动起来,我们需要用到定时器。在一开始的时候,这个div应该是在左侧隐藏起来的,因此还需要在css里添加其left值将其隐藏(-150px)。接下来运用我们前面的运动框架,鼠标移入时,使div块向右运动,鼠标移出时,使得div块向左运动(可以通过参数的形式将这两个函数合并):

window.onload = 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);
}

效果如下:

【JavaScript从入门到精通】第十五课 JS运动基础-01

运动框架及应用之淡入淡出

淡入淡出也是网页的常见功能,我们希望在鼠标移入时,图片变得清晰,鼠标移出时,图片变得透明。大家应该都知道,在css里,控制透明度使用的是filter属性(IE)以及opacity属性(chrome)。使用透明度属性配合运动框架,就可以实现我们想要的淡入淡出效果了。

<html>
<head>
    <meta charset="utf-8">
    <title>无标题文档</title>
</head>
<body>
<div id="div1"></div>
</body>
</html>
#div1 {
    width: 200px;
    height: 200px;
    background: red;
    filter: alpha(opacity:30);
    opacity: 0.3;
}
window.onload = function () {
    var oDiv = document.getElementById('div1');
    oDiv.onmouseover = function () {
        startMove(100);
    };
    oDiv.onmouseout = function () {
        startMove(30);
    };
};
var alpha = 30;
var timer = null;

function startMove(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 + ')';
                oDiv.style.opacity = alpha / 100;
            }
        },
        30);
};

效果如下:

【JavaScript从入门到精通】第十五课 JS运动基础-01

其中,我们用alpha变量储存透明度的值,并通过判断alpha的值来决定是关闭定时器还是执行运动,实际上图片透明度的变化是由alpha值的变化而产生。

如需转载,烦请注明出处:https://www.qdskill.com/javascript/537.html

发表评论

登录后才能评论