JavaScript學習總結【11】、JS運動

来源:http://www.cnblogs.com/Mtime/archive/2016/01/19/5130927.html
-Advertisement-
Play Games

動畫效果在網站中是一種非常常見的互動式體驗效果,比如側邊欄分享、圖片淡入淡出,我們把這種動畫效果就叫做運動,也就是讓物體動起來。如果想讓一個物體動起來,無非就是改變它的速度,也就是改變屬性值,比如 left、right、width、height、opacity ,那麼既然是運動,就可以分為很多種.....


  動畫效果在網站中是一種非常常見的互動式體驗效果,比如側邊欄分享、圖片淡入淡出,我們把這種動畫效果就叫做運動,也就是讓物體動起來。如果想讓一個物體動起來,無非就是改變它的速度,也就是改變屬性值,比如 left、right、width、height、opacity ,那麼既然是運動,就可以分為很多種,如勻速運動、緩衝運動、多物體運動、任意值運動、鏈式運動和同時運動。我們從最簡單的動畫開始,如何讓單個物體運動,逐步深入多物體運動、多動畫同時運動到實現完美運動框架的封裝,在這個過程中,每一個運動都封裝為一個函數,可以更好的培養和鍛煉我們的編程思想,增強邏輯思維。

  1、簡單運動

  簡單運動的實現都是勻速運動,顧名思義就是運動速度不變,通過寬、高、透明度等的變化,實現簡單的動畫效果,下麵我們就讓一個 div 運動起來。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>簡單運動</title>
 6 <style>
 7 *{margin:0;padding:0;}
 8 #div1{
 9     width:200px;
10     height:200px;
11     background:green;
12     position:absolute;
13 }
14 </style>
15 <script>
16 function startMove(){
17     var oDiv = document.getElementById('div1');
18     setInterval(function (){
19         oDiv.style.left = oDiv.offsetLeft + 10 + 'px';
20     },30);
21 }
22 </script>
23 </head>
24 <body>
25 <input type="button" value="動起來" onclick="startMove()">
26 <div id="div1"></div>
27 </body>
28 </html>

  讓一個 div 動起來,只需要開一個定時器,用於定義速度,告訴物體運動的快慢,上面的代碼,當點擊按鈕後,div 每隔30毫秒從左向右運動10像素。

  這裡需要註意,讓 div 向右運動,在定義樣式時,一定要給運動的物體加絕對定位,也就是相對於哪個位置進行運動,offsetLeft 代表物體的當前位置,所以每次運動,都是給當前的 offsetLeft 加10像素。

  雖然是讓 div 動起來了,但是問題多多,動起來後根本停不下來,這樣就太任性了,而且當重覆點擊的話,運動速度還會加快,這都不是我們想要的,下麵就我們就讓他停止在指定位置處。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>簡單運動</title>
 6 <style>
 7 *{margin:0;padding:0;}
 8 #div1{
 9     width:200px;
10     height:200px;
11     background:green;
12     position:absolute;
13 }
14 </style>
15 <script>
16 var timer = null;
17 function startMove(){
18     var oDiv = document.getElementById('div1');
19     clearInterval(timer);
20     timer = setInterval(function (){
21         if(oDiv.offsetLeft == 300){
22             clearInterval(timer);
23         }
24         else{
25             oDiv.style.left = oDiv.offsetLeft + 10 + 'px';
26         }
27     },30);
28 }
29 </script>
30 </head>
31 <body>
32 <input type="button" value="動起來" onclick="startMove()">
33 <div id="div1"></div>
34 </body>
35 </html>

  上面的代碼,點擊按鈕後,div 從左向右運動到300像素時停止運動。

  若要停止一個物體的運動,只要關閉定時器即可,也就是判斷 div 的 offsetLeft 值是否等於300,若等於300則清空定時器。這裡需要註意,在做判斷時,一定要給運動位置加 else,判斷語句為二選一,成立或者不成立時執行,這樣再點擊按鈕就不會運動了,否則當 div 運動到300像素時,再點擊按鈕,div 還會向右移動10像素,雖然在到達300像素時已經關閉了定時器,但是按鈕的點擊事件,還會執行一次函數,所以加了 else 之後,當再點擊按鈕時,這時候條件已經成立了,也就不會再執行 else 中的語句了。

  重覆點擊按鈕,運動速度會不斷加快,是因為每點擊一次按鈕,startMove 函數被執行一次,多次點擊,也就相當於開了多個定時器,所以需要在執行 startMove 函數時,首先清空定時器,這樣重覆點擊按鈕時,會先把之前運行的定時器關閉,再開一個新的定時器運行,這就保證了始終是一個定時器在工作。

  下麵我們看兩個簡單動畫的實例:

  實例:側邊欄分享

  實現思路:網站側邊欄菜單是最常見的動畫效果,該效果在初始時,只顯示一個按鈕或者菜單項,當滑鼠移上去時,滑出隱藏部分,展示內容。該效果在做佈局時,主要用絕對定位實現隱藏,left 的值為內容容器 width 的值,該值為負值,動畫效果實現就是改變它的 offsetLeft 的值,當滑鼠移入時,增加 offsetLeft 的值,值為0時停止運動,當滑鼠移開時,offsetLeft 的值從0減小到 left 的值。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>側邊欄分享</title>
 6 <style>
 7 *{margin:0;padding:0;}
 8 #div1{
 9     width:150px;
