JavaScript的運動框架學習總結

一、目錄

  1. 入門案例——實現勻速運動

  2. 入門案例——實現緩衝運動

  3. 實現任意值的運動框架v.1

  4. 改進任意值的運動框架v.2  

  5. 改進任意值的運動框架v.3

  6. 實現鏈式運動框架

  7. 實現完美運動框架

二、內容

  1. 入門案例——實現勻速運動

  ①. 要求:只要簡單的實現傳入的對象和運動的最終目標,便能操作該對象的left屬性的大小勻速的變化到目標大小。

  ②. 具體代碼:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <style>
 7         #div1 {
 8             width: 100px;
 9             height: 100px;
10             background: red;
11             margin: 10px;
12             position:absolute;
13         }
14     </style>
15     <script>
16         var timer = null; //定時器
17         var speed = 10; //運動速度
18         function uniformMotion(obj,iTarget) {
19             if (obj.offsetLeft > iTarget) { //判斷當前left屬性的值與最終目標的值之間的位置
20                 speed = -10;                //說明當前對象的位置在目標值的右邊
21             } else {
22                 speed = 10;
23             }
24             clearInterval(timer);                   //先關閉之前的定時器
25             timer = setInterval(function () {       //開啓定時器,並保存返回的定時器對象
26                 if (obj.offsetLeft == iTarget) {
27                     clearInterval(timer);           //運動到目標後關閉定時器
28                 } else if (Math.abs(obj.offsetLeft - iTarget) < Math.abs(speed)) {
29                     obj.style.left = iTarget + 'px'; //如果當前位置與目標的位置不足10,那麼就讓它直接跳到目標位置上
30                     clearInterval(timer);            //關閉定時器
31                 } else {
32                     obj.style.left = obj.offsetLeft + speed + 'px'; //讓當前位置向目標位置移動
33                 }
34             }, 30);
35         }
36         window.onload = function () {
37             var btn = document.getElementsByTagName("input")[0];
38             var oDiv = document.getElementById("div1");
39             btn.onclick = function(){
40                 uniformMotion(oDiv,300);
41             }
42         }
43     </script>
44 </head>
45 <body>
46 <input type="button" value="勻速運動"/>
47 <div id="div1"></div>
48 </body>
49 </html>

   2. 入門案例——實現緩衝運動

    ①. 要求:只要簡單的實現傳入的對象和運動的最終目標,便能操作該對象的left屬性的大小由大到小的變化到目標大小。

    ②. 具體代碼:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6 
 7     <style>
 8         div {
 9             width: 100px;
10             height: 100px;
11             position: absolute;
12             background: red;
13             margin: 10px;
14             left: 100px;
15         }
16 
17         #div2{
18             width: 1px;
19             height:300px;
20             background-color: black;
21             position: absolute;
22             left:600px;
23         }
24     </style>
25     <script>
26         /*緩衝運動*/
27         var timer = null;
28         var speed = 0;
29         function UnUniformModition(obj,iTarget) {
30             clearInterval(timer);
31             timer = setInterval(function () {
32                 if (parseInt(getStyle(obj, "left")) == iTarget) {
33                     clearInterval(timer);
34                 } else {
35                     speed = (iTarget - parseInt(getStyle(obj, "left"))) / 10;
36                     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
37                     obj.style.left = parseInt(getStyle(obj, "left")) + speed + "px";
38                 }
39             }, 30);
40         }
41         /* 用來獲取樣式的值 obj-對象,name-樣式名*/
42         function getStyle(obj, name) {
43             if (obj.currentStyle) {
44                 return obj.currentStyle[name];
45             } else {
46                 return getComputedStyle(obj, false)[name];
47             }
48         }
49         window.onload = function () {
50             var btn = document.getElementsByTagName("input")[0];
51             var oDiv = document.getElementsByTagName("div")[0];
52             btn.onclick = function () {
53                 UnUniformModition(oDiv,600);
54             }
55         }
56     </script>
57 </head>
58 <body>
59 <input type="button" value="緩衝運動">
60 <div></div>
61 <div id="div2"></div>
62 </body>
63 </html>

   3. 實現任意值的運動框架v.1

    ①. 要求:只要簡單的實現傳入的對象、要變化的屬性名和運動的最終目標,便能操作該對象的傳入要變花屬性的值由大到小的變化到目標大小。(基於緩衝運動)

    ②. 具體代碼:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>任意值運動框架version 1.0</title>
  6     <style>
  7         div {
  8             width: 100px;
  9             height: 100px;
 10             background: green;
 11             margin: 10px;
 12         }
 13         #div2 {
 14             border: 1px solid black;
 15         }
 16         #div3{
 17             -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 18             filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 19             opacity: 0.3;
 20         }
 21     </style>
 22     <script>
 23         /**
 24          *
 25          * @param obj 操作對象
 26          * @param attr  屬性名
 27          * @param iTarget  目標值
 28          */
 29         var timer = null;
 30         function startMove(obj, attr, iTarget) {
 31             clearInterval(timer);
 32             timer = setInterval(function () {
 33                 var cur = 0;
 34                 if (attr == 'opacity') { //單獨處理透明度問題,因爲只有透明度一定要小數
 35                     cur = parseFloat(getStyle(obj, attr)) * 100;//乘以100是讓透明度的0~1之間的度數擴大,方便後面的使用
 36                 } else {
 37                     cur = parseInt(getStyle(obj, attr));
 38                 }
 39                 var speed = (iTarget - cur) / 6; //讓速度與當前位置離ITarget的距離成正比。除數越大那麼緩衝就越大
 40                 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
 41                 if (cur == iTarget) {
 42                     clearInterval(timer);
 43                 } else {
 44                     if (attr == 'opacity') {
 45                         obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
 46                         obj.style.opacity = (cur + speed) / 100;//把範圍重新縮小爲0~1之間
 47                     } else {
 48                         obj.style[attr] = cur + speed + 'px';
 49                     }
 50                 }
 51             }, 30);
 52         }
 53         /**
 54          * 獲取樣式屬性的值。代替offset。
 55          * @param obj   操作對象
 56          * @param name  屬性名
 57          * @returns {*}
 58          */
 59         function getStyle(obj, name) {
 60             if (obj.currentStyle) {
 61                 return obj.currentStyle[name];
 62             } else {
 63                 return getComputedStyle(obj, false)[name];
 64             }
 65         }
 66 
 67         /**
 68          * 測試:
 69          * 下面的例子只能一個一個進行測試,因爲在這裏沒有設置多對象動作,
 70          *  也就是說定時器此時是共有的,如果同時使用這個定時器,會出錯。
 71          */
 72         window.onload = function () {
 73             //測試width的變化(未設置border等其他影響width的屬性)
 74             var oDiv1 = document.getElementById("div1");
 75             oDiv1.onmouseover = function () {
 76                 startMove(this, "width", 500);
 77             }
 78             oDiv1.onmouseout = function () {
 79                 startMove(this, "width", 100);
 80             }
 81             //測試width的變化(設置了影響width值得元素)
 82             /*
 83             var oDiv2 = document.getElementById("div2");
 84             oDiv2.onmouseover = function () {
 85                 startMove(this, "width", 500);
 86             }
 87             oDiv2.onmouseout = function () {
 88                 startMove(this, "width", 100);
 89             }
 90             */
 91 
 92             //測試width的變化(設置了影響width值得元素)
 93             /*
 94             var oDiv3 = document.getElementById("div3");
 95             oDiv3.onmouseover = function () {
 96                 startMove(this, "opacity", 100);
 97             }
 98             oDiv3.onmouseout = function () {
 99                 startMove(this, "opacity", 30);
100             }
101             */
102         }
103     </script>
104 </head>
105 <body>
106 <div id="div1"></div>
107 <div id="div2"></div>
108 <div id="div3"></div>
109 </body>
110 </html>

    4. 改進任意值的運動框架v.2

    ①. 要求:在ie低版本測試下,透明度的值因爲是小數,會出現一些特殊的情況,所以對此進行改進。

    ②. 具體代碼:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <!-- 2.o版本對透明度的算法進行了改進,加進了round方法 具體內容在39行-->
  5     <meta charset="UTF-8">
  6     <title>任意值運動框架version 2.0</title>
  7     <style>
  8         div {
  9             width: 100px;
 10             height: 100px;
 11             background: green;
 12             margin: 10px;
 13         }
 14 
 15         #div2 {
 16             border: 1px solid black;
 17         }
 18         #div3{
 19             -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 20             filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 21             opacity: 0.3;
 22         }
 23     </style>
 24     <script>
 25         /**
 26          *
 27          * @param obj 操作對象
 28          * @param attr  屬性名
 29          * @param iTarget  目標值
 30          */
 31         var timer = null;
 32         function startMove(obj, attr, iTarget) {
 33             clearInterval(timer);
 34             timer = setInterval(function () {
 35                 var cur = 0;
 36                 if (attr == 'opacity') { //單獨處理透明度問題,因爲只有透明度一定要小數
 37                     //因爲parseFloat會得到一個帶小數的值,因爲計算機會有誤差,所以會得到一些奇怪的數值。
 38                     //因此在這裏使用round()方法對其值進行四捨五入,去除掉小數
 39                     cur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
 40                 } else {
 41                     cur = parseInt(getStyle(obj, attr));
 42                 }
 43                 var speed = (iTarget - cur) / 6; //讓速度與當前位置離ITarget的距離成正比。除數越大那麼緩衝就越大
 44                 //如果attr的值是0~1之間的話,下面這句代碼將不可用,如果是0~100之間的話,那麼就沒問題
 45                 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
 46                 if (cur == iTarget) {
 47                     clearInterval(timer);
 48                 } else {
 49                     if (attr == 'opacity') {
 50                         obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
 51                         obj.style.opacity = (cur + speed) / 100;//把範圍重新縮小爲0~1之間
 52                     } else {
 53                         obj.style[attr] = cur + speed + 'px';
 54                     }
 55                 }
 56             }, 30);
 57         }
 58         /**
 59          * 獲取樣式屬性的值。代替offset。
 60          * @param obj   操作對象
 61          * @param name  屬性名
 62          * @returns {*}
 63          */
 64         function getStyle(obj, name) {
 65             if (obj.currentStyle) {
 66                 return obj.currentStyle[name];
 67             } else {
 68                 return getComputedStyle(obj, false)[name];
 69             }
 70         }
 71 
 72         /**
 73          * 測試:
 74          * 下面的例子只能一個一個進行測試,因爲在這裏沒有設置多對象動作,
 75          *  也就是說定時器此時是共有的,如果同時使用這個定時器,會出錯。
 76          */
 77         window.onload = function () {
 78             //測試width的變化(未設置border等其他影響width的屬性)
 79             var oDiv1 = document.getElementById("div1");
 80             oDiv1.onmouseover = function () {
 81                 startMove(this, "width", 500);
 82             }
 83             oDiv1.onmouseout = function () {
 84                 startMove(this, "width", 100);
 85             }
 86             //測試width的變化(設置了影響width值得元素)
 87             /*
 88             var oDiv2 = document.getElementById("div2");
 89             oDiv2.onmouseover = function () {
 90                 startMove(this, "width", 500);
 91             }
 92             oDiv2.onmouseout = function () {
 93                 startMove(this, "width", 100);
 94             }
 95             */
 96 
 97             //測試width的變化(設置了影響width值得元素)
 98             /*
 99             var oDiv3 = document.getElementById("div3");
100             oDiv3.onmouseover = function () {
101                 startMove(this, "opacity", 100);
102             }
103             oDiv3.onmouseout = function () {
104                 startMove(this, "opacity", 30);
105             }
106             */
107         }
108     </script>
109 </head>
110 <body>
111 <div id="div1"></div>
112 <div id="div2"></div>
113 <div id="div3"></div>
114 </body>
115 </html>

 

    5. 改進任意值的運動框架v.3

    ①. 要求:在任意值的運動框架的1/2版本中,都沒有實現多物體運動,也就是同時多個物體進行運動,在第三版本中加入了多物體運動的功能。

    ②. 具體代碼:

    

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <!-- 3.o版本 支持多物體運動 下面的三個例子可以同時測試-->
  5     <meta charset="UTF-8">
  6     <title>任意值運動框架version 2.0</title>
  7     <style>
  8         div {
  9             width: 100px;
 10             height: 100px;
 11             background: green;
 12             margin: 10px;
 13         }
 14 
 15         #div2 {
 16             border: 1px solid black;
 17         }
 18         #div3{
 19             -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 20             filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
 21             opacity: 0.3;
 22         }
 23     </style>
 24     <script>
 25 
 26 
 27         /**
 28          *
 29          * @param obj 操作對象
 30          * @param attr  屬性名
 31          * @param iTarget  目標值
 32          */
 33         function startMove(obj, attr, iTarget) {
 34             clearInterval(obj.timer);
 35             obj.timer = setInterval(function () {
 36                 var cur = 0;
 37                 if (attr == 'opacity') { //單獨處理透明度問題,因爲只有透明度一定要小數
 38                     //因爲parseFloat會得到一個帶小數的值,因爲計算機會有誤差,所以會得到一些奇怪的數值。
 39                     //因此在這裏使用round()方法對其值進行四捨五入,去除掉小數
 40                     cur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
 41                 } else {
 42                     cur = parseInt(getStyle(obj, attr));
 43                 }
 44                 var speed = (iTarget - cur) / 6; //讓速度與當前位置離ITarget的距離成正比。除數越大那麼緩衝就越大
 45                 //如果attr的值是0~1之間的話,下面這句代碼將不可用,如果是0~100之間的話,那麼就沒問題
 46                 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
 47                 if (cur == iTarget) {
 48                     clearInterval(obj.timer);
 49                 } else {
 50                     if (attr == 'opacity') {
 51                         obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
 52                         obj.style.opacity = (cur + speed) / 100;//把範圍重新縮小爲0~1之間
 53                     } else {
 54                         obj.style[attr] = cur + speed + 'px';
 55                     }
 56                 }
 57             }, 30);
 58         }
 59 
 60 
 61         /**
 62          * 獲取樣式屬性的值。代替offset。
 63          * @param obj   操作對象
 64          * @param name  屬性名
 65          * @returns {*}
 66          */
 67         function getStyle(obj, name) {
 68             if (obj.currentStyle) {
 69                 return obj.currentStyle[name];
 70             } else {
 71                 return getComputedStyle(obj, false)[name];
 72             }
 73         }
 74 
 75         /**
 76          * 測試:
 77          * 下面的例子只能一個一個進行測試,因爲在這裏沒有設置多對象動作,
 78          *  也就是說定時器此時是共有的,如果同時使用這個定時器,會出錯。
 79          */
 80         window.onload = function () {
 81             //測試width的變化(未設置border等其他影響width的屬性)
 82             var oDiv1 = document.getElementById("div1");
 83             oDiv1.timer = null;
 84             oDiv1.onmouseover = function () {
 85                 startMove(this, "width", 500);
 86             }
 87             oDiv1.onmouseout = function () {
 88                 startMove(this, "width", 100);
 89             }
 90             //測試width的變化(設置了影響width值得元素)
 91             var oDiv2 = document.getElementById("div2");
 92             oDiv2.timer = null;
 93             oDiv2.onmouseover = function () {
 94                 startMove(this, "width", 500);
 95             }
 96             oDiv2.onmouseout = function () {
 97                 startMove(this, "width", 100);
 98             }
 99 
100             //測試opacity的變化
101             var oDiv3 = document.getElementById("div3");
102             oDiv3.timer = null;
103             oDiv3.onmouseover = function () {
104                 startMove(this, "opacity", 100);
105             }
106             oDiv3.onmouseout = function () {
107                 startMove(this, "opacity", 30);
108             }
109         }
110     </script>
111 </head>
112 <body>
113 <div id="div1"></div>
114 <div id="div2"></div>
115 <div id="div3"></div>
116 </body>
117 </html>

 

   6. 實現鏈式運動框架

    ①. 要求:讓其運動可以一個接一個的運行,也就是鏈式運動。具體效果看測試代碼

    ②. 具體代碼:

    html代碼部分:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <style>
 7         #div1{
 8             width:100px;
 9             height:100px;
