web前端練習23----js中延時執行函數setInterval()和setTimeout() 案例:倒計時,大小動畫平移動畫,輪播圖

文檔:

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

 

 

 

 

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