定时器(时间的使用)

时间:2022-04-09 23:34:01

window 对象允许以指定的时间间隔执行代码,这些时间间隔称为定时事件。

1. 延时器:推迟多少毫秒再执行前面的函数(只执行一次) ==> setTimeout()

  • window.setTimeout(function, milliseconds);

  • 第一个参数是要执行的函数。

  • 第二个参数指示执行之前的毫秒数。

  • 可以不带 window 前缀来编写。

// <button onclick='clearTimer()'>清除定时器</button>

var timer = window.setTimeout(func, 5000);
function func () {
    console.log('您很好');
    
}

function clearTimer(){      // 停止
    window.clearTimeout(timer);
}

2. 定时器:每隔多少毫秒一直执行这个函数(循环执行)==> setInterval()

  • window.setInterval(function, milliseconds);
1,
setInterval(function() {},10);
// 每隔10毫秒一直执行这个函数(循环定时器)

2,
var time = 1000;
setInterval(function() {},time);
time = 2000;
// 它是首先识别time为 1000,它只识别一次,然后一直执行函数,后来改变time就没用了

3,
setInterval是非常不准的。
setInterval底层是基于红黑树的

window.setInterval,它是window上的,里面函数的this指向window

4,
var timer = setInterval(function () {}, 1000);
var timer2 = setInterval(function () {}, 1000);
console.log(timer)//1
console.log(timer2)//2

// setInterval有返回值,它会返回数字就是第几个定时器,作为它的唯一标识

clearInterval(timer),那么清除定时器的时候它会利用唯一标识;
var timer = setInterval(function () {
    //想让它停止就加上
    clearInterval(timer);
}, 1000);

实例:设置一个三分钟的计时器

minutes : <input type = "text" value = "0">
seconds : <input type = "text" value = "0">
<input onclick = 'create()' type="button" value="开始">
<input onclick = 'clearTime()' type="button" value="结束">
var minutesNode = document.getElementsByTagName('input')[0];
var secondsNode = document.getElementsByTagName('input')[1];
var minutes = 0;
var seconds = 0;
function create(){
    time = setInterval(function () {
        seconds++;
        if(seconds == 60) {
            seconds = 0;
            minutes++;
        }
        secondsNode.value = seconds;
        minutesNode.value = minutes;
        
        if(minutes == 3){
            clearInterval(time);
        }
    }, 1000);
}

function clearTime(){
    clearInterval(time);
}

// 点击“开始”按钮计时开始,点击“结束”按钮停止计时。
// 计时到 3 分钟就停止

实例:时钟

// <div id="myDiv"></div>

myDiv.innerHTML = /\d\d:\d\d:\d\d/.exec(new Date().toString())[0];
setInterval(function(){
    myDiv.innerHTML = /\d\d:\d\d:\d\d/.exec(new Date().toString())[0];    
},500);

实例:简易倒计时

  • 简易倒计时就是每1s通过setInterval将设置的时间减去1来达到要求
<div id="myDiv">
    <label for="set"><input type="number" id="set" step="1" value="0">秒</label>
    <button id="btn">确定</button>
    <button id="reset">重置</button>    
</div>
var timer;
reset.onclick = function(){
    history.go();
}
btn.onclick = function(){
    if(timer) return;
    set.setAttribute('disabled','disabled');
    timer = setInterval(function(){
        if(Number(set.value) === 0){
            clearInterval(timer);
            timer = 0;
            set.removeAttribute('disabled');
            return;
        }
        set.value = Number(set.value) - 1;
    },1000);
} 

定时器(时间的使用)

实例:精确倒计时

由定时器的运行机制,我们知道每间隔1000ms去改变时间的作法并不可靠。更精确地做法,应该是与系统的运行时间作为参照,倒计时的时间变化与系统的时间变化同步,达到精确倒计时的效果 

注意:此部分中,需要通过取模运算和除法运算进行时、分、秒的计算

<div id="myDiv">
    <label for="hour"><input type="number" id="hour" min="0" max="23" step="1" value="0" />时</label>
    <label for="minute"><input type="number" id="minute" min="0" max="59" step="1" value="0" />分</label>
    <label for="second"><input type="number" id="second" min="0" max="23" step="1" value="0" />秒</label>
    <button id="btn">确定</button>
    <button id="reset">重置</button>
</div>
var timer;
//输入限制
hour.onchange = function(){
    if(Number(this.value) !== Number(this.value)) this.value = 0;
    if(this.value > 23) this.value = 23;
    if(this.value < 0) this.value = 0;
}
second.onchange = minute.onchange = function(){
    if(Number(this.value) !== Number(this.value)) this.value = 0;
    if(this.value > 59) this.value = 59;
    if(this.value < 0) this.value = 0;
}
reset.onclick = function(){
    history.go();
}
btn.onclick = function(){
    if(timer) return;
    for(var i = 0; i < 3; i++){
        myDiv.getElementsByTagName('input')[i].setAttribute('disabled','disabled');
    }
    //原始储存值
    var setOri = hour.value*3600 + minute.value*60 + second.value*1;
    //原始系统时间值
    var timeOri = (new Date()).getTime();
    //现在所剩时间值
    var setNow;
    cancelAnimationFrame(timer);
    timer = requestAnimationFrame(function fn(){
        //当前系统时间值
        var timeNow = (new Date()).getTime();
        //使系统时间的差值与设置时间的差值相等,来获得正常的时间变化
        setNow = setOri - Math.floor((timeNow - timeOri)/1000);
        hour.value = Math.floor((setNow%86400)/3600);
        minute.value = Math.floor((setNow%3600)/60);
        second.value = Math.floor(setNow%60);
        timer = requestAnimationFrame(fn);
        if(setNow==0){
            cancelAnimationFrame(timer);
            timer = 0;
            btn.innerHTML = '计时结束';
            for(var i = 0; i < 3; i++){
                myDiv.getElementsByTagName('input')[i].removeAttribute('disabled');
            }
            setTimeout(function(){
                btn.innerHTML = '确定';
            },1000)            
        }

    })
}

