對于javascript運動的理解

運動原理:

對于javascript的運動簡單的來說就是利用定時器讓物體運動起來炒事,并不斷的改變物體的樣式。在運動中我們一般改變的是物體的定位而不是margin值吱七,因為改變margin值有時會影響其他元素容易造成頁面的混亂汽久。也許有的朋友會說難道不能使用for循環(huán)嗎?其實是可以的不過for循環(huán)太快了踊餐,通常你一打開網(wǎng)頁運動就完成了景醇,所以我們一般使用定時器來管理運動。

代碼示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script>
        window.onload=function(){
            var oT=document.getElementsByTagName('textarea')[0];
            var oBtn=document.getElementsByTagName('input')[0];
            var oTime=new Date().getTime();//開定時器前先獲取一個時間戳
            var timer=setInterval(function(){
            var oTime2=new Date().getTime();//根據(jù)定時器的間隔時間再獲取一個時間戳
                     oT.innerHTML+=oTime2-oTime+'\n';//在文本區(qū)域內(nèi)顯示時間差值
                     oTime=oTime2;//對初始時間戳重新賦值

            },1)
            oBtn.onclick=function(){   //暫停鍵
                clearInterval(timer);
            };
        };
    </script>
</head>
<body>   
    <textarea rows="" cols="" id="t1"></textarea>
    <input type="button" name="" value="btn">
</body>
</html>

希望各位小伙伴可以在編輯器試一下該段代碼吝岭。
在該段代碼中顯示出一個問題三痰,就是定時器的時間間隔并不是太穩(wěn)定

Paste_Image.png

(ps:你們也看到了飄得很是厲害。窜管。散劫。。)
??在javascript的定時器中選取間隔數(shù)字是有講究的幕帆,一般選擇的運動時間間隔為20-40ms之間,我們平均一下選取30ms获搏。一來人類視覺感受可以接受,時間間隔長會產(chǎn)生鈍感失乾,時間間隔太短的話會對性能的消耗也很大(碰到個辣眼睛的圖片會晃瞎哈哈哈)常熙。我們選取30ms如下圖:

Paste_Image.png

小伙伴們看到了吧,很穩(wěn)定吧碱茁。
??對于定時器在javascript中的運行順序也需要提一下裸卫,計算機在執(zhí)行代碼時會先執(zhí)行定時器下邊的代碼,到了時間才會執(zhí)行定時器里邊的纽竣。

代碼示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script>
        var n=1;
        setInterval(function(){
            n=2;
        },1);
        alert(n);
    </script>
</head>
<body>
    
</body>
</html>

該代碼顯示的結(jié)果為1墓贿。
??定時器還有一個問題就是當(dāng)你在瀏覽器中打開另外一個頁面時瀏覽器會默認的將你的原來有定時器的那個頁面的時間間隔降為1s以優(yōu)化性能茧泪。
代碼示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script>
        var n=0;
        setInterval(function(){
            n++;
            document.title=n;
        },1);
    </script>
</head>
<body>
</body>
</html>

接下來我們可以試一下物體的運動了。
代碼示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    *{margin: 0;
    padding: 0;
    list-style: none;}
    div{width: 100px;
    height: 100px;
    background: red;
    position: absolute;
    left: 0;}
    </style>
    <script>
        window.onload=function(){
            var oDiv=document.getElementsByTagName('div')[0];
            var time=1000;//總時間;
            var start=0;//開始
            var end=300;//結(jié)束
            var dis=end-start;//總位置
            var count=Math.ceil(time/30);//次數(shù)
            var n=0;//統(tǒng)計步數(shù)聋袋;
            var timer=null;
            timer=setInterval(function(){
                n++;
                oDiv.style.left=n*dis/count+'px';//n*一步距離队伟;
                oDiv.style.top=n*dis/count+'px';//n*一步距離;
                if(n==count){
                    clearInterval(timer);
                }
            },30);

        }
    </script>
</head>
<body>
    <div></div>
</body>
</html>

