web前端练习23----js中延时执行函数setInterval()和setTimeout() 案例:倒计时,大小动画平移动画,轮播图

Posted zhaihaohao1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

 

 

 

以上是关于web前端练习23----js中延时执行函数setInterval()和setTimeout() 案例:倒计时,大小动画平移动画,轮播图的主要内容,如果未能解决你的问题,请参考以下文章

web前端练习22----js中的原型对象prototype,原型链(重要)

好程序员web前端分享前端javascript练习题一

好程序员web前端教程分享前端javascript练习题之闭包案例

JavaScript定时器(延时定时器和间歇定时器)

web前端练习28----Dom4,事件(事件对象,事件冒泡,事件委派,事件传播,事件绑定,事件移除及案例练习)

web前端练习28----Dom4,事件(事件对象,事件冒泡,事件委派,事件传播,事件绑定,事件移除及案例练习)