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();
}
});
}