文檔:
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setInterval
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setTimeout
setInterval();
定時執行函數 setInterval 無限次的執行,要通過 clearInterval() 停止
基本語法
每1秒執行一次,無限次的執行
通過 clearInterval() 停止
let timer = setInterval(function () {
console.log('無限執行');
}, 1000);
// clearInterval(timer);
setTimeout();
基本語法
延時1秒後執行,執行一次
通過 clearTimeout() 停止執行
let time2 = setTimeout(function(){
console.log('執行一次');
}, 1000);
//clearTimeout(time2);
應用:
案例1:倒計時
分別使用 setInterval() 和 setTimeout 寫個倒計時
setInterval() 實現倒計時
// 這裏寫一個倒計時
function daojishi1() {
let time = 10;
let countdown = setInterval(function () {
time--;
if (time == 0) {
// 停止執行
clearInterval(countdown);
} else {
console.log(time);
}
}, 1000);
}
daojishi1();
setTimeout() 實現倒計時
let jjj = 10;
function daojishi2() {
let daojishi = setTimeout(function () {
--jjj;
if (jjj == 0) {
// 停止執行
clearTimeout(daojishi);
} else {
console.log(jjj);
// 遞歸調用
daojishi2();
}
}, 1000);
}
daojishi2();
案例2:封裝一個 移動動畫的函數:
2.1 實現向右移動
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0px;
padding: 0px;
}
#box {
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
}
#line {
width: 1px;
height: 100%;
background-color: black;
position: absolute;
left: 800px;
}
</style>
</head>
<body>
<div>
<button id="kaishi">開始</button>
<button id="jieshu">停止</button>
</div>
<!-- 定時器動畫效果 -->
<div id="box">完成一個動畫效果</div>
<div id="line"></div>
<script>
let kaishi = document.getElementById('kaishi');
let jieshu = document.getElementById('jieshu');
let box = document.getElementById('box');
let timer;
kaishi.onclick = function() {
clearInterval(timer);
timer = setInterval(function() {
// 當前生效的屬性
let leftShengXiao = parseInt(getStyle(box, 'left'));
let leftDistance = leftShengXiao + 30;
if (leftDistance >= 800) {
leftDistance = 800;
}
// 向右移動,就是改變離左邊的距離
box.style.left = leftDistance + 'px';
if (leftDistance == 800) {
clearInterval(timer);
}
}, 30);
}
jieshu.onclick = function() {
clearInterval(timer);
}
/*
* 定義一個函數,用來獲取指定元素的當前的樣式
* 參數:
* obj 要獲取樣式的元素
* name 要獲取的樣式名
*/
function getStyle(obj, name) {
if (window.getComputedStyle) {
//正常瀏覽器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,沒有getComputedStyle()方法
return obj.currentStyle[name];
}
}
</script>
</body>
</html>
2.2實現向左,或向右移動, 封裝成一個函數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0px;
padding: 0px;
}
#box {
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
}
#line {
width: 1px;
height: 100%;
background-color: black;
position: absolute;
left: 800px;
}
</style>
</head>
<body>
<div id="line"></div>
<div>
<button id="kaishi">開始(向右跑)</button>
<button id="kaishiLeft">開始(向左跑)</button>
</div>
<!-- 定時器動畫效果 -->
<div id="box">完成一個動畫效果</div>
<script>
let kaishi = document.getElementById('kaishi');
let kaishiLeft = document.getElementById('kaishiLeft');
let box = document.getElementById('box');
let timer;
// 向右跑
// 對象 box 向右到 800 速度是5
kaishi.onclick = function() {
move(box, 800, 3);
}
// 向左跑
// 對象 box 向左到 0 速度是5
kaishiLeft.onclick = function() {
move(box, 0, 3);
}
/*
* 把移動動畫轉化成一個函數
* element 運動的元素
* target 目標距離
* speed 奔跑速度
*
*/
function move(element, target, speed) {
clearInterval(timer);
// 拿到當前的位置
let leftShengXiao = parseInt(getStyle(element, 'left'));
if (leftShengXiao > target) {
speed = -speed;
}
timer = setInterval(function() {
// 當前生效的屬性
let leftShengXiao = parseInt(getStyle(element, 'left'));
let newJuLi = leftShengXiao + speed;
// 判斷保證移動到目標的準確性 右移,左移
if ((speed > 0 && newJuLi > target) || speed < 0 && newJuLi < target) {
newJuLi = target;
}
// 向右移動,就是改變離左邊的距離
element.style.left = newJuLi + 'px';
if (newJuLi == target) {
clearInterval(timer);
}
}, 30);
}
/*
* 定義一個函數,用來獲取指定元素的當前的樣式
* 參數:
* obj 要獲取樣式的元素
* name 要獲取的樣式名
*/
function getStyle(obj, name) {
if (window.getComputedStyle) {
//正常瀏覽器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,沒有getComputedStyle()方法
return obj.currentStyle[name];
}
}
</script>
</body>
</html>
2.3 封裝成通用的函數,能夠左右移動,能夠改變大小
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0px;
padding: 0px;
}
#box {
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
}
#box2 {
width: 100px;
height: 100px;
background-color: brown;
position: absolute;
top: 200px;
}
#line {
width: 1px;
height: 100%;
background-color: black;
position: absolute;
left: 800px;
}
</style>
</head>
<body>
<div id="line"></div>
<div>
<button id="kaishi">開始(向右跑)</button>
</div>
<!-- 定時器動畫效果 -->
<div id="box">完成一個動畫效果</div>
<script>
let box = document.getElementById('box');
// 向右跑
// 對象 box 向右到 800 速度是5
kaishi.onclick = function() {
move(box, 'left', 800, 17, function() {
// 注意他的本來寬高是 100,設置成100是沒有效果的
move(box, 'height', 50, 5);
});
}
/*
* 封裝一個動畫的方法
* 把移動動畫轉化成一個函數
* element 運動的元素
* attr:要執行動畫的樣式,比如:left top width height
* target 目標距離
* speed 奔跑速度
* callback 動畫執行完之後的回調
*
*/
function move(element, attr, target, speed, callback) {
clearInterval(element.timer);
// 拿到當前的位置
let leftShengXiao = parseInt(getStyle(element, attr));
if (leftShengXiao > target) {
speed = -speed;
}
element.timer = setInterval(function() {
// 當前生效的屬性
let leftShengXiao = parseInt(getStyle(element, attr));
let newJuLi = leftShengXiao + speed;
// 判斷保證移動到目標的準確性 右移,左移
if ((speed > 0 && newJuLi > target) || speed < 0 && newJuLi < target) {
newJuLi = target;
}
// 向右移動,就是改變離左邊的距離
element.style[attr] = newJuLi + 'px';
if (newJuLi == target) {
clearInterval(element.timer);
if (callback) {
callback();
}
}
}, 30);
}
/*
* 定義一個函數,用來獲取指定元素的當前的樣式
* 參數:
* obj 要獲取樣式的元素
* name 要獲取的樣式名
*
* 這個函數要好好的推敲一下,要知道,這個函數在那一節講過
* 把相關技術整理整理
*/
function getStyle(obj, name) {
if (window.getComputedStyle) {
//正常瀏覽器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,沒有getComputedStyle()方法
return obj.currentStyle[name];
}
}
</script>
</body>
</html>
案例3.實現輪播圖:
效果圖:
3.1實現點擊指示器,切換圖片:
第一步:工具類 tools.js,就是把上面封裝的 移動動畫的函數 抽取出來,作爲一個單獨文件調用:
//嘗試創建一個可以執行簡單動畫的函數
/*
* 參數:
* obj:要執行動畫的對象
* attr:要執行動畫的樣式,比如:left top width height
* target:執行動畫的目標位置
* speed:移動的速度(正數向右移動,負數向左移動)
* callback:回調函數,這個函數將會在動畫執行完畢以後執行
*/
function move(obj, attr, target, speed, callback) {
//關閉上一個定時器
clearInterval(obj.timer);
//獲取元素目前的位置
var current = parseInt(getStyle(obj, attr));
//判斷速度的正負值
//如果從0 向 800移動,則speed爲正
//如果從800向0移動,則speed爲負
if(current > target) {
//此時速度應爲負值
speed = -speed;
}
//開啓一個定時器,用來執行動畫效果
//向執行動畫的對象中添加一個timer屬性,用來保存它自己的定時器的標識
obj.timer = setInterval(function() {
//獲取box1的原來的left值
var oldValue = parseInt(getStyle(obj, attr));
//在舊值的基礎上增加
var newValue = oldValue + speed;
//判斷newValue是否大於800
//從800 向 0移動
//向左移動時,需要判斷newValue是否小於target
//向右移動時,需要判斷newValue是否大於target
if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
newValue = target;
}
//將新值設置給box1
obj.style[attr] = newValue + "px";
//當元素移動到0px時,使其停止執行動畫
if(newValue == target) {
//達到目標,關閉定時器
clearInterval(obj.timer);
//動畫執行完畢,調用回調函數
callback && callback();
}
}, 30);
}
/*
* 定義一個函數,用來獲取指定元素的當前的樣式
* 參數:
* obj 要獲取樣式的元素
* name 要獲取的樣式名
*/
function getStyle(obj, name) {
if(window.getComputedStyle) {
//正常瀏覽器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,沒有getComputedStyle()方法
return obj.currentStyle[name];
}
}
第二步:點擊指示器,完成圖片切換:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#outer {
width: 200px;
height: 200px;
position: relative;
margin: 50px auto;
background-color: chartreuse;
border: 10px yellowgreen solid;
overflow: hidden;
}
#imgList {
list-style: none;
width: 1000px;
height: 200px;
position: absolute;
left: 0px;
top: 0px;
box-sizing: border-box;
}
#imgList li {
float: left;
width: 200px;
height: 200px;
box-sizing: border-box;
}
#imgList li img {
width: 200px;
height: 200px;
box-sizing: border-box;
}
/*設置導航按鈕*/
#navDiv {
/*開啓絕對定位*/
position: absolute;
/*設置位置*/
bottom: 15px;
/*設置left值
outer寬度 200
navDiv寬度 20*5 = 100
200 - 100 = 100/2 = 50
* */
left: 50px;
}
#navDiv a {
/*設置超鏈接浮動*/
float: left;
/*設置超鏈接的寬和高*/
width: 10px;
height: 10px;
/*設置背景顏色*/
background-color: red;
/*設置左右外邊距*/
margin: 0 5px;
/*設置透明*/
opacity: 0.5;
/*兼容IE8透明*/
filter: alpha(opacity=50);
}
</style>
</head>
<body>
<!-- 創建一個外部的div,來作爲大的容器 -->
<div id="outer">
<!-- 創建一個ul,用於放置圖片 -->
<ul id="imgList">
<li id="li0"><img src="http://pic31.nipic.com/20130703/7447430_141623328000_2.jpg" /></li>
<li><img src="http://pic36.nipic.com/20131208/14707495_183310522168_2.jpg" /></li>
<li><img src="http://pic31.nipic.com/20130727/13038997_113031257000_2.jpg" /></li>
<li><img src="http://pic39.nipic.com/20140318/4345437_001948326145_2.jpg" /></li>
<li><img src="http://pic45.nipic.com/20140805/7447430_145300895000_2.jpg" /></li>
</ul>
<div id="navDiv">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
<!-- 引入動畫的js -->
<script type="text/javascript" src="tools.js"></script>
<script>
// ul對象
let imgList = document.getElementById('imgList');
// 導航對象
let navDiv = document.getElementById('navDiv');
// 拿到a元素的集合
let aCollect = navDiv.getElementsByTagName('a');
// 把集合轉成數組
let aArray = [...aCollect];
// 設置第一個顏色
aArray[0].style.backgroundColor = "black";
// 循環數組,綁定點擊事件
for (let i = 0; i < aArray.length; i++) {
aArray[i].onclick = function () {
console.log('打印索引' + i);
setBackGround(i);
let target = i * (-200);
move(imgList, 'left', target, 10, function () { });
}
}
/*
寫一個點擊索引改變背景顏色
*/
function setBackGround(clickIndex) {
for (let index = 0; index < aArray.length; index++) {
aArray[index].style.backgroundColor = 'red';
}
aArray[clickIndex].style.backgroundColor = 'black';
}
</script>
</body>
</html>
3.2實現自動輪播:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#outer {
width: 200px;
height: 200px;
position: relative;
margin: 50px auto;
background-color: chartreuse;
border: 10px yellowgreen solid;
/*裁剪溢出的內容*/
/* 調試的時候可以放開看一下效果 */
overflow: hidden;
}
#imgList {
list-style: none;
/* width: 1200px; */
height: 200px;
position: absolute;
left: 0px;
top: 0px;
box-sizing: border-box;
}
#imgList li {
float: left;
width: 200px;
height: 200px;
box-sizing: border-box;
}
#imgList li img {
width: 200px;
height: 200px;
box-sizing: border-box;
}
/*設置導航按鈕*/
#navDiv {
/*開啓絕對定位*/
position: absolute;
/*設置位置*/
bottom: 15px;
/*設置left值
outer寬度 200
navDiv寬度 20*5 = 100
200 - 100 = 100/2 = 50
* */
left: 50px;
}
#navDiv a {
/*設置超鏈接浮動*/
float: left;
/*設置超鏈接的寬和高*/
width: 10px;
height: 10px;
/*設置背景顏色*/
background-color: red;
/*設置左右外邊距*/
margin: 0 5px;
/*設置透明*/
opacity: 0.5;
/*兼容IE8透明*/
filter: alpha(opacity=50);
}
</style>
</head>
<body>
<!-- 創建一個外部的div,來作爲大的容器 -->
<div id="outer">
<!-- 創建一個ul,用於放置圖片 -->
<ul id="imgList">
<li id="li0"><img src="http://img.sccnn.com/bimg/326/203.jpg" /></li>
<li><img src="http://pic30.nipic.com/20130624/7447430_170333629000_2.jpg" /></li>
<li><img src="http://img08.tooopen.com/20191016/tooopen_sl_174947494798654.jpg" /></li>
<li><img src="http://pic39.nipic.com/20140318/4345437_001948326145_2.jpg" /></li>
<li><img src="http://pic45.nipic.com/20140805/7447430_145300895000_2.jpg" /></li>
</ul>
<div id="navDiv">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
<!-- 引入動畫的js -->
<script type="text/javascript" src="tools.js"></script>
<script>
// ul對象
let imgList = document.getElementById('imgList');
// 把第一個對象克隆出來放到末尾
let li0 = document.getElementById('li0');
let cloneLi0 = li0.cloneNode(true);
// 放入克隆後的元素,此時元素數量就是 6
imgList.appendChild(cloneLi0);
// 查找imgList下面的子元素,應該就是6
let liCollect = imgList.getElementsByTagName('li');
let liArray = [...liCollect];
// 設置ul的寬度
imgList.style.width = 200 * liArray.length + 'px';
// 導航對象
let navDiv = document.getElementById('navDiv');
// 拿到a元素的集合
let aCollect = navDiv.getElementsByTagName('a');
// 把集合轉成數組
let aArray = [...aCollect];
//默認顯示圖片的索引
let myIndex = 0;
//設置默認選中的效果
aArray[myIndex].style.backgroundColor = "black";
let timer;
lunbo();
// 循環數組,綁定點擊事件
for (let i = 0; i < aArray.length; i++) {
aArray[i].onclick = function () {
clearInterval(timer);
myIndex = i;
setABackGround();
move(imgList, 'left', -200 * myIndex, 10, function () {
lunbo();
});
}
}
// 輪播
function lunbo() {
timer = setInterval(function () {
myIndex++;
myIndex = myIndex % liArray.length;
console.log(myIndex + ">>>" + liArray.length);
move(imgList, 'left', -200 * myIndex, 10, function () {
setABackGround();
});
}, 1000);
}
/*
寫一個點擊索引改變背景顏色
*/
function setABackGround() {
if (myIndex >= liArray.length - 1) {
//則將index設置爲0
myIndex = 0;
//此時顯示的最後一張圖片,而最後一張圖片和第一張是一摸一樣
//通過CSS將最後一張切換成第一張
imgList.style.left = 0 + 'px';
}
// 設置指示器的顏色
//遍歷所有a,並將它們的背景顏色設置爲紅色
for (let index = 0; index < aArray.length; index++) {
aArray[index].style.backgroundColor = 'red';
}
aArray[myIndex].style.backgroundColor = 'black';
}
</script>
</body>
</html>
參考視頻:131-136
http://www.gulixueyuan.com/course/58/tasks