最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

BOM系列第一篇之定時器setTimeout和setInterval

 更新時間:2016年08月17日 10:38:41   作者:小火柴的藍(lán)色理想  
這篇文章主要介紹了BOM系列第一篇之定時器setTimeout和setInterval 的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

setTimeout()

  setTimeout()方法用來指定某個函數(shù)或字符串在指定的毫秒數(shù)之后執(zhí)行。它返回一個整數(shù),表示定時器的編號,這個值可以傳遞給clearTimeout()用于取消這個函數(shù)的執(zhí)行

  以下代碼中,控制臺先輸出0,大概過1000ms即1s后,輸出定時器setTimeout()方法的返回值1

var Timer = setTimeout(function(){
console.log(Timer);
},1000);
console.log(0);

  也可以寫成字符串參數(shù)的形式,由于這種形式會造成javascript引擎兩次解析,降低性能,故不建議使用

var Timer = setTimeout('console.log(Timer);',1000);
console.log(0);

  如果省略setTimeout的第二個參數(shù),則該參數(shù)默認(rèn)為0

  以下代碼中,控制臺出現(xiàn)0和1,但是0卻在前面,后面會解釋這個疑問

var Timer = setTimeout(function(){
console.log(Timer);
});
console.log(0);

  實(shí)際上,除了前兩個參數(shù),setTimeout()方法還允許添加更多的參數(shù),它們將被傳入定時器中的函數(shù)中

  以下代碼中,控制臺大概過1000ms即1s后,輸出2,而IE9-瀏覽器只允許setTimeout有兩個參數(shù),不支持更多的參數(shù),會在控制臺輸出NaN

setTimeout(function(a,b){
console.log(a+b);
},1000,1,1);

  可以使用IIFE傳參來兼容IE9-瀏覽器的函數(shù)傳參

setTimeout((function(a,b){
return function(){
console.log(a+b);
}
})(1,1),1000);

  或者將函數(shù)寫在定時器外面,然后函數(shù)在定時器中的匿名函數(shù)中帶參數(shù)調(diào)用

function test(a,b){
console.log(a+b);
}
setTimeout(function(){
test(1,1);
},1000);

this指向

  在this機(jī)制系列已經(jīng)詳細(xì)介紹過this指向的4種綁定規(guī)則,由于定時器中的this存在隱式丟失的情況,且極易出錯,因此在這里再次進(jìn)行說明

var a = 0;
function foo(){
console.log(this.a);
};
var obj = {
a : 2,
foo:foo
}
setTimeout(obj.foo,100);//0
//等價于
var a = 0;
setTimeout(function foo(){
console.log(this.a);
},100);//0

  若想獲得obj對象中的a屬性值,可以將obj.foo函數(shù)放置在定時器中的匿名函數(shù)中進(jìn)行隱式綁定

var a = 0;
function foo(){
console.log(this.a);
};
var obj = {
a : 2,
foo:foo
}
setTimeout(function(){
obj.foo();
},100);//2

  或者也可以使用bind方法將foo()方法的this綁定到obj上

var a = 0;
function foo(){
console.log(this.a);
};
var obj = {
a : 2,
foo:foo
}
setTimeout(obj.foo.bind(obj),100);//2

clearTimeout()

  setTimeout函數(shù)返回一個表示計(jì)數(shù)器編號的整數(shù)值,將該整數(shù)傳入clearTimeout函數(shù),取消對應(yīng)的定時器

//過100ms后,控制臺輸出setTimeout()方法的返回值1
var Timer = setTimeout(function(){
console.log(Timer);
},100);

  于是可以利用這個值來取消對應(yīng)的定時器

var Timer = setTimeout(function(){
console.log(Timer);
},100);
clearTimeout(Timer);

  或者直接使用返回值作為參數(shù)

var Timer = setTimeout(function(){
console.log(Timer);
},100);
clearTimeout(1);

  一般來說,setTimeout返回的整數(shù)值是連續(xù)的,也就是說,第二個setTimeout方法返回的整數(shù)值比第一個的整數(shù)值大1