10     height:210px;
11     background:lightgreen;
12     position:absolute;
13     left:-150px;
14 }
15 #div1 span{
16     width:20px;
17     height:60px;
18     line-height:20px;
19     color:white;
20     background:green;
21     position:absolute;
22     right:-20px;
23     top:70px;
24 }
25 </style>
26 <script>
27 window.onload = function (){
28     var oDiv = document.getElementById('div1');
29     oDiv.onmouseover = function (){
30         startMove();
31     };
32     oDiv.onmouseout = function (){
33         stopMove();
34     };
35 };
36 var timer = null;
37 function startMove(){
38     var oDiv = document.getElementById('div1');
39     clearInterval(timer);
40     timer = setInterval(function (){
41         if(oDiv.offsetLeft == 0){
42             clearInterval(timer);
43         }
44         else{
45             oDiv.style.left = oDiv.offsetLeft + 10 + 'px';
46         }
47     },30);
48 }
49 function stopMove(){
50     var oDiv = document.getElementById('div1');
51     clearInterval(timer);
52     timer = setInterval(function (){
53         if(oDiv.offsetLeft == -150){
54             clearInterval(timer);
55         }
56         else{
57             oDiv.style.left = oDiv.offsetLeft - 10+ 'px';
58         }
59     },30);
60 }
61 </script>
62 </head>
63 <body>
64 <div id="div1">
65     <span>分享到</span>
66 </div>
67 </body>
68 </html>

  上面的代碼,當滑鼠移入"分享到",隱藏的 div 即內容容器每隔30毫秒從左向右運動10像素,offsetLeft 值為0時停止運動,當滑鼠移開時,顯示的 div 每隔30毫秒從右向左移動5像素,offsetLeft 值為-150時停止運動。這裡要註意的是,offsetLeft 值的變化,從左向右運動時,值為正值,也就是+10,從右向左運動時,值為負值,也就是-10。

  我們可以看到,startMove 和 stopMove 都有相同的代碼結構,如果代碼中存在大致相同的代碼,就可以對代碼進行優化,上面的代碼,就只有 offsetLeft 的移動位置 和 停止位置不同,因此可以用函數傳參的方式將上面的代碼簡化為:

 1 <script>
 2 window.onload = function (){
 3     var oDiv = document.getElementById('div1');
 4     oDiv.onmouseover = function (){
 5         startMove(10, 0);
 6     };
 7     oDiv.onmouseout = function (){
 8         startMove(-10, -150);
 9     };
10 };
11 var timer = null;
12 function startMove(speed, iTarget){
13     var oDiv = document.getElementById('div1');
14     clearInterval(timer);
15     timer = setInterval(function (){
16         if(oDiv.offsetLeft === iTarget){
17             clearInterval(timer);
18         }
19         else{
20             oDiv.style.left = oDiv.offsetLeft + speed + 'px';
21         }
22     },30);
23 }
24 </script>

  移動位置也就是速度,用 speed 參數傳入,停止位置也就是目標位置,用 iTarget 參數傳入。在功能相同的情況下,一個函數傳入的參數越少越好,那麼還可以簡化為:

 1 <script>
 2 window.onload = function (){
 3     var oDiv = document.getElementById('div1');
 4     oDiv.onmouseover = function (){
 5         startMove(0);
 6     };
 7     oDiv.onmouseout = function (){
 8         startMove(-150);
 9     };
10 };
11 var timer = null;
12 function startMove(iTarget){
13     var oDiv = document.getElementById('div1');
14     clearInterval(timer);
15     timer = setInterval(function (){
16         var speed = 0;
17         if(oDiv.offsetLeft > iTarget){
18             speed = -10;
19         }
20         else{
21             speed = 10;
22         }
23         if(oDiv.offsetLeft == iTarget){
24             clearInterval(timer);
25         }
26         else{
27             oDiv.style.left = oDiv.offsetLeft + speed + 'px';
28         }
29     },30);
30 }
31 </script>

  速度值和目標值,目標值肯定是不能省略的,就好比坐火車,買票肯定得有一個終點,所以速度值可以被省略掉,不管是動車還是普通車,都會到達終點,不同的就是速度的快慢。首先讓速度值等於0,再做一個判斷,判斷目標值與物體當前位置的關係,如果 offsetLeft 值大於目標值,那麼就要從右向左運動,所以為負值,否則,也就是目標值大於 offsetLeft 值,這說明此時物體是隱藏的,那麼就從左向右運動,速度值為正值。

  該效果如果用緩衝運動做的話,效果更好。

  實例:淡入淡出

  淡入淡出效果是滑鼠移入移出改變透明度,透明度動畫也屬於運動效果,可以使用上例中 startMove 框架完成這種效果。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>淡入淡出</title>
 6 <style>
 7 #div1{
 8     width:200px;
 9     height:200px;