10             background: green;
11         }
12 
13     </style>
14 
15     <script src="鏈式運動框架.js"></script>
16     <script>
17         window.onload=function(){
18             var oBtn = document.getElementsByTagName('input')[0];
19             var oDiv = document.getElementById('div1');
20             oBtn.onclick = function(){
21                 startMove(oDiv,'width',500,function(){
22                     startMove(oDiv,'height',500);
23                 });
24             }
25         }
26     </script>
27 </head>
28 <body>
29 <input type="button" value="運動">
30 
31 <div id="div1"></div>
32 </body>
33 </html>

 

鏈式運動框架.js代碼:

  

 1 /**
 2  * 獲取計算後的樣式
 3  * @param obj 對象
 4  * @param name 樣式名稱:width/height等
 5  * @returns {*}
 6  */
 7 function getStyle(obj, name) {
 8     if (obj.currentStyle) {
 9         return obj.currentStyle[name];
10     } else {
11         return getComputedStyle(obj, false)[name];
12     }
13 }
14 
15 function startMove(obj, attr, iTarget, fun) {
16     clearInterval(obj.timer);
17     obj.timer = setInterval(function () {
18         var cur;
19         if (attr == 'opacity') {
20             cur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
21         } else {
22             cur = parseInt(getStyle(obj, attr));
23         }
24         var speed = (iTarget - cur) / 6;
25         speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
26         if (cur == iTarget) {
27             clearInterval(obj.timer);
28             if (fun) {
29                 fun();
30             }
31         } else {
32             if (attr == 'opacity') {
33                 obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
34                 obj.style.opacity = (cur + speed) / 100;//把範圍重新縮小爲0~1之間
35             } else {
36                 obj.style[attr] = cur + speed + 'px';
37             }
38         }
39     }, 30);
40 }

 

   7. 實現完美運動框架

    ①. 要求:改進鏈式運動框架,鏈式框架沒辦法實現多個“屬性”同時運動!比如width、height同時變化。鏈式運動框架是沒法實現的,所以對此進行改進,也就是最終的運動框架!

    ②. 具體代碼:

    html代碼部分:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <style>
 7         #div1{
 8             width:100px;
 9             height:100px;