在以上代碼我們首先要設(shè)定好的就是總時間舱馅、開始位置缰泡、目標(biāo)位置刀荒、總路程代嗤、多長時間走一步(其實就是定時器設(shè)置的時間)、一共走多少步count(總時間除以設(shè)置時間: time/設(shè)置時間缠借。其中取整有幾種方式:parseInt\Math.floor()\Math.ceil()\Math.round() )干毅、一步走多遠:dis/count。
??在完成以上目標(biāo)后我們可以繼續(xù)加一些別的東西泼返,比如將以上的代碼進行封裝硝逢。
代碼示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
     <style>
    *{margin: 0;
    padding: 0;
    list-style: none;}
    div{width: 100px;
    height: 100px;
    background: red;
    position: absolute;
    left: 100px;
    top: 0;}
    </style>
    <script>
    function move(obj,end){
         var time=1000;//總時間;
            var start=obj.offsetLeft;//開始(在這里初試位置為left:100px)
            //注銷var end=300;//結(jié)束
            var dis=end-start;//總位置
            var count=Math.ceil(time/30);//次數(shù)
            var n=0;//統(tǒng)計步數(shù);
            var timer=null;

            timer=setInterval(function(){
                n++;
                obj.style.left=start+n*dis/count+'px';//n*一步距離绅喉;
                if(n==count){
                    clearInterval(timer);
                }
            },30);
    }
        window.onload=function(){
            var oDiv=document.getElementsByTagName('div')[0];

            move(oDiv,300);
        }
    </script>
</head>
<body>
    <div></div>
</body>
</html>

以上的代碼除了封裝以外渠鸽,還改變的物體運動的初始位置,各位小伙伴可以敲敲感受一下柴罐。此外我們還可以加上透明度徽缚。
代碼示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        
        div {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
            left: 100px;
            top: 0;
        }
    </style>
    <script>
        function getStyle(obj,sName){
            return (obj.currentStyle||getComputedStyle(obj,false))[sName]
        }
        function move(obj, sName,end) {
            var time = 1000; //總時間;
            var star = parseFloat(getStyle(obj,sName)); //這里用parseFloat取整
            //注銷var end=300;//結(jié)束
            var dis = end - star; //總位置
            var count = Math.ceil(time / 30); //次數(shù)
            var n = 0; //統(tǒng)計步數(shù);
            var timer = null;
            timer = setInterval(function () {
                n++;
                if(sName=='opacity'){
                obj.style[sName] = star + n * dis / count ;   
                                
                }else{

                obj.style[sName] = star + n * dis / count + 'px'; //n*一步距離革屠;
                }
                if (n == count) {
                    clearInterval(timer);
                }
            }, 30);
        }
        window.onload = function () {
            var oDiv = document.getElementsByTagName('div')[0];
            move(oDiv,'opacity', 0);
        }
    </script>
</head>

<body>
    <div></div>
</body>

</html>

此為單物體運動凿试,如果多物體還這樣的話就會出現(xiàn)錯誤。在定時器中還有一個問題就是*一定要保證一個物體上有只一個定時器(定時器加載到物體身上以達到互相獨立)似芝。
代碼示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }
         li{width: 100px;
        height: 50px;
        background:#6cf;
        margin-bottom: 10px;
        }
    </style>
    <script>
        
        function getStyle(obj,sName){
            return (obj.currentStyle||getComputedStyle(obj,false))[sName]
        }
        function move(obj, sName,end) {
            var time = 1000; //總時間;
            var start = parseFloat(getStyle(obj,sName)); //這里用parseFloat取整
            //注銷var end=300;//結(jié)束
            var dis = end - start; //總位置
            var count = Math.ceil(time / 30); //次數(shù)
            var n = 0; //統(tǒng)計步數(shù)那婉;
             clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                n++;
                if(sName=='opacity'){
                obj.style[sName] = start + n * dis / count ;   
                                
                }else{

                obj.style[sName] = start + n * dis / count + 'px'; //n*一步距離;
                }
                if (n == count) {
                    clearInterval(obj.timer);
                }
            }, 30);
        }
        window.onload = function () {
            var aLi = document.getElementsByTagName('li');
            for(var i=0;i<aLi.length;i++){
                  aLi[i].onmouseover=function(){
                move(this,'width',400);
            }
            aLi[i].onmouseout=function(){
                move(this,'width',100);
            }
            }
          
            
        }
    </script>
</head>

<body>
   <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</body>

</html>