//控制臺輸出1、2、3
var Timer1 = setTimeout(function(){
console.log(Timer1);
},100);
var Timer2 = setTimeout(function(){
console.log(Timer2);
},100);
var Timer3 = setTimeout(function(){
console.log(Timer3);
},100);

setInterval()

  setInterval的用法與setTimeout完全一致,區(qū)別僅僅在于setInterval指定某個任務(wù)每隔一段時間就執(zhí)行一次,也就是無限次的定時執(zhí)行

<button id="btn">0</button>
<script>
var timer = setInterval(function(){
btn.innerHTML = Number(btn.innerHTML) + 1;
},1000);
btn.onclick = function(){
clearInterval(timer);
btn.innerHTML = 0;
}
</script>

  [注意]HTML5標(biāo)準(zhǔn)規(guī)定,setTimeout的最短時間間隔是4毫秒;setInterval的最短間隔時間是10毫秒,也就是說,小于10毫秒的時間間隔會被調(diào)整到10毫秒

  大多數(shù)電腦顯示器的刷新頻率是60HZ,大概相當(dāng)于每秒鐘重繪60次。因此,最平滑的動畫效的最佳循環(huán)間隔是1000ms/60,約等于16.6ms

  為了節(jié)電,對于那些不處于當(dāng)前窗口的頁面,瀏覽器會將時間間隔擴(kuò)大到1000毫秒。另外,如果筆記本電腦處于電池供電狀態(tài),Chrome和IE 9以上的版本,會將時間間隔切換到系統(tǒng)定時器,大約是16.6毫秒

運(yùn)行機(jī)制

  下面來解釋前面部分遺留的疑問,為什么下面代碼的控制臺結(jié)果中,0出現(xiàn)在1的前面呢?

setTimeout(function(){
console.log(1);
});
console.log(0);

  實(shí)際上,把setTimeout的第二個參數(shù)設(shè)置為0s,并不是立即執(zhí)行函數(shù)的意思,只是把函數(shù)放入代碼隊(duì)列

  在下面這個例子中,給一個按鈕btn設(shè)置了一個事件處理程序。事件處理程序設(shè)置了一個250ms后調(diào)用的定時器。點(diǎn)擊該按鈕后,首先將onclick事件處理程序加入隊(duì)列。該程序執(zhí)行后才設(shè)置定時器,再有250ms后,指定的代碼才被添加到隊(duì)列中等待執(zhí)行

btn.onclick = function(){
setTimeout(function(){
console.log(1);
},250);
}

  如果上面代碼中的onclick事件處理程序執(zhí)行了300ms,那么定時器的代碼至少要在定時器設(shè)置之后的300ms后才會被執(zhí)行。隊(duì)列中所有的代碼都要等到JavaScript進(jìn)程空閑之后才能執(zhí)行,而不管它們是如何添加到隊(duì)列中的

  如圖所示,盡管在255ms處添加了定時器代碼,但這時候還不能執(zhí)行,因?yàn)閛nclick事件處理程序仍在運(yùn)行。定時器代碼最早能執(zhí)行的時機(jī)是在300ms處,即onclick事件處理程序結(jié)束之后

setInterval的問題

  使用setInterval()的問題在于,定時器代碼可能在代碼再次被添加到隊(duì)列之前還沒有完成執(zhí)行,結(jié)果導(dǎo)致定時器代碼連續(xù)運(yùn)行好幾次,而之間沒有任何停頓。而javascript引擎對這個問題的解決是:當(dāng)使用setInterval()時,僅當(dāng)沒有該定時器的任何其他代碼實(shí)例時,才將定時器代碼添加到隊(duì)列中。這確保了定時器代碼加入到隊(duì)列中的最小時間間隔為指定間隔

  但是,這樣會導(dǎo)致兩個問題:1、某些間隔被跳過;2、多個定時器的代碼執(zhí)行之間的間隔可能比預(yù)期的小

  假設(shè),某個onclick事件處理程序使用serInterval()設(shè)置了200ms間隔的定時器。如果事件處理程序花了300ms多一點(diǎn)時間完成,同時定時器代碼也花了差不多的時間,就會同時出現(xiàn)跳過某間隔的情況

  例子中的第一個定時器是在205ms處添加到隊(duì)列中的,但是直到過了300ms處才能執(zhí)行。當(dāng)執(zhí)行這個定時器代碼時,在405ms處又給隊(duì)列添加了另一個副本。在下一個間隔,即605ms處,第一個定時器代碼仍在運(yùn)行,同時在隊(duì)列中已經(jīng)有了一個定時器代碼的實(shí)例。結(jié)果是,在這個時間點(diǎn)上的定時器代碼不會被添加到隊(duì)列中