10             background: black;
11         }
12     </style>
13     <script src="完美運動框架.js"></script>
14     <script>
15         window.onload = function(){
16             var oBtn = document.getElementById('btn1');
17             var oDiv = document.getElementById('div1');
18             oBtn.onclick = function(){
19                 startMove(oDiv,{width:500,height:500},function(){
20                     startMove(oDiv,{width:100,height:100});
21                 });
22             }
23         }
24 
25     </script>
26 </head>
27 <body>
28 <input id="btn1" type="button" value="運動">
29 <div id="div1"></div>
30 </body>
31 </html>

 

    完美運動框架.js代碼部分:

 1 /**
 2  * 獲取對象的樣式
 3  * @param obj  對象
 4  * @param name 樣式名稱
 5  */
 6 function getStyle(obj, name) {
 7     if (obj.currentStyle) {
 8         return obj.currentStyle[name];
 9     } else {
10         return getComputedStyle(obj, false)[name];
11     }
12 }
13 /**
14  * 完美運動框架實現了鏈式運動框架無法實現多屬性同時運動的情況。如:width/height同時運動
15  * @param obj
16  * @param json 把要運動的屬性通過json方式傳入。如:{width:500,height:500}
17  * @param fun 執行完動作後,需要調用的方法
18  */
19 function startMove(obj, json, fun) {
20     clearTimeout(obj.timer);
21     obj.timer = setInterval(function () {
22         var stop = true; //用來判斷是否可以關閉定時器
23         for (var item in json) {
24             var cur;
25             if (item == 'opacity') {
26                 cur = Math.round(parseFloat(getStyle(obj, item)) * 100);
27             } else {
28                 cur = parseInt(getStyle(obj, item));
29             }
30             var speed = (json[item] - cur) / 6;
31             speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
32             if (cur != json[item]) {    //判斷當前對象的值是否已經達到目標值
33                 stop = false;           //未達到目標值時,讓stop爲false。
34             }
35             if (item == 'opacity') {
36                 obj.style.filter = 'alpha(opacity:' + (cur + speed) + ')';
37                 obj.style.opacity = (cur + speed) / 100;//把範圍重新縮小爲0~1之間
38             } else {
39                 obj.style[item] = cur + speed + 'px';
40             }
41             if(stop){
42                 clearInterval(obj.timer);
43                 if(fun){fun();} 
44             }
45         }
46     }, 30);
47 }

 

 

聲明:這些知識點都來自智能社的視頻所得~~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章