首頁 > web前端 > js教程 > javascript運動詳解_javascript技巧

javascript運動詳解_javascript技巧

WBOY
發布: 2016-05-16 15:51:26
原創
1441 人瀏覽過

物體運動原理:透過改變物體的位置,而發生移動變化。

方法:

1.運動的物體使用絕對定位
2.透過改變定位物體的屬性(left、right、top、bottom)值來使物體移動。例如向右或左移動可以使用offsetLeft(offsetRight)來控制左右移動。

步驟:

1.開始運動前,先清除已有定時器 (因為:是連續點擊按鈕,物體會運動越來越快,造成運動混亂)
2、開啟定時器,計算速度
3.把運動和停止分開(if/else),判斷停止條件,執行運動

一.定時器

在javascritp中,有兩個關於定時器的專用函數,它們是:

1.倒數計時器:timename=setTimeout("function();",delaytime);
2.循環定時器:timename=setInterval("function();",delaytime);

  function()是定時器觸發時要執行的是事件的函數,可以是一個函數,也可以是幾個函數,或者javascript的語句也可以,單要用;隔開;delaytime則是間隔的時間,以毫秒為單位。

  倒數計時器就是在指定時間後觸發事件,而循環定時器就是在間隔時間到來時反覆觸發事件,其區別在於:前者只是作用一次,而後者則不停地作用。

  倒數計時器一般用於頁面上只需要觸發一次的情況,例如點擊某按鈕後頁面在一定時間後跳到相應的站點,也可以用於判斷一個瀏覽者是不是你的站點上的“老客”,如果不是,你就可以在5秒或10秒後跳到相應的站點,然後告訴他以後再來可以在某個地方按某一個按鈕就可以快速進入。

  循環定時器一般用於網站上需要從復執行的效果,例如一個javascript的滾動條或狀態欄,也可以用來將頁面的背景用飛雪的圖片來表示。這些事件需要隔一段時間運行一次。

  有時候我們也想去掉一些加上的定時器,此時可以用clearTimeout(timename) 來關閉倒數計時器,而用clearInterval(timename)來關閉循環計時器。

二.運動研究

1.運動:等速運動(讓物體動起來)

對定時器的使用
給DIV加絕對定位
offsetLeft

問題:到達某個特定位罝停符
解決:做判斷,符合條件時關掉定時器(存定時器timer)
速度變慢(一般不動時間,而是改數字-速度)
用變數存速度

問題:取7時,offsetLeft沒有等於300的時候,div停不下來
解決:>=300 //停在 301

問題:到300後點選按鈕還繼續走
原因:點選按鈕,執行函數,開定時器(執行目前函數一至少執行一次)
解決:加else (沒有到達目標之前才執行)

問題:連續點擊,速度變快
原因:每點擊一次就開一個定時器,點擊幾次就有幾個定時器同時工作
解決:保證每次只有一個定時器工作,先cearlnterval ()

範例1,

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>分享到</title>
<style>
#div1 {width:150px; height:200px; background:green; position:absolute; left:-150px;}
#div1 span {position:absolute; width:20px; height:60px; line-height:20px; background:blue; right:-20px; top:70px;}
</style>
<script>
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);
}
</script>
</head>

<body>
<div id="div1">
  <span>分享到</span>
</div>
</body>
</html>
登入後複製

效果如下:

範例2,淡入淡出:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>淡入淡出</title>
<style>
#div1 {width:200px; height:200px; background:red; filter:alpha(opacity:30); opacity:0.3;}
</style>
<script>
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);
}
</script>
</head>

<body>
<div id="div1"></div>
</body>
</html>
登入後複製

效果如下:

勻速運動的停止條件

距離夠近