10     background:red;
11     filter:alpha(opacity:30);
12     opacity:0.3;
13 }
14 </style>
15 <script>
16 window.onload = function (){
17     var oDiv = document.getElementById('div1');
18     oDiv.onmouseover = function (){
19         startMove(100);
20     };
21     oDiv.onmouseout = function (){
22         startMove(30);
23     };
24 };
25 var alpha = 30;    //將透明度值存儲在變數中
26 var timer = null;
27 function startMove(iTarget){
28     var oDiv = document.getElementById('div1');
29     clearInterval(timer);
30     timer = setInterval(	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 寫了這麼久的CSS,但大部分前端er都沒有按照良好的CSS書寫規範來寫CSS代碼,這樣會影響代碼的閱讀體驗,這裡總結一個CSS書寫規範、CSS書寫順序供大家參考,這些是參考了國外一些文章以及我的個人經驗總結出來,我想對寫CSS的前端用戶來說是值得學習的。 CSS書寫順序 1.位置屬性(positi....
  • 在這時碰到了一個圓角邊框的問題,以前的代碼是在每個頁面寫一個固定結構的div,使用背景圖片來實現圓角邊框。代碼結構大致如下:.top_border{background:url(topborder.png);}.left_border{background:url(leftborder.png);}...
  • 好吧,因為很重要的事情,幾天沒寫筆記了。關於對象:||可以用來填充預設值,如:myApp.name || "無"&&可以用來避免錯誤,myApp.NameObj有某種情況不存在,那麼可以用myApp.NameObj &&myApp.NameObj.Name避免腳本錯誤所有通過對象字面量創建的對象都連...
  • 我們知道,MongoDB屬於文檔型資料庫,其存儲的文檔類型都是JSON對象。正是由於這一特性,我們在Node.js中會經常使用MongoDB進行數據的存取。但由於Node.js是非同步執行的,這就導致我們無法保證每一次的資料庫save操作都是原子型的。也就是說,如果客戶端連續兩次發起同一事件將數據.....
  • 前些天在寫一個項目的時候,使用cookie來存儲一些用戶數據,在用戶登出時需要清理以往的數據,對於一個初學者來說,我需要學習如何清除一個已知的cookie。首先,引入兩個js文件: 1.jquery-1.12.0.min.js這是編輯這篇文章時最新的jQuery; 2.carhartl-jque.....
  • javascript基本概念重要知識點總結。
  • 想通過JQuery來check或者uncheck頁面上的checkbox控制項,我們可能會想到用下麵的代碼:$('#chk-all').on('click', function(){ var checked = $(this).is(':checked'); $("input[type...
  • 在網頁佈局中,經常用到高度自適應增長的佈局。如左側是文章內容部分,隨著文章內容的變化,高度也不固定,右側則是一些固定高度的相關內容。如圖所示: 簡單摸索後發現CSS中有一個min-height的屬性,如果設置min-height為200px,當高度大於200px時,則自動開始增長;小於20...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...