迭代setTimeout

  為了避免setInterval()定時器的問題,可以使用鏈?zhǔn)絪etTimeout()調(diào)用

setTimeout(function fn(){
setTimeout(fn,interval);
},interval);

  這個模式鏈?zhǔn)秸{(diào)用了setTimeout(),每次函數(shù)執(zhí)行的時候都會創(chuàng)建一個新的定時器。第二個setTimeout()調(diào)用當(dāng)前執(zhí)行的函數(shù),并為其設(shè)置另外一個定時器。這樣做的好處是,在前一個定時器代碼執(zhí)行完之前,不會向隊(duì)列插入新的定時器代碼,確保不會有任何缺失的間隔。而且,它可以保證在下一次定時器代碼執(zhí)行之前,至少要等待指定的間隔,避免了連續(xù)的運(yùn)行

  使用setInterval()

<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;position:absolute;left:0;"></div>
<script>
myDiv.onclick = function(){
var timer = setInterval(function(){
if(parseInt(myDiv.style.left) > 200){
clearInterval(timer);
return false;
}
myDiv.style.left = parseInt(myDiv.style.left) + 5 + 'px'; 
},16); 
}
</script>

  使用鏈?zhǔn)絪etTimeout()

<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;position:absolute;left:0;"></div>
<script>
myDiv.onclick = function(){
setTimeout(function fn(){
if(parseInt(myDiv.style.left) <= 200){
setTimeout(fn,16); 
}else{
return false;
}
myDiv.style.left = parseInt(myDiv.style.left) + 5 + 'px'; 
},16); 
}
</script>

應(yīng)用

  使用定時器來調(diào)整事件發(fā)生順序

  【1】網(wǎng)頁開發(fā)中,某個事件先發(fā)生在子元素,然后冒泡到父元素,即子元素的事件回調(diào)函數(shù),會早于父元素的事件回調(diào)函數(shù)觸發(fā)。如果,我們先讓父元素的事件回調(diào)函數(shù)先發(fā)生,就要用到setTimeout(f, 0)

  正常情況下,點(diǎn)擊div元素,先彈出0,再彈出1

<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;"></div>
<script>
myDiv.onclick = function(){
alert(0);
}
document.onclick = function(){
alert(1);
}
</script>

  如果進(jìn)行想讓document的onclick事件先發(fā)生,即點(diǎn)擊div元素,先彈出1,再彈出0。則進(jìn)行如下設(shè)置

<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;"></div>
<script>
myDiv.onclick = function(){
setTimeout(function(){
alert(0);
})
}
document.onclick = function(){
alert(1);
}
</script>

  【2】用戶自定義的回調(diào)函數(shù),通常在瀏覽器的默認(rèn)動作之前觸發(fā)。比如,用戶在輸入框輸入文本,keypress事件會在瀏覽器接收文本之前觸發(fā)。因此,下面的回調(diào)函數(shù)是達(dá)不到目的

<input type="text" id="myInput">
<script>
myInput.onkeypress = function(event) {
this.value = this.value.toUpperCase();
}
</script>

  上面代碼想在用戶輸入文本后,立即將字符轉(zhuǎn)為大寫。但是實(shí)際上,它只能將上一個字符轉(zhuǎn)為大寫,因?yàn)闉g覽器此時還沒接收到文本,所以this.value取不到最新輸入的那個字符

  只有用setTimeout改寫,上面的代碼才能發(fā)揮作用

<input type="text" id="myInput">
<script>
myInput.onkeypress = function(event) {
setTimeout(function(){
myInput.value = myInput.value.toUpperCase();
});
}
</script> 

代碼到此結(jié)束。下篇給大家介紹

BOM系列第二篇之定時器requestAnimationFrame