範例3,勻速運動的停止條件:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>匀速运动的停止条件</title>
<style>
#div1 {width:100px; height:100px; background:red; position:absolute; left:600px; top:50px;}
#div2 {width:1px; height:300px; position:absolute; left:300px; top:0; background:black;}
#div3 {width:1px; height:300px; position:absolute; left:100px; top:0; background:black;}
</style>
<script>
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;
    }
    
    if(Math.abs(iTarget-oDiv.offsetLeft)<=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>
登入後複製

2.變速運動(緩衝運動)

逐漸變慢,最後停止
距離越遠速度越大
速度有距離決定
速度=(目標值-目前值)/縮放係數
如果沒有縮放係數t速度太大,瞬間到達終點.沒有過程

問題:並沒有真正到達300
原因:速度只剩0.9 //像素是螢幕能顯示的最/J庫位,並不會四捨五入掉
Math.ceil ()向上取整
Math.floor ()向下取整

問題:往左走,又差一塊--Math.floor ()
判斷:三目 speed=speed>0 ? Math.ceil ( speed ): Math.floor ( speed )

例,緩衝運動:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>缓冲运动</title>
<style>
#div1 {width:100px; height:100px; background:red; position:absolute; left:600px; top:50px;}
#div2 {width:1px; height:300px; position:absolute; left:300px; top:0; background:black;}
</style>
<script>
function startMove()
{
  var oDiv=document.getElementById('div1');
  setInterval(function (){
    var speed=(300-oDiv.offsetLeft)/10;
    speed=speed>0&#63;Math.ceil(speed):Math.floor(speed);
    
    oDiv.style.left=oDiv.offsetLeft+speed+'px';
    
    document.title=oDiv.offsetLeft+','+speed;
  }, 30);
}
</script>
</head>

<body>
<input type="button" value="开始运动" onclick="startMove()" />
<div id="div1"></div>
<div id="div2"></div>
</body>
</html>
登入後複製

效果如下:

3.多物体运动

多个div ,鼠标移入变宽
运动框架传参obj,知道让哪个物体动起来
用到缓冲一定要取整

问题:div没运动回去 //清除前一个定时器
原因:只有一个定时器
解决:加物体上的定时器,使每个物体都有一个定时器。定时器作为物体属性

多个div淡入淡出
首先关闭物体上的定时器
经验:多物体运动框架所有东西都不能共用

问题:不是因为定时器,而是因为alpha
解决:作为属性附加到物体上 /不以变量形式存在

offset 的 bug

加border变宽

offsetWith并不是真正的width ,它获取的是盒模型尺寸
解决:躲着 宽度扔到行间,parselnt ( oDiv.style.width )

进一步解决: getStyle ( obj, name ) currentStyle , getComputedStyle
加border ,只要offset就有问题 去掉offset

示例,多物体运动:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
div {width:100px; height:50px; background:red; margin:10px; border:10px solid black;}
</style>
<script>
window.onload=function ()
{
  var aDiv=document.getElementsByTagName('div');
  
  for(var i=0;i<aDiv.length;i++)
  {
    aDiv[i].timer=null;
    
    aDiv[i].onmouseover=function ()
    {
      startMove(this, 400);
    };
    
    aDiv[i].onmouseout=function ()
    {
      startMove(this, 100);
    };
  }
};

function startMove(obj, iTarget)
{
  clearInterval(obj.timer);
  obj.timer=setInterval(function (){
    var speed=(iTarget-obj.offsetWidth)/6;
    speed=speed>0&#63;Math.ceil(speed):Math.floor(speed);
    
    if(obj.offsetWidth==iTarget)
    {
      clearInterval(obj.timer);
    }
    else
    {
      obj.style.width=obj.offsetWidth+speed+'px';
    }
  }, 30);
}
</script>
</head>

<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
登入後複製

效果如下:

4.任意值运动

任意值运动的单位分为透明度和px。

px单位的任意值

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
div {width:200px; height:200px; margin:20px; float:left; background:yellow; border:10px solid black; font-size:14px;}
</style>
<script>
window.onload=function ()
{
  var oDiv1=document.getElementById('div1');
  oDiv1.onmouseover=function (){startMove(this, 'height', 400);};
  oDiv1.onmouseout=function (){startMove(this, 'height', 200);};
  
  var oDiv2=document.getElementById('div2');
  
  oDiv2.onmouseover=function (){startMove(this, 'width', 400);};
  oDiv2.onmouseout=function (){startMove(this, 'width', 200);};
  
  var oDiv3=document.getElementById('div3');
  oDiv3.onmouseover=function (){startMove(this, 'fontSize', 50);};
  oDiv3.onmouseout=function (){startMove(this, 'fontSize', 14);};
  
  var oDiv4=document.getElementById('div4');
  oDiv4.onmouseover=function (){startMove(this, 'borderWidth', 100);};
  oDiv4.onmouseout=function (){startMove(this, 'borderWidth', 10);};
};

function getStyle(obj, name)
{
  if(obj.currentStyle){return obj.currentStyle[name];}
  else{return getComputedStyle(obj, false)[name];}
}

function startMove(obj, attr, iTarget)
{
  clearInterval(obj.timer);
  obj.timer=setInterval(function (){
    var cur=parseInt(getStyle(obj, attr));
    
    var speed=(iTarget-cur)/6;
    speed=speed>0&#63;Math.ceil(speed):Math.floor(speed);
    
    if(cur==iTarget)
    {
      clearInterval(obj.timer);
    }
    else
    {
      obj.style[attr]=cur+speed+'px';
    }
  }, 30);
}
</script>
</head>

<body>
<div id="div1">变高</div>
<div id="div2">变宽</div>
<div id="div3">safasfasd</div>
<div id="div4"></div>
</body>
</html>
登入後複製

效果如下:

透明度的任意值,需要做判断:

判断
var cur=0
if ( attr== 'opacity '){
cur=parseFloat ( getStyle ( obj, attr)) *100
}else{

}
设置样式判断
if ( attr== 'opacity '){
obj.style.fiIter = 'alpha ( opacity: '( cur+speed ) + ')'
obj.style.opacity= ( cur+speed ) /100
}else{

}
登入後複製

5.链式运动

多出来的一个参数,只有传进去的时候才调用
鼠标移入变宽,结束之后弹出abc
先横向展开.再以向展开
鼠标移出,先变回不透明,变矮,变窄

三.封装运动框架(源码下载:https://github.com/jingwhale/jsmove/blob/master/move.js)

基于以上的分析与总结,封装运动框架move.js如下:

function getStyle(obj, name)
{
  if(obj.currentStyle)
  {
    return obj.currentStyle[name];
  }
  else
  {
    return getComputedStyle(obj, false)[name];
  }
}

function startMove(obj, json, fnEnd)
{
  clearInterval(obj.timer);
  obj.timer=setInterval(function (){
    var bStop=true;    //假设:所有值都已经到了
    
    for(var attr in json)
    {
      var cur=0;
      
      if(attr=='opacity')
      {
        cur=Math.round(parseFloat(getStyle(obj, attr))*100);
      }
      else
      {
        cur=parseInt(getStyle(obj, attr));
      }
      
      var speed=(json[attr]-cur)/6;
      speed=speed>0&#63;Math.ceil(speed):Math.floor(speed);
      
      if(cur!=json[attr])
        bStop=false;
      
      if(attr=='opacity')
      {
        obj.style.filter='alpha(opacity:'+(cur+speed)+')';
        obj.style.opacity=(cur+speed)/100;
      }
      else
      {
        obj.style[attr]=cur+speed+'px';
      }
    }
    
    if(bStop)
    {
      clearInterval(obj.timer);
            
      if(fnEnd)fnEnd();
    }
  }, 30);
}
登入後複製

move.js运动框架基本满足现在网页上所有动画的需求(不包括css3)。

四.应用应用

1,完成如下效果:

js代码如下:

<script src="move.js"></script>
<script>
window.onload=function ()
{
  var oDiv=document.getElementById('play');
  var aBtn=oDiv.getElementsByTagName('ol')[0].getElementsByTagName('li');
  var oUl=oDiv.getElementsByTagName('ul')[0];
  
  var now=0;
  for(var i=0;i<aBtn.length;i++)
  {
    aBtn[i].index=i;
    aBtn[i].onclick=function ()
    {
      now=this.index;
      tab();
    };
  }
  
  function tab()
  {
    for(var i=0;i<aBtn.length;i++)
    {
      aBtn[i].className='';
    }
    aBtn[now].className='active';
    startMove(oUl, {top: -150*now});
  }
  
  function next()
  {
    now++;
    if(now==aBtn.length){now=0;}
    tab();
  }
  
  var timer=setInterval(next, 2000);
  
  oDiv.onmouseover=function (){clearInterval(timer);};
  
  oDiv.onmouseout=function (){timer=setInterval(next, 2000);};
};
</script>
登入後複製

应用2,完成如下效果:

代码如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
.....
</style>
<script type="text/javascript" src="move.js"></script>
<script type="text/javascript">
window.onload=function ()
{
  var oBtn=document.getElementById('but');
  var oBottom=document.getElementById('zns_bottom');
  var oBox=document.getElementById('zns_box');
  var oBtnClose=document.getElementById('btn_close');
  
  oBox.style.display='block';
  var initBottomRight=parseInt(getStyle(oBottom, 'right'));
  var initBoxBottom=parseInt(getStyle(oBox, 'bottom'));
  oBox.style.display='none';
  
  oBtn.onclick=openHandler;
  oBtnClose.onclick=closeHandler;
  
  function openHandler()
  {
    startMove(oBottom, {right: 0}, function (){
      oBox.style.display='block';
      startMove(oBox, {bottom: 0});
    });
    oBtn.className='but_hide';
    oBtn.onclick=closeHandler;
  }
  
  function closeHandler()
  {
    startMove(oBox, {bottom: initBoxBottom}, function (){
      oBox.style.display='none';
      startMove(oBottom, {right: initBottomRight}, function (){
        oBtn.className='but_show';
      });
    });
    oBtn.onclick=openHandler;
  }
};
</script>
</head>
<body>
  ......
</body>
</html>
登入後複製

源码下载:https://github.com/jingwhale/jsmove

以上所述就是本文的全部内容了,希望大家能够喜欢。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板