javascript运动详解


Posted in Javascript onJuly 06, 2015

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

方法:

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>

效果如下:

javascript运动详解

示例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>

效果如下:

javascript运动详解

匀速运动的停止条件

距离足够近

示例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?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>

效果如下:

javascript运动详解

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

效果如下:

javascript运动详解

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

效果如下:

javascript运动详解

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

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

javascript运动详解

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

javascript运动详解

代码如下:

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

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

Javascript 相关文章推荐
用Javascript获取页面元素的具体位置
Dec 09 Javascript
js 对小数加法精度处理示例说明
Dec 27 Javascript
原生js的弹出层且其内的窗口居中
May 14 Javascript
JS清除文本框内容离开在恢复及鼠标离开文本框时触发js的方法
Jan 12 Javascript
JavaScript将DOM事件处理程序封装为event.js 出现的低级错误问题
Aug 03 Javascript
深入理解jQuery3.0的domManip函数
Sep 01 Javascript
Node.js中看JavaScript的引用
Apr 22 Javascript
Node.js微信 access_token ( jsapi_ticket ) 存取与刷新的示例
Sep 30 Javascript
vue.js 输入框输入值自动过滤特殊字符替换中问标点操作
Aug 31 Javascript
vue 导航守卫和axios拦截器有哪些区别
Dec 19 Vue.js
AJAX实现指定部分页面刷新效果
Oct 16 Javascript
Vue OpenLayer 为地图绘制风场效果
Apr 24 Vue.js
浅谈jQuery中height与width
Jul 06 #Javascript
jQuery中$this和$(this)的区别介绍(一看就懂)
Jul 06 #Javascript
浅谈Javascript实现继承的方法
Jul 06 #Javascript
JavaScript保存并运算页面中数字类型变量的写法
Jul 06 #Javascript
angularjs客户端实现压缩图片文件并上传实例
Jul 06 #Javascript
jQuery 遍历函数详解
Jul 05 #Javascript
php结合imgareaselect实现图片裁剪
Jul 05 #Javascript
You might like
PHP教程之PHP中shell脚本的使用方法分享
2012/02/23 PHP
Codeigniter检测表单post数据的方法
2015/03/21 PHP
浅谈htmlentities 、htmlspecialchars、addslashes的使用方法
2016/12/09 PHP
redis查看连接数及php模拟并发创建redis连接的方法
2016/12/15 PHP
JS类库Bindows1.3中的内存释放方式分析
2007/03/08 Javascript
multiSteps 基于Jquery的多步骤滑动切换插件
2011/07/22 Javascript
jQuery中$.fn的用法示例介绍
2013/11/05 Javascript
jquery选择器之属性过滤选择器详解
2014/01/27 Javascript
js使用ajax读博客rss示例
2014/05/06 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
2016/06/12 Javascript
Javascript之面向对象--接口
2016/12/02 Javascript
在js代码拼接dom对象到页面上去的模板总结(必看)
2017/02/14 Javascript
关于vue.js v-bind 的一些理解和思考
2017/06/06 Javascript
基于JS实现移动端左滑删除功能
2017/07/28 Javascript
Angular刷新当前页面的实现方法
2018/11/21 Javascript
Vue一次性简洁明了引入所有公共组件的方法
2018/11/28 Javascript
JavaScript中this的全面解析及常见实例
2019/05/14 Javascript
jQuery Migrate 插件用法实例详解
2019/05/22 jQuery
微信小程序mpvue点击按钮获取button值的方法
2019/05/29 Javascript
js实现无刷新监听URL的变化示例代码详解
2020/06/03 Javascript
Vue组件跨层级获取组件操作
2020/07/27 Javascript
python time模块用法实例详解
2014/09/11 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
OpenCV HSV颜色识别及HSV基本颜色分量范围
2019/03/22 Python
TensorFlow实现checkpoint文件转换为pb文件
2020/02/10 Python
基于python判断字符串括号是否闭合{}[]()
2020/09/21 Python
Too Faced官网:美国知名彩妆品牌
2017/03/07 全球购物
John Hardy官方网站:手工设计首饰的奢侈品牌
2017/07/05 全球购物
全球最大的中文旅行网站:去哪儿网
2017/11/16 全球购物
美国电力供应商店/电气批发商:USESI
2018/10/12 全球购物
支部鉴定材料
2014/06/02 职场文书
好听的队名和口号
2014/06/09 职场文书
购房委托书
2014/10/15 职场文书
资产运营委托书范本
2014/10/16 职场文书
《藏戏》教学反思
2016/02/23 职场文书