千萬記住要清定時器党瓮。详炬。否則他會一直動哈哈。而且事件之間也會起沖突寞奸。
??大家肯定對于上邊那個關(guān)于透明度的問題有疑問呛谜,我除了設(shè)定透明度還要設(shè)置寬度怎么辦呢,原來的數(shù)據(jù)被透明度給占據(jù)了蝇闭。這里就由json出場了呻率。將相對應(yīng)的需要獲取的鍵值加入for in循環(huán)
代碼示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        
        div {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
            left: 100px;
            top: 0;
        }
    </style>
    <script>
        function getStyle(obj, sName) {
            return (obj.currentStyle || getComputedStyle(obj, false))[sName]
        }
        //function move(obj, sName,end) {原來的替換為下邊這個
        function move(obj, json) {
            var time = 1000; //總時間;
            var start = {} //{width:0;height:0;}開始位置{left:0,top:0}
            var dis = {} //{width:300;height:300;}總距離{left:300呻引,top:300}
            for (var name in json) {
                start[name] = parseFloat(getStyle(obj, name)); //
                dis[name] = json[name] - start[name];
                console.log(start);
                 console.log(dis)        
            }
            var count = Math.ceil(time / 30); //次數(shù)
            var n = 0; //統(tǒng)計步數(shù)礼仗;
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                n++;
                for (var name in json) {
                    if (name == 'opacity') {
                        obj.style[name] = start[name] + n * dis[name] / count;
                    } else {
                        obj.style[name] = start[name] + n * dis[name] / count + 'px'; //n*一步距離;
                    }
                }
                    if (n == count) {
                        clearInterval(obj.timer);
                    }

            }, 30);
        }
        window.onload = function () {
            var oDiv = document.getElementsByTagName('div')[0];
            document.onclick = function () {
                
                move(oDiv, {
                    'width': 300,
                    'height': 300,
                    'opacity': 0
                });
            };

        }
    </script>
</head>
<body>
    <div></div>
</body>
</html>

已經(jīng)為大家加入了console.log大家可以看一下start與end的json的鍵值對。
在此基礎(chǔ)上我們可以進一步升級元践,加入控制時間選項韭脊。
代碼示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        
        div {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
            left: 100px;
            top: 0;
        }
    </style>
    <script>
        function getStyle(obj, sName) {
            return (obj.currentStyle || getComputedStyle(obj, false))[sName]
        }
        //function move(obj, sName,end) {
        function move(obj, json,duration,complete) {
           var time=duration||1000;//前者條件滿足就不往后走了,或的條件
            var start = {} //{width:0;height:0;}開始位置{left:0单旁,top:0}
            var dis = {} //{width:300;height:300;}總距離{left:300沪羔,top:300}
            for (var name in json) {
                start[name] = parseFloat(getStyle(obj, name)); //
                dis[name] = json[name] - start[name];
                // console.log(start);
                // console.log(dis)        
            }
            var count = Math.ceil(time / 30); //次數(shù)
            var n = 0; //統(tǒng)計步數(shù);
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                n++;
                for (var name in json) {
                    if (name == 'opacity') {
                        obj.style[name] = start[name] + n * dis[name] / count;
                    } else {
                        obj.style[name] = start[name] + n * dis[name] / count + 'px'; //n*一步距離象浑;
                    }   
                }
                if (n == count) {
                    clearInterval(obj.timer);
                    complete && complete();//如果有就執(zhí)行如果沒有就不執(zhí)行蔫饰,防止了無函數(shù)出現(xiàn)undefine。
                }
            }, 30);
        }
        window.onload = function () {
            var oDiv = document.getElementsByTagName('div')[0];
            document.onclick = function () {
                move(oDiv, {
                    'width': 300,
                    'height': 300,
                    'opacity': 0
                },3000,function(){
                     alert(1);
                });
            };
        }
    </script>
</head>
<body>
    <div></div>
</body>
</html>

