简单的运动基础
简单案例演示(让div运动):
1 <script> 2 var timer=null; 3 4 function startMove(){ 5 var oDiv=document.getElementById('div'); 6 7 clearInterval(timer); 8 //每次startMove()事件触发,关闭之前的定时器(避免多次触发,调用多次定时器) 9 10 timer=setInterval(function(){ //开启定时器,让div运动起来 11 if(oDiv.offsetLeft>=400){ 12 clearInterval(timer); //让div在固定位置停止运动 13 } 14 else{ 15 oDiv.style.left=oDiv.offsetLeft+10+'px'; 16 //让div以10px距离的速度进行运动,即改变div左边距到窗口的长度 17 } 18 },30); 19 } 20 </script>
运动框架:
每个运动的事物都必须遵守运动框架这个规则!!!
1>在开始运动时,关闭已有的定时器
2>把运动和停止隔开(if/else)
以上的简单代码中,第7行代码中,遵循了运动框架第1条;第11-15行代码中,遵循了运动框架第二条
运动框架实例
(一)匀速运动
》含义:物体以一个固定速度做移动
案例一:“分享到”侧边栏的案例
实现效果如下:
代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 body{ 10 margin: 0; 11 padding: 0; 12 } 13 #div{ 14 width: 100px; 15 height: 200px; 16 background: #cccccc; 17 position: absolute; 18 left: -100px; 19 } 20 #div span{ 21 width: 20px; 22 height: 60px; 23 line-height: 20px; 24 text-align: center; 25 background: yellow; 26 position:absolute; 27 left: 100px; 28 top: 50px; 29 } 30 </style> 31 <script> 32 window.onload=function(){ 33 var oDiv=document.getElementById('div'); 34 oDiv.onmousemove=function(){ 35 startMove(); 36 } 37 oDiv.onmouseout=function(){ 38 stopMove(); 39 } 40 } 41 42 var timer=null; 43 function startMove(){ 44 var oDiv=document.getElementById('div'); 45 clearInterval(timer); 46 timer=setInterval(function(){ 47 if(oDiv.offsetLeft==0){ 48 clearInterval(timer); 49 } 50 else{ 51 oDiv.style.left=oDiv.offsetLeft+10+'px'; 52 } 53 },30) 54 } 55 function stopMove(){ 56 var oDiv=document.getElementById('div'); 57 clearInterval(timer); 58 timer=setInterval(function(){ 59 if(oDiv.offsetLeft==-100){ 60 clearInterval(timer); 61 } 62 else{ 63 oDiv.style.left=oDiv.offsetLeft-10+'px'; 64 } 65 },30) 66 } 67 </script> 68 </head> 69 <body> 70 <div id="div"> 71 <span id="span">分享到</span> 72 </div> 73 </body> 74 </html>
以上js代码有很多重复的地方,下面让它简化一下:(整合成一个方法即可)
1 <script> 2 window.οnlοad=function(){ 3 var oDiv=document.getElementById('div'); 4 oDiv.οnmοusemοve=function(){ 5 Move(0); //当iTarget:目标位置为0时 6 } 7 oDiv.οnmοuseοut=function(){ 8 Move(-100); //当iTarget:目标位置为-100时 9 } 10 } 11 12 var timer=null; 13 function Move(iTarget){ //传参数,iTarget表示目标位置 14 var oDiv=document.getElementById('div'); 15 clearInterval(timer); 16 timer=setInterval(function(){ 17 var iSpeed=0; 18 if(oDiv.offsetLeft<iTarget){ //做判断 【通过目标点left的距离计算速度的值】 19 iSpeed=10; //若当前div左边距到界面上的长度<目标位置,则速度为正 20 } 21 else{ 22 iSpeed=-10; //反之,则速度为负 23 } 24 25 if(oDiv.offsetLeft==iTarget){ 26 clearInterval(timer); 27 } 28 else{ 29 oDiv.style.left=oDiv.offsetLeft+iSpeed+'px'; 30 } 31 },30) 32 } 33 </script>
案例二:“淡入淡出的图片”案例
实现效果如下:
代码如下:(简化写法【即传入一个参数、调用一个函数即可】)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #img{ 10 width: 50%; 11 opacity: 0.3; 12 } 13 </style> 14 <script> 15 window.onload=function(){ 16 var oImg=document.getElementById('img'); 17 oImg.onmouseover=function(){ 18 change(100); //当鼠标移入图片,设置它的“透明度”最后值为100 19 } 20 oImg.onmouseout=function(){ 21 change(30); //当鼠标移出图片,设置它的“透明度”最后值为30 22 } 23 } 24 25 var timer=null; 26 var opacity=30; 27 //额外设置变量表示“透明度”的值,后面通过修改这个值来让图片改变“透明度” 28 //因为获取不到图片的透明值,所以只能用变量来代替(不像offsetWidth一样可以获取宽度) 29 30 function change(iTarget){ //传入一个参数,用于表示“透明度”的最后值 31 var oImg=document.getElementById('img'); 32 33 clearInterval(timer); //至关重要的一步!!!!要记得清除原有的计时器 34 timer=setInterval(function(){ 35 var iSpeed=0; 36 if(opacity<iTarget){ //做判断 【通过目标“透明度”计算速度的值】 37 iSpeed=6; //若当前图片“透明度”<目标“透明度”,则速度为正 38 } 39 else{ 40 iSpeed=-6; //反之,则速度为负 41 } 42 43 if(opacity==iTarget){ 44 clearInterval(timer); 45 } 46 else{ 47 opacity+=iSpeed; 48 if(opacity>=100){ 49 //当改变速度iSpeed的值时,若最后加在一起的“透明度”数值大于等于100时,直接设置“透明度”为100即可 50 opacity=100; 51 } 52 else if(opacity<=30){ 53 opacity=30; 54 } 55 oImg.style.opacity=opacity/100; 56 //因为opacity的值为0-1之间的值,所以取值要除以100 57 } 58 },30) 59 } 60 </script> 61 </head> 62 <body> 63 <img id="img" src="PPT.jpg" alt="PPT"> 64 </body> 65 </html>
(二)缓冲运动
》含义:物体移动逐渐变慢,最后停止
案例一:div以缓冲运动进行移动的案例
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #div{ 10 width: 100px; 11 height: 100px; 12 background: #ccc; 13 position: absolute; 14 left: 0; 15 top: 50px; 16 } 17 </style> 18 <script> 19 window.onload=function(){ 20 var oBtn=document.getElementById('btn'); 21 oBtn.onclick=function(){ 22 Move(400); 23 } 24 } 25 var timer=null; 26 function Move(iTarget){ 27 var oDiv=document.getElementById('div'); 28 clearInterval(timer); 29 timer=setInterval(function(){ 30 var iSpeed=(iTarget-oDiv.offsetLeft)/8; 31 //让速度的值随div靠近目标距离的长度而减小 32 if(oDiv.offsetLeft==iTarget){ 33 clearInterval(timer); 34 } 35 else{ 36 oDiv.style.left=oDiv.offsetLeft+iSpeed+'px'; 37 } 38 },30) 39 } 40 </script> 41 </head> 42 <body> 43 <input id="btn" type="button" value="click"> 44 <div id="div"></div> 45 </body> 46 </html>
//以上代码轻松实现了,div向右进行缓冲运动。
所谓缓冲运动就是物体移动逐渐变慢,最后停止。而且距离越远速度越大【速度由距离决定;速度=(目标-当前值)/缩放系数】
但是,上面的这段代码存在一个bug,就是物体没有达到所规定的400px的距离。(以上代码,最后div的移动距离为:394.75px)
修改以上bug问题,完整的代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #div{ 10 width: 100px; 11 height: 100px; 12 background: #ccc; 13 position: absolute; 14 left: 0; /*div的设置了left,值为0*/ 15 top: 50px; 16 } 17 </style> 18 <script> 19 window.onload=function(){ 20 var oBtn=document.getElementById('btn'); 21 oBtn.onclick=function(){ 22 Move(400); 23 } 24 } 25 var timer=null; 26 function Move(iTarget){ 27 var oDiv=document.getElementById('div'); 28 clearInterval(timer); 29 timer=setInterval(function(){ 30 var iSpeed=(iTarget-oDiv.offsetLeft)/8; 31 //如上所示div运动到394.75px就不动了 32 //原因是div到394.75px的位置速度就变成0.75了,这时计算机会让距离转化成整数394px。 33 //因为下次速度还是0.75,所以相加以后,距离依然为394.75。。就这样一直进入这个死循环中。 34 35 iSpeed=Math.ceil(iSpeed); //所以用向上取整的方法,让后面的速度(0.75)变成整数“1” 36 //Math.ceil()即:向上取整 37 38 if(oDiv.offsetLeft==iTarget){ 39 clearInterval(timer); 40 } 41 else{ 42 oDiv.style.left=oDiv.offsetLeft+iSpeed+'px'; 43 } 44 },30) 45 } 46 </script> 47 </head> 48 <body> 49 <input id="btn" type="button" value="click"> 50 <div id="div"></div> 51 <span style="width: 1px; height:200px; background:red; position:fixed;left:400px;"></span> 52 </body> 53 </html>
效果图如下:
若要让div从右往左移动呢???只需要修改成下面的代码即可!!
代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #div{ 10 width: 100px; 11 height: 100px; 12 background: #ccc; 13 position: absolute; 14 right: 0; /*div的设置了right,值为0*/ 15 top: 50px; 16 } 17 </style> 18 <script> 19 window.onload=function(){ 20 var oBtn=document.getElementById('btn'); 21 oBtn.onclick=function(){ 22 Move(400); 23 } 24 } 25 var timer=null; 26 function Move(iTarget){ 27 var oDiv=document.getElementById('div'); 28 clearInterval(timer); 29 timer=setInterval(function(){ 30 var iSpeed=(iTarget-oDiv.offsetLeft)/8; 31 32 iSpeed=Math.floor(iSpeed); //向下取整 33 34 if(oDiv.offsetLeft==iTarget){ 35 clearInterval(timer); 36 } 37 else{ 38 oDiv.style.left=oDiv.offsetLeft+iSpeed+'px'; 39 } 40 },30) 41 } 42 </script> 43 </head> 44 <body> 45 <input id="btn" type="button" value="click"> 46 <div id="div"></div> 47 <span style="width: 1px; height:200px; background:red; position:fixed;left:400px;"></span> 48 </body> 49 </html>
最后,把上面的代码整合一下,用if语句来包裹速度的求值,做向左还是向右的动作,只需要修改css中的left/right即可。
最终代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #div{ 10 width: 100px; 11 height: 100px; 12 background: #ccc; 13 position: absolute; 14 left: 0; 15 /*right:0*/ 16 top: 50px; 17 } 18 </style> 19 <script> 20 window.onload=function(){ 21 var oBtn=document.getElementById('btn'); 22 oBtn.onclick=function(){ 23 Move(400); 24 } 25 } 26 var timer=null; 27 function Move(iTarget){ 28 var oDiv=document.getElementById('div'); 29 clearInterval(timer); 30 timer=setInterval(function(){ 31 var iSpeed=(iTarget-oDiv.offsetLeft)/8; 32 33 //解决左右div向某一位置移动出现的距离达不到指定目标的距离(速度出现小数)问题 34 if(oDiv.offsetLeft>iTarget){ //当div在右,往左边移动时 35 iSpeed=Math.floor(iSpeed); //速度向下取整 36 } 37 else{ //反之 38 iSpeed=Math.ceil(iSpeed); //速度向上取整 39 } 40 41 if(oDiv.offsetLeft==iTarget){ 42 clearInterval(timer); 43 } 44 else{ 45 oDiv.style.left=oDiv.offsetLeft+iSpeed+'px'; 46 } 47 },30) 48 } 49 </script> 50 </head> 51 <body> 52 <input id="btn" type="button" value="click"> 53 <div id="div"></div> 54 <span style="width: 1px; height:200px; background:red; position:fixed;left:400px;"></span> 55 </body> 56 </html>
补充/回顾——js知识点:
(1)Math.ceil():该方法执行的是向上取整计算,它返回的是大于或等于函数参数,并且与之最接近的整数。【例如:2.3,向上取整后得:3】
(2)Math.floor():该方法执行的是向下取整计算,它返回的是小于或等于函数参数,并且与之最接近的整数。【例如:2.3,向下取整后得:2】
案例二:上下滑动的侧边栏的案例
显示效果如下:
代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #div{ 10 width: 100px; 11 height: 100px; 12 background: #ccc; 13 position: absolute; 14 right: 0; 15 top: 50%; 16 } 17 </style> 18 <script> 19 window.onscroll=function(){ 20 var oDiv=document.getElementById('div'); 21 var scrollTop=document.documentElement.scrollTop || document.body.scrollTop; 22 var clientHeight=document.documentElement.clientHeight; 23 //oDiv.style.top=scrollTop+(clientHeight-oDiv.offsetHeight)/2+'px'; 24 25 t=scrollTop+(clientHeight-oDiv.offsetHeight)/2; 26 //t表示:页面到div的高度距离。即:鼠标滑动高度+当前浏览器适应高度-div高度,再除2。 27 Move(t); 28 } 29 var timer=null; 30 function Move(iTarget){ 31 var oDiv=document.getElementById('div'); 32 clearInterval(timer); 33 timer=setInterval(function(){ 34 var iSpeed=(iTarget-oDiv.offsetTop)/8; 35 if(iTarget<oDiv.offsetTop){ //当目标高度距离<div上距离到浏览器的总高度 36 iSpeed=Math.ceil(iSpeed); //速度向上取整 37 } 38 else{ 39 iSpeed=Math.floor(iSpeed); //反之向下取整 40 } 41 if(iTarget==oDiv.offsetTop){ 42 clearInterval(timer); 43 } 44 else{ 45 oDiv.style.top=oDiv.offsetTop+iSpeed+'px'; 46 } 47 },30) 48 } 49 </script> 50 </head> 51 <body style="height: 2000px;"> 52 <div id="div"></div> 53 </body> 54 </html>
绘图讲解:(以上代码的第21-23行代码)
最后解决一个运动终止条件的问题
1》缓冲运动:两点重合【上面(二)缓冲运动中的案例一:div以缓冲运动进行移动的案例成功的解决了运动终止条件的问题】
2》匀速运动:距离足够近【看最后的代码演示】
【以往的写法是:(主要看第37行代码)】
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #div{ 10 width: 100px; 11 height: 100px; 12 background: #ccc; 13 position: absolute; 14 top: 50px; 15 left: 0; 16 } 17 </style> 18 <script> 19 window.onload=function(){ 20 var oBtn=document.getElementById('btn'); 21 oBtn.onclick=function(){ 22 Move(400); 23 } 24 } 25 var timer=null; 26 function Move(iTarget){ 27 var oDiv=document.getElementById('div'); 28 clearInterval(timer); 29 timer=setInterval(function(){ 30 var iSpeed=0; 31 if(oDiv.offsetLeft<iTarget){ 32 iSpeed=7; 33 } 34 else{ 35 iSpeed=-7; 36 } 37 if(oDiv.offsetLeft>=iTarget){ 38 clearInterval(timer); 39 } 40 else{ 41 oDiv.style.left=oDiv.offsetLeft+iSpeed+'px'; 42 } 43 },30) 44 } 45 </script> 46 </head> 47 <body> 48 <input id="btn" type="button" value="click"> 49 <div id="div"></div> 50 <span style="width: 1px; height:200px; background:red; position:fixed;left:400px;"></span> 51 </body> 52 </html>
显示效果如下图:
//以上,因为div移动的速度是7,不足以被目标距离(400)整除,所以div最终移动的距离会超过目标距离(400)。
//只有用下面这种方法才能解决该问题。
【 下面就来用js代码解决该问题(如下代码),(主要看第37行代码)】
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #div{ 10 width: 100px; 11 height: 100px; 12 background: #ccc; 13 position: absolute; 14 top: 50px; 15 left: 0; 16 } 17 </style> 18 <script> 19 window.onload=function(){ 20 var oBtn=document.getElementById('btn'); 21 oBtn.onclick=function(){ 22 Move(400); 23 } 24 } 25 var timer=null; 26 function Move(iTarget){ 27 var oDiv=document.getElementById('div'); 28 clearInterval(timer); 29 timer=setInterval(function(){ 30 var iSpeed=0; 31 if(oDiv.offsetLeft<iTarget){ 32 iSpeed=7; 33 } 34 else{ 35 iSpeed=-7; 36 } 37 if(Math.abs(oDiv.offsetLeft-iTarget)<7){ 38 //Math.abs():该方法相当于取绝对值 【例如:Math.abs(-5)=5】 39 40 //当div左边距到浏览器的长度-目标位置(400)<速度:7 41 //让div.style.left的值=目标位置(400)并 关闭定时器 42 clearInterval(timer); 43 oDiv.style.left=iTarget+'px'; 44 } 45 else{ 46 oDiv.style.left=oDiv.offsetLeft+iSpeed+'px'; 47 } 48 },30) 49 } 50 </script> 51 </head> 52 <body> 53 <input id="btn" type="button" value="click"> 54 <div id="div"></div> 55 <span style="width: 1px; height:200px; background:red; position:fixed;left:400px;"></span> 56 </body> 57 </html>