BOM系列第三篇之定時器應(yīng)用(時鐘、倒計(jì)時、秒表和鬧鐘)

以上所述是小編給大家介紹的BOM系列第一篇之定時器setTimeout和setInterval ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • JavaScript觀察者模式(經(jīng)典)

    JavaScript觀察者模式(經(jīng)典)

    Observer模式也叫觀察者模式,是由GoF提出的23種軟件設(shè)計(jì)模式的一種。Observer模式是行為模式之一,它的作用是當(dāng)一個對象的狀態(tài)發(fā)生變化時,能夠自動通知其他關(guān)聯(lián)對象,自動刷新對象狀態(tài)
    2015-12-12
  • 詳解微信小程序中組件通訊

    詳解微信小程序中組件通訊

    在本篇文章里我們給大家分享了微信小程序中組件通訊的相關(guān)知識點(diǎn)以及相關(guān)實(shí)例代碼,有興趣的朋友們學(xué)習(xí)分享下。
    2018-10-10
  • js的三種繼承方式詳解

    js的三種繼承方式詳解

    本文主要介紹了js的三種繼承方式。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • electron實(shí)現(xiàn)讀取和寫入配置文件的示例詳解

    electron實(shí)現(xiàn)讀取和寫入配置文件的示例詳解

    這篇文章主要介紹了electron實(shí)現(xiàn)讀取和寫入配置文件的示例,文中通過代碼示例和圖文結(jié)合的方式介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03
  • 微信小程序?qū)崿F(xiàn)錨點(diǎn)定位功能的方法實(shí)例

    微信小程序?qū)崿F(xiàn)錨點(diǎn)定位功能的方法實(shí)例

    “錨點(diǎn)”功能在實(shí)際應(yīng)用設(shè)計(jì)的好,可以提高用戶體驗(yàn),這篇文章主要給大家介紹了關(guān)于微信小程序?qū)崿F(xiàn)錨點(diǎn)定位功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-07-07
  • javascript 事件處理示例分享

    javascript 事件處理示例分享

    這篇文章主要介紹了javascript 事件處理示例分享,需要的朋友可以參考下
    2014-12-12
  • kmock javascript 單元測試代碼

    kmock javascript 單元測試代碼

    javascript其實(shí)是非常需要單元測試的,但是qmock總感覺不好使?或是文檔的新舊有問題,反正我暫時是只需要函數(shù)調(diào)用的次數(shù)判斷,結(jié)果就寫了個kmock
    2011-02-02
  • 基于JS實(shí)現(xiàn)接粽子小游戲的示例代碼

    基于JS實(shí)現(xiàn)接粽子小游戲的示例代碼

    端午節(jié)馬上就到了,聽說你們公司沒發(fā)粽子大禮包?沒關(guān)系,這里用?JS實(shí)現(xiàn)了一個簡單的接粽子小游戲,能接到多少粽子,完全看你手速,快跟隨小編一起來學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • php顯示當(dāng)前文件所在的文件以及文件夾所有文件以樹形展開

    php顯示當(dāng)前文件所在的文件以及文件夾所有文件以樹形展開

    本文為大家介紹喜愛php如何顯示當(dāng)前文件所在的文件以及文件夾所有文件并以樹形展開,感興趣的朋友可以參考下
    2013-12-12
  • JavaScript實(shí)現(xiàn)頁面高亮操作提示和蒙板

    JavaScript實(shí)現(xiàn)頁面高亮操作提示和蒙板

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)頁面高亮操作提示和蒙板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01

最新評論

古浪县| 汉阴县| 桃园市| 铁力市| 克拉玛依市| 顺平县| 阿鲁科尔沁旗| 托里县| 开江县| 彭山县| 星子县| 抚顺市| 太康县| 团风县| 韩城市| 高雄市| 资兴市| 凯里市| 镇沅| 大厂| 乌兰察布市| 泗阳县| 西昌市| 德庆县| 北川| 甘孜县| 邹城市| 汉川市| 湘潭市| 方城县| 德昌县| 南宫市| 皮山县| 嘉鱼县| 芜湖市| 巧家县| 阳东县| 西和县| 韶关市| 元氏县| 左贡县|