定时器(时间的使用)

实例:简易秒表

  • 每间隔100ms增加100ms即可

<div id="myDiv">
    <label for="set"><input id="set" value="0"></label>
    <button id="btn">开始</button>
    <button id="reset">重置</button>    
</div>
var timer;
var con = 'off';
var num = 0;
reset.onclick = function(){
    history.go();
}
btn.onclick = function(){
    if(con === 'off'){
        set.setAttribute('disabled','disabled');
        con = 'on';
        btn.innerHTML = '暂停';
        timer = setInterval(function(){
            num+= 100;
            var minute = Math.floor(num/1000/60);
            var second = Math.floor(num/1000);
            var ms = Math.floor(num%1000)/100;
            set.value = minute + ' : ' + second + ' . ' + ms; 
        },100);
    }else{
        clearInterval(timer);
        con = 'off';
        btn.innerHTML = '开始';    
    }
}    

定时器(时间的使用)

实例:精确秒表

与倒计时类似,使用计时器的时间间隔作为时间变化的参照是不准确的。更精确的做法,应该是使用系统的时间变化作为秒表的变化的参照

<div id="myDiv">
    <label for="set"><input id="set" value="0"></label>
    <button id="btn">开始</button>
    <button id="reset">重置</button>    
</div>
var timer;
var con = 'off';
//ori表示初始的系统时间
var ori;
//dis表示当前运行时的秒数(动态)
var dis = 0;
//last储存暂停时的秒数(静态)
var last = 0;
reset.onclick = function(){
    history.go();
}
btn.onclick = function(){
    if(con === 'off'){
        set.setAttribute('disabled','disabled');
        con = 'on';
        btn.innerHTML = '暂停';
        //保留已经走过的秒数的系统时间
        ori = (new Date()).getTime() - last; 
        timer = requestAnimationFrame(function fn(){

            dis = (new Date()).getTime() - ori;
            cancelAnimationFrame(timer);
            timer = requestAnimationFrame(fn);
            var minute = Math.floor(dis/1000/60);
            var second = Math.floor(dis/1000);
            var ms = Math.floor(dis%1000);
            set.value = minute + ' : ' + second + ' . ' + ms; 
        });
    }else{
        cancelAnimationFrame(timer);
        btn.innerHTML = '开始';    
        con = 'off';
        last = dis;
    }
}  

定时器(时间的使用)

实例:闹钟

<div id="myDiv"></div>
<div id="con">
    <label for="hour"><input type="number" id="hour" min="0" max="23" step="1" value="0" />时</label>
    <label for="minute"><input type="number" id="minute" min="0" max="59" step="1" value="0" />分</label>
    <label for="second"><input type="number" id="second" min="0" max="23" step="1" value="0" />秒</label>
    <button id="btn">确定</button>
    <button id="reset">重置</button>
</div>
<div id="show"></div>
<audio src='music/Bandari - Dream Catcher.mp3' preload="auto" id="music"></audio>
<!--preload规定当网页加载时,音频是否默认被加载以及如何被加载。 auto - 当页面加载后载入整个音频-->
var timer;
//所剩时间
var dis;
myDiv.innerHTML = /\d\d:\d\d:\d\d/.exec(new Date().toString())[0];
setInterval(function(){
    myDiv.innerHTML = /\d\d:\d\d:\d\d/.exec(new Date().toString())[0];    
},100);

reset.onclick = function(){
    history.go();
}

btn.onclick = function(){
    //原始储存值
    var setOri = hour.value*3600 + minute.value*60 + second.value*1;
    //原始值转换为1970年的毫秒数
    var setMs = +new Date(new Date().toDateString()) + setOri*1000;
    //如果设置的时间早于当前时间,则设置无效
    if(setMs < +new Date()){
        return;
    }
    for(var i = 0; i < 3; i++){
        con.getElementsByTagName('input')[i].setAttribute('disabled','disabled');
    }
    cancelAnimationFrame(timer);
    timer = requestAnimationFrame(function fn(){
        //算出设置时间与当前时间的差值
        dis = Math.ceil((setMs - (new Date()).getTime())/1000);
        var showHour = Math.floor((dis%86400)/3600);
        var showMinute = Math.floor((dis%3600)/60);
        var showSecond = Math.floor(dis%60);
        timer = requestAnimationFrame(fn);
        show.innerHTML = '距离预定时间还有 ' + showHour + '小时 ' + showMinute + '分 ' + showSecond + '秒';
        //当差值为0时,时间到
        if(dis==0){
            cancelAnimationFrame(timer);
            music.play();     
        }
    });
}