javascript运动详解

javascript运动详解

本文给大家详细介绍下如何使用javascript来实现运动效果,总结的十分全面,附上各种效果的详细示例和演示图,有需要的小伙伴可以参考下。

物体运动原理:通过改变物体的位置,而发生移动变化。

方法:

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,

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

<!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,淡入淡出:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

<!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,匀速运动的停止条件:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

<!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 )

示例,缓冲运动:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<!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?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

示例,多物体运动:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<!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?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单位的任意值

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

<!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?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>

效果如下:

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

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

判断

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如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

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?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代码如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

<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,完成如下效果:

代码如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

<!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

时间: 2024-08-02 02:41:58

javascript运动详解的相关文章

javascript事件详解笔记

javascript事件详解笔记: 一.事件流 1.事件流: 描述的是页面中接受事件的顺序,有事件冒泡.事件捕获两种. 2.事件冒泡: 由最具体的元素接收,然后逐级向上传播到最不具体的元素的节点(文档). 3.事件捕获: 最不具体的节点先接收事件,而最具体的节点应该是最后接收事件. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>事件</title&

JavaScript prototype 详解(对prototype 使用的一些讲解)

对JavaScript有一定了解的你,对jquery不陌生吧,那你看jQuery源代码的时候对prototype 也一定有见过,如果对prototype有疑问或者想更深入的去了解与使用它,欢迎你继续往下阅读. 最初的用法是, 为了避免方法在构造器里随机数据被实例化时而产生重复的副本  后来被用在"继承"上面了, 注意, JS语义上是没有继承的, 这里说的是人为的实现.对于下面对JavaScript中类型名称叫做"对象"."函数"."类型

Javascript学习--------详解window窗口对象

对话框: 警告对话框:alert(): 语法:window.alert(src)或者alert(src); 询问回答对话框:confirm(): 语法:window.confrim(question)或者confrim(question); 单击确认,返回true: 单击取消,返回false 提示对话框:prompt(): 语法:window.prompt([showtxt],[defaultTxt])或者prompt([showtxt],[defaultTxt]); 单击确认,返回输入的文本:

JavaScript事件详解-zepto的事件实现

zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们可以看到,整个event模块,事件绑定核心就是on和off,还有一个trigger用来触发,类观察者模式,可以先看看汤姆大叔的深入理解JavaScript系列(32):设计模式之观察者模式,其余皆为实现的处理函数.首先来个demo: $("#btn").on("click&quo

javascript 函数详解2 -- arguments

今天我们接着上篇文章来继续javascript函数这个主题.今天要讲的是函数对像中一个很重要的属性--arguments. 相关阅读: javascript 函数详解1 -- 概述 javascript 函数详解2 -- arguments Javascript 函数详解3 -- this对象 Javascript 函数详解4 -- 函数的其他属性 Javascript 函数详解5 -- 函数对象的内部函数 arguments对象参数数组引用 arguments是函数对象内部一个比较特殊的类数组

JavaScript正则表达式详解(一)正则表达式入门

JavaScript正则表达式是很多JavaScript开发人员比较头疼的事情,也很多人不愿意学习,只是必要的时候上网查一下就可以啦~本文中详细的把JavaScript正则表达式的用法进行了列表,希望对于大家学习JavaScript正则表达式有一定的帮助. 建立正则表达式对象语法 re = new RegExp(/pattern/[flags]) flags 参数说明: g (全文查找出现的所有 pattern) i (忽略大小写) m (多行查找) 普通字符 描述 \ 将下一个字符标记为一个特

JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 exec方法的返回值 exec方法返回的其实并不是匹配结果字符串,而是一个对象,简单地修改一下execReg函数,来做一个实验就可以印证这一点: function execReg(reg, str) { var result = reg.exec(str); alert(typeof result

JavaScript 对象详解

1 创建对象的方法 最常见的创建对象方法是通过new调用构造函数,此外还有一个方法就是使用Object.create(),将一个原型对象作为参数传递给Object.create也可以创建一个继承了其属性的新对象.但是和使用new创建对象还有一点差别,那就是构造函数不会被调用.所以如果使用这种方法创建一个foo新对象,其foo.f是undefined的: function Foo(z) { this.f = z; } Foo.prototype.add = function(x, y) { ret

javascript原型详解

1.原型基本特征: ps:1.原型类型与其他语言的一个类,所定义的属性,方法可以被此类产生的所有对象所共享 2.修改原型的属性或者方法,会立即生效,其派生的子类的属性,方法也将改变 例子1: function Mytest(){ } Mytest.prototype.name="jerry"; var test1=new Mytest(); alert(test1.name);//jerry Mytest.prototype.name="jack"; var tes