我們將控制時間與完成時執(zhí)行事件封裝愉豺。
示例代碼:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        
        div {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
            left: 100px;
            top: 0;
        }
    </style>
    <script>
        function getStyle(obj, sName) {
            return (obj.currentStyle || getComputedStyle(obj, false))[sName]
        }
        //function move(obj, sName,end) {
        function move(obj, json,options) {
           //var time = 1000; //總時間;
           var options=options||{};
           var time=options.duration||1000;//前者條件滿足就不往后走了篓吁,或的條件
            var start = {} //{width:0;height:0;}開始位置{left:0,top:0}
            var dis = {} //{width:300;height:300;}總距離{left:300蚪拦,top:300}
            for (var name in json) {
                start[name] = parseFloat(getStyle(obj, name)); //
                dis[name] = json[name] - start[name];
                // console.log(start);
                // console.log(dis)        
            }
            var count = Math.ceil(time / 30); //次數(shù)
            var n = 0; //統(tǒng)計步數(shù)杖剪;
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                n++;
                for (var name in json) {
                    if (name == 'opacity') {
                        obj.style[name] = start[name] + n * dis[name] / count;
                    } else {
                        obj.style[name] = start[name] + n * dis[name] / count + 'px'; //n*一步距離;
                    }          
                }
                if (n == count) {
                    clearInterval(obj.timer);
                    options.complete && options.complete();//如果有就執(zhí)行如果沒有就不執(zhí)行驰贷,防止了無函數(shù)出現(xiàn)undefine盛嘿。
                }

            }, 30);
        }
        window.onload = function () {
            var oDiv = document.getElementsByTagName('div')[0];
            document.onclick = function () {
                move(oDiv, {
                    "width": 300,
                    "height": 300,
                    "opacity": 0
                },{"duration":3000,"complete":function(){
                    alert(1);
                }});
            };

        }
    </script>
</head>
<body>
    <div></div>
</body>
</html>

到這里對于運動方面就告一段落了,在工作中我們都會使用已經(jīng)封裝好的框架來用括袒,以上內(nèi)容就是為了更好的理解javascript運動的邏輯問題次兆。

本人前端小白,希望在自己努力的同時可以認識更多志同道合的朋友箱熬,也希望大神和老師傅們能夠提攜一二帶我上車类垦,本人不勝感激。哈哈城须,希望小伙伴們能夠給出意見蚤认,讓我能夠加以改正,謝謝糕伐!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末砰琢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子良瞧,更是在濱河造成了極大的恐慌陪汽,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件褥蚯,死亡現(xiàn)場離奇詭異挚冤,居然都是意外死亡,警方通過查閱死者的電腦和手機赞庶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門训挡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澳骤,“玉大人,你說我怎么就攤上這事澜薄∥梗” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵肤京,是天一觀的道長颊艳。 經(jīng)常有香客問我,道長忘分,這世上最難降的妖魔是什么棋枕? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮饭庞,結(jié)果婚禮上戒悠,老公的妹妹穿的比我還像新娘。我一直安慰自己舟山,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布卤恳。 她就那樣靜靜地躺著累盗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪突琳。 梳的紋絲不亂的頭發(fā)上若债,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音拆融,去河邊找鬼蠢琳。 笑死,一個胖子當(dāng)著我的面吹牛镜豹,可吹牛的內(nèi)容都是我干的傲须。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼趟脂,長吁一口氣:“原來是場噩夢啊……” “哼泰讽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昔期,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤已卸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后硼一,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體累澡,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年般贼,在試婚紗的時候發(fā)現(xiàn)自己被綠了愧哟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惑申。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖翅雏,靈堂內(nèi)的尸體忽然破棺而出圈驼,到底是詐尸還是另有隱情,我是刑警寧澤望几,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布绩脆,位于F島的核電站,受9級特大地震影響橄抹,放射性物質(zhì)發(fā)生泄漏靴迫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一楼誓、第九天 我趴在偏房一處隱蔽的房頂上張望玉锌。 院中可真熱鬧,春花似錦疟羹、人聲如沸主守。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽参淫。三九已至,卻和暖如春愧杯,著一層夾襖步出監(jiān)牢的瞬間涎才,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工力九, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留耍铜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓跌前,卻偏偏與公主長得像棕兼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子舒萎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫程储、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,119評論 4 61
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協(xié)議臂寝。它實...
    香橙柚子閱讀 23,902評論 8 183
  • 19世紀法國生活的最好寫照 之前并未接觸過太多莫泊桑的小說章鲤,只知他善于諷刺和批判,讀完長篇小說漂亮朋友后咆贬,對其寫作...
    會子閱讀 1,606評論 9 10
  • 早上七點半去了趟廁所败徊,回來接著躺在床上,冥想掏缎。今天剛好周六皱蹦,有理由賴床煤杀。 正當(dāng)漸入佳境時,窗臺外噼里啪啦的開始下起...
    靈君閱讀 193評論 0 0