第八節 JS運動基礎
阿新 • • 發佈:2019-01-11
運動基礎
讓Div運動起來
速度——物體運動的快慢
運動中的Bug
不會停止
速度取某些值會無法停止
到達位置後再點選還會運動
重複點選速度加快
勻速運動(速度不變)
運動框架及應用:
運動框架:
在開始運動時,關閉已有定時器
把運動和停止隔開(if/else)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JS運動基礎</View Codetitle> <style> #div1{ width: 200px; height: 200px; background: yellow; position: absolute; top: 50px; left: 0px; } </style> <script> var timer=null; //用於儲存定時器 functionstartMove() { var oDiv=document.getElementById('div1'); clearInterval(timer); //不管之前有沒有定時器,都先關閉,然後下面開啟定時器,以保證每次點選該事件時只有一個定時器在工作, timer=setInterval(function () { var speed=7; //控制物體運動的快慢 //注意此時,速度為7,而距離300不能整除7,所以當到達294時直接跳過300,而直接到301,所以物體就不會停止,而是繼續向下運動,// if (oDiv.offsetLeft==300){ //當離左邊的距離為300畫素的時候,關掉定時器,使其停止運動 if (oDiv.offsetLeft>=300){ //解決不會停止的辦法,此時停在的301px的位置,但是問題又來了,如果再次點選按鈕, // 則物體會運動7畫素,再點選一下,有運動7畫素,一直點選,一直運動7的倍數個畫素 //這是因為,每次點選按鈕時,都會重新開一個定時器,所以每次點選就會運動一下,解決辦法如下else中語句 clearInterval(timer); //到達終點以後要做的事情 } else { oDiv.style.left=oDiv.offsetLeft+speed+'px'; //到達終點之前要做的事情 } // oDiv.style.left=oDiv.offsetLeft+speed+'px'; //offsetleft就是取div的位置; speed控制運動速度 }, 30); } </script> </head> <body> <input id="btn1" type="button" value="開始運動" onclick="startMove()"/> <div id="div1"></div> </body> </html>
運動框架例項:
例1:“分享到”側邊欄(通過目標點,計算速度值)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>側邊隱藏欄</title> <style> *{margin: 0px;padding: 0px;} #div1{ width: 150px; height: 150px; background: green; position: absolute; top: 100px; left: -150px; } #div1 span{ width: 20px; height: 60px; line-height: 20px; position: absolute; background: blue; right: -20px; top: 20px; } </style> <script> window.onload=function () { var oDiv=document.getElementById('div1'); // oDiv.onmouseover=function () { // InOut1(10, 0); //傳入引數speed, iTarget // }; // oDiv.onmouseout=function () { // InOut1(-10, -150); //傳入引數speed, iTarget // }; oDiv.onmouseover=function () { InOut2(0); //傳入引數iTarget }; oDiv.onmouseout=function () { InOut2(-150); //傳入引數iTarget }; }; var timer=null; // function Out() { // var oDiv=document.getElementById('div1'); // clearInterval(timer); // timer=setInterval(function () { // if (oDiv.offsetLeft == 0) { // clearInterval(timer); // } else { // oDiv.style.left=oDiv.offsetLeft+10+"px"; // } // }, 30); // } // // function In() { // var oDiv=document.getElementById('div1'); // clearInterval(timer); // timer=setInterval(function () { // if (oDiv.offsetLeft == -150) { // clearInterval(timer); // } else { // oDiv.style.left=oDiv.offsetLeft-10+"px"; // } // }, 30); // } //程式碼合併,把要發生變動的“量”定義為引數,呼叫時直接傳入 // function InOut1(speed, iTarget) { // var oDiv=document.getElementById('div1'); // clearInterval(timer); // timer=setInterval(function () { // if (oDiv.offsetLeft == iTarget) { // clearInterval(timer); // } else { // oDiv.style.left=oDiv.offsetLeft+speed+"px"; // } // }, 30); // } //程式碼簡化,儘量少傳入引數 function InOut2(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> <a>hhhhhh</a> </div> </body> </html>View Code
例2:淡入淡出的圖片(用變數儲存透明度)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>內容淡入淡出-透明度的變換</title> <style> #div1{ width: 200px; height: 200px; background: red; filter:alpha(opacity:30); /*IE透明度*/ opacity: 0.3; /*Chrome Firefox透明度*/ } </style> <script> window.onload = function () { var oDiv = document.getElementById('div1'); oDiv.onmouseover=function () { Fade_In_Out(100); //淡入 }; oDiv.onmouseout=function () { Fade_In_Out(30); //淡出 }; }; var alpha = 30; //因為沒有offsetAlpha該引數,所以我們改變透明度時,需要自定義變數 var timer = null; function Fade_In_Out(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+')'; //IE改變透明度,其中“:”可以換位“=” oDiv.style.opacity = alpha/100; //Chrome FireFox } }, 30); } </script> </head> <body> <div id="div1"> </div> </body> </html>View Code
緩衝運動
逐漸變慢,最後停止
距離越遠速度越大:速度由距離決定(距離越大,速度越快;距離越小,速度越慢),速度=(目標值-當前值)/縮放係數
例子:緩衝選單
Bug:速度調整(所以當用到緩衝運動時,切記一定要用到取整,否則會有誤)
// alert(Math.ceil(3.01)); //返回值為4,表示向上取整
// alert(Math.floor(3.999)); //返回值為3,表示向下取整
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>速度調整</title> <style> #div1{ width: 100px; height: 100px; background: red; position: absolute; left: 0px; /*向右運動*/ /*left: 600px; !*向左運動*!*/ top: 50px; } #div2{ width: 1px; height: 300px; position: absolute; background: black; left: 300px; top: 0px; } </style> <script> // alert(Math.ceil(3.01)); //返回值為4,表示向上取整 // alert(Math.floor(3.999)); //返回值為3,表示向下取整 function startMove() { var oDiv = document.getElementById('div1'); setInterval(function () { //不斷計算left的值,首先是(300-0)/15,之後是(300-x)/15,而x不斷增大,速度也就逐漸變慢 var speed = (300-oDiv.offsetLeft)/15; // speed = Math.ceil(speed); //當div1向有運動時,速度向上取整 // speed = Math.floor(speed); //當div1向左運動時,速度向下取整 speed = speed>0?Math.ceil(speed):Math.floor(speed); //上面兩句程式碼的合併 oDiv.style.left = oDiv.offsetLeft+speed+'px'; document.title = oDiv.offsetLeft+','+speed; //把主題title轉換為left和speed的值,方便觀察變化 }, 30); } </script> </head> <body> <button onclick="startMove()">開始運動</button> <div id="div1"></div> <div id="div2"></div> </body> </html>View Code
跟隨頁面滾動的緩衝側邊欄
潛在問題:目標值不是整數時;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>右側懸浮框</title> <style> body{height: 2000px; /*為了呈現出滾動條*/} #div1{ width: 100px; height: 150px; background: red; position: absolute; right: 0px; bottom: 318px; } </style> <script> //onscroll滾動 window.onscroll = function(){ var oDiv = document.getElementById('div1'); var scrollTop = document.documentElement.scrollTop||document.body.scrollTop; // oDiv.style.top = (document.documentElement.clientHeight-oDiv.offsetHeight+scrollTop)/2+'px'; //此時存在的問題是,在滑動滾動條的時候,div1的變化“有跳動”,跳一下才變換到正確位置,所以我們註釋掉,解決方法為: startMove(parseInt((document.documentElement.clientHeight-oDiv.offsetHeight)/2+scrollTop)); //(可視區的高-div的高)/2 表示把需要懸浮的框,懸浮在靠右中間的位置; // 其中parseInt() 表示避免“除以2”時出現0.5的畫素值(螢幕沒有半個畫素的情況),此時懸浮框會出現上下抖動的情況,而用parseInt()取整後就不會出現這種情況了。 }; var timer=null; function startMove(iTarget) { var oDiv = document.getElementById('div1'); clearInterval(timer); timer = setInterval(function(){ var speed = (iTarget-oDiv.offsetTop)/6; speed = speed>0?Math.ceil(speed):Math.floor(speed); //取整 if (oDiv.offsetTop==iTarget){ clearInterval(timer); } else { document.getElementById('txt1').value = oDiv.offsetTop; //調整懸浮框的位置,以便觀察 oDiv.style.top = oDiv.offsetTop+speed+'px'; } }, 30); } </script> </head> <body> <input type="txt1" id="txt1" style="position: fixed; right: 0px; top: 0px;"/> <div id="div1"></div> </body> </html>View Code
勻速運動的停止條件
運動終止條件:
勻速運動:距離足夠近
緩衝運動:兩點重合
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>勻速運動停止條件</title> <style> #div1{ width: 100px; height: 100px; background: red; position: absolute; left: 0px; /*向右運動*/ /*left: 600px; !*向左運動*!*/ top: 50px; } #div2{ width: 1px; height: 300px; position: absolute; background: black; left: 300px; top: 0px; } #div3{ width: 1px; height: 300px; position: absolute; background: black; left: 100px; top: 0px; } </style> <script> // alert(Math.abs(-6)); //返回值為6,abs()表示絕對值 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; } //問題出現,由於最終結果不為0,所以會因為有一定的偏差而相對抖動,我們所能夠解決的是在存在偏差的情況下,結束抖動,解決辦法如下: if (Math.abs(iTarget-oDiv.offsetLeft)<=7){ clearInterval(timer); //因為上面偏差是不能消除的,此時我們為了消除偏差,強行令left值等於目標值 oDiv.style.left = iTarget+'px'; //由於程式執行的速度較快,這種強行賦值使用肉眼是觀察不到的 } else { oDiv.style.left = oDiv.offsetLeft+speed+'px'; } }, 30); } </script> </head> <body> <button onclick="startMove(100)">到100px</button> <button onclick="startMove(300)">到300px</button> <div id="div1"></div> <div id="div2"></div> <div id="div3"></div> </body> </html>View Code