一、定時器
1. setInterval()
函數
-
setInterval()
函數可以重復調用一個函數,在每次調用之間具有固定的時間間隔
。setInterval(function () { // 這個函數將自動被以固定間隔時間調用 }, 2000);
- 第一個參數是函數
- 第二個參數是間隔時間,以毫秒為單位,1000毫秒是1秒
-
函數的參數
setInterval()
函數可以接收第3、4……個參數,它們將按順序傳入函數setInterval(function (a, b) {// 形式參數a的值是88,形式參數b的值是66 }, 2000, 88, 66);
- 從第三個參數開始,表示傳入函數內的參數
-
具名函數也可以傳入setInterval
var a = 0; function fun() { console.log(++a);}setInterval(fun, 1000);
- 具名函數當做第一個參數,注意這里沒有圓括號!
-
清除定時器
clearInterval()
函數可以清除一個定時器。// 設置定時器,并且用timer變量接收這個定時器 var timer = setInterval(function () {}, 2000);// 點擊按鈕時,清除定時器 oBtn.onclick = function () { clearInterval(timer); }
- 用變量
timer
- 清除定時器的時候,要傳入定時器變量
- 用變量
二、延時器
1. setTimeout()
函數
setTimeout()
函數可以設置一個延時器,當指定時間到了之后,會執行函數一次,不再重復執行。setTimeout(function () { // 這個函數會在2秒后執行一次 }, 2000);
- 清除延時器
clearTimeout()
函數可以清除延時器,和clearInterval()
非常類似
三、異步語句
-
setInterval()
和setTimeout()
是兩個異步語句。 -
異步(asynchronous):不會阻塞CPU繼續執行其他語句,當異步完成時,會執行"回調函數"(callback)
setTimeout(function () { console.log('A'); }, 2000); console.log('B');
- 打印:B A
console.log('B');
異步語句不會阻塞程序的正常執行。
-
使用定時器實現動畫
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#box {position: absolute;top: 100px;left: 100px;width: 100px;height: 100px;background-color: orange;}</style> </head><body><button id="btn">開始運動</button><div id="box"></div><script>// 得到元素var btn = document.getElementById('btn');var box = document.getElementById('box');// 全局變量盒子的left值var left = 100;// 按鈕監聽btn.onclick = function () {var timer = setInterval(function () {// 改變全局變量left += 10;if (left >= 1000) {clearInterval(timer);}// 設置left屬性box.style.left = left + 'px';}, 20);};</script> </body></html>
- 使用定時器可以實現動畫,利用的就是"視覺暫留"原理。
- 使用定時器實現動畫較為不便:
- 不方便根據動畫總時間計算步長
- 運動方向要設置正負
- 多種運動進行疊加較為困難(比如一個方形一邊移動 一邊變為圓形)
-
JS和CSS3結合實現動畫
- JavaScript可以利用
CSS3
的transition
屬性輕松實現元素動畫。 - JS和CSS3結合實現動畫規避了定時器制作動畫的缺點
- JavaScript可以利用
-
函數節流
- 函數節流:一個函數執行一次后,只有大于設定的執行周期 后才允許執行第二次
- 函數節流非常容易實現,只需要借助setTimeout()延時器
var lock = true;function 需要節流的函數() {// 如果鎖是關閉狀態,則不執行 if (!lock) return; // 函數核心語句// 關鎖 lock = false;// 指定毫秒數后將鎖打開 setTimeout(function () { lock = true; }, 2000);}
-
無縫連續滾動特效
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;padding: 0;}.box {width: 1000px;height: 130px;border: 1px solid #000;margin: 50px auto;overflow: hidden;}.box ul {list-style: none;/* 設置大一點,這樣li才能浮動 */width: 5000px;position: relative;}.box ul li {float: left;margin-right: 10px;}</style> </head><body><div id="box" class="box"><ul id="list"><li><img src="images/number/0.png" alt=""></li><li><img src="images/number/1.png" alt=""></li><li><img src="images/number/2.png" alt=""></li><li><img src="images/number/3.png" alt=""></li><li><img src="images/number/4.png" alt=""></li><li><img src="images/number/5.png" alt=""></li></ul></div><script>var box = document.getElementById('box');var list = document.getElementById('list');// 復制多一遍所有的lilist.innerHTML += list.innerHTML;// 全局變量,表示當前list的left值var left = 0;// 定時器,全局變量var timer;move();// 動畫封裝成函數function move() {// 設表先關,防止動畫積累clearInterval(timer);timer = setInterval(function () {left -= 4;// 驗收if (left <= - 1260) {left = 0;}list.style.left = left + 'px';}, 20);}// 鼠標進入停止定時器box.onmouseenter = function () {clearInterval(timer);};// 鼠標離開繼續定時器box.onmouseleave = function () {move();};</script> </body></html>
-
跑馬燈輪播圖
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>*{margin: 0;padding: 0;}.carousel {width: 650px;height: 360px;border: 1px solid #000;margin: 50px auto;position: relative;overflow: hidden;}.carousel ul {list-style: none;width: 6000px;position: relative;left: 0px;transition: left .5s ease 0s;}.carousel ul li {float: left;}.carousel .leftbtn {position: absolute;left: 20px;top: 50%;margin-top: -25px;width: 50px;height: 50px;background-color: rgb(28, 180, 226);border-radius: 50%;}.carousel .rightbtn {position: absolute;right: 20px;top: 50%;margin-top: -25px;width: 50px;height: 50px;background-color: rgb(28, 180, 226);border-radius: 50%;}</style> </head> <body><div class="carousel"><ul id="list"><li><img src="images/beijing/0.jpg" alt=""></li><li><img src="images/beijing/1.jpg" alt=""></li><li><img src="images/beijing/2.jpg" alt=""></li><li><img src="images/beijing/3.jpg" alt=""></li><li><img src="images/beijing/4.jpg" alt=""></li></ul><a href="javascript:;" class="leftbtn" id="leftbtn"></a><a href="javascript:;" class="rightbtn" id="rightbtn"></a></div><script>// 得到按鈕和ul,ul整體進行運動var leftbtn = document.getElementById('leftbtn');var rightbtn = document.getElementById('rightbtn');var list = document.getElementById('list');// 克隆第一張圖片var cloneli = list.firstElementChild.cloneNode(true);list.appendChild(cloneli);// 當前ul顯示到第幾張了,從0開始數var idx = 0;// 節流鎖var lock = true;// 右邊按鈕監聽rightbtn.onclick = function () {// 判斷鎖的狀態if (!lock) return; lock = false;// 給list加過渡,為什么要加??css中不是已經加了么??這是因為最后一張圖片會把過渡去掉list.style.transition = 'left .5s ease 0s';idx ++;if (idx > 4) {// 設置一個延時器,延時器的功能就是將ul瞬間拉回0的位置,延時器的目的就是讓過渡動畫結束之后setTimeout(function() {// 取消掉過渡,因為要的是瞬間移動,不是“咕嚕”回去list.style.transition = 'none';list.style.left = 0;idx = 0;}, 500);}list.style.left = -idx * 650 + 'px';// 函數節流setTimeout(function() {lock = true; }, 500);}// 左邊按鈕監聽leftbtn.onclick = function () {if (!lock) return;lock = false;// 判斷是不是第0張,如果是,就要瞬間用假的替換真的if (idx == 0) {// 取消掉過渡,因為要的是瞬間移動,不是“咕嚕”過去list.style.transition = 'none';// 直接瞬間移動到最后的假圖片上list.style.left = -5 * 650 + 'px';// 設置一個延時器,這個延時器的延時時間可以是0毫秒,雖然是0毫秒,但是可以讓我們過渡先是瞬間取消,然后再加上setTimeout(function() {// 加過渡list.style.transition = 'left .5s ease 0s';// idx改為真正的最后一張idx = 4;list.style.left = -idx * 650 + 'px';}, 0);} else {idx --;list.style.left = -idx * 650 + 'px';}// 函數節流setTimeout(function() {lock = true; }, 500);}</script> </body> </html>
-
呼吸輪播圖
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;padding: 0;}.carousel {width: 650px;height: 360px;border: 1px solid #000;margin: 50px auto;position: relative;}.carousel ul {list-style: none;}.carousel ul li {position: absolute;top: 0;left: 0;/* 透明度都是0 */opacity: 0;transition: opacity 1s ease 0s;}/* 只有第一張透明度是1 */.carousel ul li:first-child {opacity: 1;}.carousel .leftbtn {position: absolute;left: 20px;top: 50%;margin-top: -25px;width: 50px;height: 50px;background-color: rgb(28, 180, 226);border-radius: 50%;}.carousel .rightbtn {position: absolute;right: 20px;top: 50%;margin-top: -25px;width: 50px;height: 50px;background-color: rgb(28, 180, 226);border-radius: 50%;}</style> </head><body><div class="carousel"><ul id="list"><li><img src="images/beijing/0.jpg" alt=""></li><li><img src="images/beijing/1.jpg" alt=""></li><li><img src="images/beijing/2.jpg" alt=""></li><li><img src="images/beijing/3.jpg" alt=""></li><li><img src="images/beijing/4.jpg" alt=""></li></ul><a href="javascript:;" class="leftbtn" id="leftbtn"></a><a href="javascript:;" class="rightbtn" id="rightbtn"></a></div><script>// 得到按鈕和ul,ul整體進行運動var leftbtn = document.getElementById('leftbtn');var rightbtn = document.getElementById('rightbtn');var list = document.getElementById('list');var lis = list.getElementsByTagName('li');// 當前是第幾張圖顯示var idx = 0;// 節流var lock = true;// 右按鈕rightbtn.onclick = function () {// 判斷節流if (!lock) return;lock = false;// 還沒有改idx,此時的idx這個圖片就是老圖,老圖淡出lis[idx].style.opacity = 0;idx++;if (idx > 4) idx = 0;// 改了idx,此時的idx這個圖片就是新圖,新圖淡入lis[idx].style.opacity = 1;// 動畫結束之后,開鎖setTimeout(function () {lock = true;}, 1000);}// 左按鈕leftbtn.onclick = function () {// 判斷節流if (!lock) return;lock = false;// 還沒有改idx,此時的idx這個圖片就是老圖,老圖淡出lis[idx].style.opacity = 0;idx--;if (idx < 0) idx = 4;// 改了idx,此時的idx這個圖片就是新圖,新圖淡入lis[idx].style.opacity = 1;// 動畫結束之后,開鎖setTimeout(function () {lock = true;}, 1000);}</script> </body></html>
重點內容
- 訪問元素節點有哪些方法?
- 節點的關系有哪些?
- 常用節點操作有哪些?
- 節點的創建、移除和克隆要如何實現?
- 事件捕獲和冒泡是什么?應該如何設置?
- 什么是事件委托?什么時候要用事件委托?
- 使用定時器和CSS3的過度實現動畫