你們好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新......javascript
- github:https://github.com/Daotin/Web
- 微信公衆號:Web前端之巔
- 博客園:http://www.cnblogs.com/lvonve/
- CSDN:https://blog.csdn.net/lvonve/
在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的項目。如今就讓咱們一塊兒進入 Web 前端學習的冒險之旅吧!css
BOM 中有兩中方式設置定時器。html
特色:定時器能夠重複使用。前端
// 參數有兩個: // 第一個參數:定時器定時結束處理函數 // 第二個參數:定時事件,單位毫秒。 // 返回值:定時器id值 var timeId = window.setInterval(function() { // ... }, 1000); // 定時1s // 清除定時器 // 參數只有一個:定時器的 id 值。 window.clearInterval(timeId);
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> div { position: absolute; } </style> </head> <body> <input type="button" value="搖起來" id="btn1"> <input type="button" value="中止" id="btn2"> <div id="dv"> <img src="images/Daotin.png" alt=""> </div> <script src="common.js"></script> <script> var timeId = 0; my$("btn1").onclick = function () { timeId = setInterval(function () { //讓圖片動起來可使div動起來 var x = parseInt(Math.random() * 100) + 1; // 1-100隨機數 var y = parseInt(Math.random() * 100) + 1; my$("dv").style.left = x + "px"; my$("dv").style.top = y + "px"; }, 100); }; my$("btn2").onclick = function () { clearInterval(timeId); }; </script> </body> </html>
點擊」搖起來「按鈕,圖片每隔 100ms 動一次,點擊中止按鈕,圖片中止移動。java
遺留問題:git
屢次點擊「搖起來」按鈕的時候,圖片動的愈來愈快,並且點擊「中止」按鈕無法停下來。github
緣由分析:微信
屢次點擊「搖起來」按鈕的時候,timeId 的值會有多個,而中止的時候,只會清理最後一個值,其餘的值對應的定時器沒有清理。app
解決方法:dom
在每次點擊按鈕的時候,先進行一次定時器的清理動做。clearInterval(timeId);
特色:定時器是一次性的。
setTimeout(); // 參數與返回值同 setInterval();
這個定時器只執行一次。雖然只執行一次,可是仍是要清零,否則就一直佔內存。
clearTimeOut(); // 參數爲 setTimeout() 定時器的 id。
<body> <input type="button" value="請認真閱讀協議(5)" id="btn" disabled> <script src="common.js"></script> <script> var time = 5; var timeId = setInterval(function () { time--; if (time >= 0) { my$("btn").value = "請認真閱讀協議(" + time + ")"; } else { clearInterval(timeId); my$("btn").value = "贊成"; my$("btn").disabled = false; } }, 1000); </script> </body>
倒計時後才能夠點擊贊成按鈕。
目標:有兩個按鈕,點擊第一個按鈕,div 緩慢移動到 400px 位置,點擊第二個按鈕緩慢移動到 800px 位置,再點擊第一個按鈕緩慢移動到 400px 位置......
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } input { margin-top: 10px; } div { position: absolute; width: 200px; height: 100px; background-color: yellowgreen; margin-top: 10px; /*left: 20px;*/ } </style> </head> <body> <input type="button" value="移動400px" id="btn1"> <input type="button" value="移動800px" id="btn2"> <div id="dv"></div> <script src="common.js"></script> <script> // 移動400px my$("btn1").onclick = function () { animation(my$("dv"), 400); }; // 移動800px my$("btn2").onclick = function () { animation(my$("dv"), 800); }; // 封裝動畫移動函數 function animation(element, target) { // 判斷當前的位置 var current = element.offsetLeft; // 不能使用 element.style.left var onestep = 7; var timeId = setInterval(function () { current += current < target ? onestep : -onestep; if (Math.abs(current - target) >= onestep) { element.style.left = current + "px"; } else { clearInterval(timeId); element.style.left = target + "px"; } }, 20); } </script> </body> </html>
一、既然要緩慢移動,就須要定時器。
二、當前位置的獲取不能使用 element.style.left; 而須要使用 element.offsetLeft; 由於全部寫在標籤中的 style 屬性值都拿不到,只有內聯的 style 屬性值可使用 element.style.left 拿到。而 element.offsetLeft 則兩種方式均可以拿到。
三、須要每次移動的步數 onestep,並且有回退的須要,因此 onestep 多是負數。
四、每次移動後判斷如今的位置到目標位置的距離,若是大於 onestep,那麼就移動 當前 current 加減 onestep 的位置,不然就移動到目標位置,這樣作的目的是避免 onestep 的不肯定,致使最後的終點與目標還差少量的距離。
五、使用當前與目標距離的絕對值來決定是前進仍是後退。
六、到達目標位置後,關閉定時器。
七、將動畫過程封裝成一個函數,參數爲移動的目標和移動的距離。
八、注意:div 須要脫離文檔流。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } #box { width: 400px; height: 250px; margin: 200px 0 0 400px; position: relative; border: 2px solid #31608a; overflow: hidden; } ul { width: 1300px; position: absolute; } li { list-style-type: none; float: left; } img { width: 400px; height: 250px; } li a { display: inline-block; } .sp { position: absolute; left: 50%; margin-left: -45px; bottom: 10px; } span { float: left; width: 20px; height: 20px; background-color: #fff; border-radius: 10px; text-align: center; font: 400 16px/20px Consolas; margin: 0 5px 0 5px; cursor: pointer; } .current { background-color: red; color: #fff; } </style> </head> <body> <div id="box"> <ul> <li><a href="#"><img src="images/img1.jpg" alt=""></a></li> <li><a href="#"><img src="images/img2.jpg" alt=""></a></li> <li><a href="#"><img src="images/img3.jpg" alt=""></a></li> </ul> <div class="sp"> <span class="current">1</span> <span>2</span> <span>3</span> </div> </div> <script src="common.js"></script> <script> // 獲取box元素 var boxObj = my$("box"); // 獲取ul元素,由於移動的就是整個ul var ulObj = boxObj.children[0]; // 移動寬度 var moveWidth = document.getElementsByTagName("img")[0].offsetWidth; // 獲取全部span標籤 var spanObjs = boxObj.children[1].getElementsByTagName("span"); // console.log(spanObjs); for (var i = 0; i < spanObjs.length; i++) { // 獲取每一個span的編號,設置自定義屬性 spanObjs[i].setAttribute("index", "" + i); spanObjs[i].onmouseover = function () { for (var j = 0; j < spanObjs.length; j++) { // 清空span背景 spanObjs[j].removeAttribute("class"); } // 設置當前span標籤 this.className = "current"; // 每一個編號*移動的寬度就是移動到的目標位置 var index = this.getAttribute("index"); animation(ulObj, -index*moveWidth); }; } // 封裝動畫移動函數 function animation(element, target) { // 判斷當前的位置 var current = element.offsetLeft; var onestep = 7; var timeId = setInterval(function () { current += current < target ? onestep : -onestep; if (Math.abs(current - target) >= onestep) { element.style.left = current + "px"; } else { clearInterval(timeId); element.style.left = target + "px"; } }, 10); } </script> </body> </html>
一、移動的時候移動的是 ul,而不是單獨的 li 或者 img。
二、span 小標籤在鼠標進入的時候,背景變成紅色。(排他事件:須要兩步,第一清理全部,第二當前元素設置屬性)
三、爲每一個 span 綁定事件時,程序開始,for 循環就運行完了,得不到每一個span 標籤的編號,因此要自定義屬性保存每一個 span 標籤的編號。
四、直接調用封裝好的動畫移動函數來移動 ul 標籤。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } #box { width: 400px; height: 250px; margin: 200px 0 0 400px; position: relative; border: 2px solid #31608a; overflow: hidden; } ul { width: 1300px; position: absolute; } li { list-style-type: none; float: left; } img { width: 400px; height: 250px; } .sp { width: 400px; height: 50px; position: absolute; top: 100px; display: none; } #left { width: 50px; height: 50px; float: left; cursor:pointer; text-align:center; font: 400 28px/50px Consolas; background-color: #fff; opacity: 0.4; /* 透明度 */ } #right { float: right; width: 50px; height: 50px; cursor:pointer; text-align:center; font: 400 28px/50px Consolas; background-color: #fff; opacity: 0.4; } </style> </head> <body> <div id="box"> <ul> <li><a href="#"><img src="images/img1.jpg" alt=""></a></li> <li><a href="#"><img src="images/img2.jpg" alt=""></a></li> <li><a href="#"><img src="images/img3.jpg" alt=""></a></li> </ul> <div class="sp"> <span id="left"><</span> <span id="right">></span> </div> </div> <script src="common.js"></script> <script> // 獲取box元素 var boxObj = my$("box"); // 獲取ul元素,由於移動的就是整個ul var ulObj = boxObj.children[0]; // 移動寬度 var moveWidth = document.getElementsByTagName("img")[0].offsetWidth; // 獲取sp標籤 var spObj =boxObj.children[1]; // 獲取span左標籤 var leftObj = my$("left"); // 獲取span右標籤 var rightObj = my$("right"); var index = 0; boxObj.onmouseover = function () { spObj.style.display = "block"; }; boxObj.onmouseout = function () { spObj.style.display = "none"; }; // 左移 leftObj.onclick = function () { if(index) { index--; animation(ulObj, -index*moveWidth); } }; // 右移 rightObj.onclick = function () { if(index<ulObj.children.length-1) { index++; animation(ulObj, -index*moveWidth); } }; // 封裝動畫移動函數 function animation(element, target) { // 判斷當前的位置 var current = element.offsetLeft; var onestep = 17; var timeId = setInterval(function () { current += current < target ? onestep : -onestep; if (Math.abs(current - target) >= onestep) { element.style.left = current + "px"; } else { clearInterval(timeId); element.style.left = target + "px"; } }, 10); } </script> </body> </html>
需求:鼠標進入數字按鈕自動切換;鼠標點擊左右切換按鈕切換,而且數字按鈕跟着切換;自動輪播。
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="base.css"> <style> * { margin: 0; padding: 0; } #box { width: 400px; height: 250px; margin: 100px 0 0 400px; position: relative; border: 2px solid #31608a; overflow: hidden; } ul { width: 1300px; position: absolute; } li { list-style-type: none; float: left; } img { width: 400px; height: 250px; } .sp { position: absolute; left: 50%; margin-left: -45px; bottom: 10px; } span { float: left; width: 20px; height: 20px; background-color: #fff; border-radius: 10px; text-align: center; font: 400 16px/20px Consolas; margin: 0 5px 0 5px; cursor: pointer; } .spdiv { width: 400px; height: 50px; position: absolute; top: 100px; display: none; } #left { width: 50px; height: 50px; float: left; cursor: pointer; text-align: center; font: 400 28px/50px Consolas; color: #fff; background-color: rgba(255, 255, 255, 0.3); } #right { float: right; width: 50px; height: 50px; cursor: pointer; text-align: center; font: 400 28px/50px Consolas; color: #fff; background-color: rgba(255, 255, 255, 0.3); } .current { background-color: red; color: #fff; } </style> </head> <body> <div id="box"> <ul> <li><a href="#"><img src="images/img1.jpg" alt=""></a></li> <li><a href="#"><img src="images/img2.jpg" alt=""></a></li> <li><a href="#"><img src="images/img3.jpg" alt=""></a></li> </ul> <div class="sp"> <span class="current">1</span> <span>2</span> <span>3</span> </div> <div class="spdiv"> <s id="left"><</s> <s id="right">></s> </div> </div> <script src="common.js"></script> <script> // 獲取box元素 var boxObj = my$("box"); // 獲取ul元素,由於移動的就是整個ul var ulObj = boxObj.children[0]; // 移動寬度 var moveWidth = document.getElementsByTagName("img")[0].offsetWidth; // 獲取ul中全部的li var liObjs = ulObj.children; ulObj.appendChild(liObjs[0].cloneNode(true)); // 克隆第一個li,加入到ul中的最後 ulObj.style.width = ulObj.offsetWidth + moveWidth + "px"; // 從新設置ul的寬度 // 獲取全部span標籤 var spanObjs = boxObj.children[1].getElementsByTagName("span"); // console.log(spanObjs); // 獲取spdiv標籤 var spdivObj = boxObj.children[2]; // 獲取span左標籤 var leftObj = my$("left"); // 獲取span右標籤 var rightObj = my$("right"); var pos = 0; var myTimeId = setInterval(moveRight, 1000); // 自動播放 + 鼠標進入事件 boxObj.onmouseover = function () { spdivObj.style.display = "block"; clearInterval(myTimeId); }; boxObj.onmouseout = function () { spdivObj.style.display = "none"; myTimeId = setInterval(moveRight, 1000); }; // 左移 leftObj.onclick = function () { if (pos === 0) { pos = spanObjs.length; ulObj.style.left = -spanObjs.length * moveWidth + "px"; } pos--; animation(ulObj, -pos * moveWidth); for (var i = 0; i < spanObjs.length; i++) { // 清空span背景 spanObjs[i].removeAttribute("class"); } // 設置當前span標籤 spanObjs[pos].className = "current"; }; // 右移 rightObj.onclick = moveRight; function moveRight() { if (pos === spanObjs.length) { // 在到達克隆的一張的時候,當即跳到第一張 pos = 0; ulObj.style.left = 0 + "px"; } pos++; animation(ulObj, -pos * moveWidth); if (pos === spanObjs.length) { spanObjs[0].className = "current"; spanObjs[spanObjs.length - 1].className = ""; } else { for (var i = 0; i < spanObjs.length; i++) { // 清空span背景 spanObjs[i].removeAttribute("class"); } // 設置當前span標籤 spanObjs[pos].className = "current"; } }; // 遍歷全部的 span 標籤 for (var i = 0; i < spanObjs.length; i++) { // 獲取每一個span的編號,設置自定義屬性 spanObjs[i].setAttribute("index", i + ""); spanObjs[i].onmouseover = function () { for (var j = 0; j < spanObjs.length; j++) { // 清空span背景 spanObjs[j].removeAttribute("class"); } // 設置當前span標籤 this.className = "current"; // 每一個編號*移動的寬度就是移動到的目標位置 pos = this.getAttribute("index"); if (pos) { animation(ulObj, -pos * moveWidth); } else { } }; } // 封裝動畫移動函數 function animation(element, target) { // 判斷當前的位置 var current = element.offsetLeft; var onestep = 7; var timeId = setInterval(function () { current += current < target ? onestep : -onestep; if (Math.abs(current - target) >= onestep) { element.style.left = current + "px"; } else { clearInterval(timeId); element.style.left = target + "px"; } }, 10); } </script> </body> </html>
一、首先獲取全部須要的元素。
二、使用克隆第一個 li 標籤來模擬從最後一個圖片切換到第一個圖片的過程。注意:這時候 ul 的寬度要改變,保證 li 的浮動在一行顯示。
三、在右移最後一張過分到第二張的時候的處理方式爲:當用戶看到第一張的時候實際上是最後一張,這個時候怎麼過分到第二張?處理方法是,當在須要從最後一張跳轉到第二張的時候,先讓最後一張圖切換到第一張,由於是克隆的,因此最後一張和第一張沒有區別,用戶看到的第一張實際上是最後一張切換到了第一張,這個時候正常切換到第二張便可。
四、當須要點擊左右切換按鈕,須要數字按鈕相對應的時候,注意第一個數字按鈕和最後一個數字按鈕的特殊處理。
五、圖片下標 pos 是連接點擊按鈕和數字按鈕的關鍵。
六、設置自動播放的時候,不使用定時器設置 pos 的方式,是由於當前 pos 的值不肯定,使用自動點擊右移按鈕的方式。之因此設置兩個 setInterval(moveRight, 1000); ,一個是進入頁面自動播放,一個是鼠標退出 box 後的自動播放。