本文轉(zhuǎn)載自博客園的小火柴的藍(lán)色理想。
對話框
??window對象提供幾種彈出框。
alert()
alert()方法接受一個字符串,并將其顯示給用戶并等待用戶關(guān)閉對話框。
confirm()
confirm()方法同樣接收一個字符串,并將其顯示給用戶。返回的布爾值若是true表示單擊OK,false表示單擊Cancel或者右上角的關(guān)閉按鈕。
prompt()
??prompt()方法接收兩個參數(shù),要顯示給用戶的文本提示和文本輸入域的默認(rèn)值(可以是一個空字符串)。如果用戶單擊了OK按鈕,則返回文本輸入域的值;如果用戶單擊了Cancel或者右上角的關(guān)閉按鈕,則該方法返回null。
var isReady = window.prompt("Can you tell me what's your name?","zyb")
console.log(isReady)
print()
??window.print()方法可以用來顯示打印對話框。
BOM
??window提供了BOM(brower object model),用于管理窗口及窗口間的通訊,有的瀏覽器窗口可能包含多個標(biāo)簽頁,每個標(biāo)簽頁都有自己的window對象,通過window下的BOM相關(guān)API可以輕易地獲取窗口位置、窗口大小,管理窗口的打開與關(guān)閉。
location
??location提供了與當(dāng)前窗口中加載的文檔有關(guān)的信息,還提供了一些導(dǎo)航功能。location是一個很特別的對象,因?yàn)樗仁莣indow對象的屬性,也是document對象的屬性,而且還可以單獨(dú)使用。

??如果URL中'?'之前有一個'#',比如
'#text?q=test',那么,location.search得到的就是空字符串'',因?yàn)?code>location.search只有取到'?'后面和'#'前面的內(nèi)容
var URL = 'http://localhost:8080/index.html?q=test#text'
console.log(location.hash) // #text
console.log(location.search) // ?q=test
??使用location對象可以通過很多方式來改變?yōu)g覽器的位置。
assign()
使用assign()方法并為其傳遞一個URL,可以立即打開新URL并在瀏覽器的歷史記錄中生成一條記錄。如果是將location.href或window.location設(shè)置為一個URL值,相當(dāng)于調(diào)用assign()方法。
location.assign("http://baidu.com");
window.location = "http://baidu.com";
document.location = "http://baidu.com";
location.;//最常用
??每當(dāng)修改location的屬性(hash除外),頁面都會以新URL重新加載。
location.hash = "#section1"; //修改hash值
location.search = "?q=javascript"; //修改查詢字符串
location.hostname = "www.baidu.com" //修改主機(jī)名
location.pathname = "mydir" //修改路徑
location.port = "8080" //修改端口號
??通過上述任意一種方式修改URL后,瀏覽器的歷史記錄都會生成一條新記錄,因此用戶通過單擊后退按鈕會導(dǎo)航到前一個頁面。
replace()
通過上述任意一種方式修改URL后,瀏覽器的歷史記錄都會生成一條新記錄,因此用戶通過單擊后退按鈕會導(dǎo)航到前一個頁面。
而要禁用這種行為,可以使用replace()方法,該方法接收一個參數(shù)即要導(dǎo)航到的URL,結(jié)果雖然會導(dǎo)致瀏覽器位置改變,但不會在歷史記錄中生成新記錄,也就是說用戶不能回到前一個頁面。
location.replace("http://baidu.com")
reload()
reload()方法用于重新加載當(dāng)前顯示的頁面。如果調(diào)用reload()方法時不傳遞任何參數(shù),頁面會以最有效的方式重新加載。也就是說,如果頁面自上次請求以來并沒有改變過,頁面就會從瀏覽器緩存中重新加載。如果要強(qiáng)制從服務(wù)器重新加載,則需要傳遞參數(shù)true
位于reload()調(diào)用之后的代碼可能會也可能不會執(zhí)行,這要取決于網(wǎng)絡(luò)延遲或系統(tǒng)資源等因素,為此,最好將reload()放在代碼的最后一行。
//有可能從緩存中加載
location.reload();
//從服務(wù)器重新加載
location.reload(true);
??[注意]千萬不要在頁面中直接使用location.reload()方法,此方法會造成頁面的無限刷新。因?yàn)轫撁鎰偧虞d完成,遇到該方法,則重新加載頁面,又遇到該方法,則又加載頁面,從而造成頁面的無限刷新。
hashchange
HTML5新增了hashchange事件,以便在URL的參數(shù)列表(及URL中“#”號后面的所有字符串)發(fā)生變化時通知開發(fā)人員。之所以新增這個事件,是因?yàn)樵贏jax應(yīng)用中,開發(fā)人員經(jīng)常要利用URL參數(shù)列來保存狀態(tài)或?qū)Ш叫畔ⅰ?br>
??必須要把hashchange事件監(jiān)聽函數(shù)添加給window對象,URL參數(shù)的hash值變化就會調(diào)用它,此時瀏覽器傳入的事件對象e應(yīng)該額外包含兩個屬性:oldURL和newURL。這兩個屬性分別保存著參數(shù)列表變化前后的完整URL。
window.onhashchange = function(e){
console.log(e.oldURL,e.newURL);
}
??[注意]所有的IE瀏覽器都不支持oldURL和newURL這兩個屬性,讓我們來做兼容性處理。
(function(window) {
if ( "onhashchange" in window.document.body ) { return; }
var location = window.location;
var oldURL = location.href;
var oldHash = location.hash;
// 每隔100毫秒檢查一下URL的hash
setInterval(function() {
var newURL = location.href;
var newHash = location.hash;
if ( newHash != oldHash && typeof window.onhashchange === "function" ) {
window.onhashchange({
type: "hashchange",
oldURL: oldURL,
newURL: newURL
});
oldURL = newURL;
oldHash = newHash;
}
}, 100);
})(window);
history
??history對象保存著用戶上網(wǎng)的歷史記錄,從窗口被打開的那一刻算起。由于安全方面的考慮,開發(fā)人員無法得到用戶歷史記錄的URL,但可以在利用history提供的API在不知道實(shí)際URL的情況下實(shí)現(xiàn)后退和前進(jìn)。
length
history.length屬性保存著歷史記錄的URL數(shù)量。初始時,該值為1。如果當(dāng)前窗口先后訪問了三個網(wǎng)址,history.length屬性等于3。
go
使用go()方法可以在用戶的歷史記錄中任意跳轉(zhuǎn)。這個方法接收一個參數(shù),表示向后或向前跳轉(zhuǎn)的頁面數(shù)的一個整數(shù)值。負(fù)數(shù)表示向后跳轉(zhuǎn)(類似于后退按鈕),正數(shù)表示向前跳轉(zhuǎn)(類似于前進(jìn)按鈕)。
//后退一頁
history.go(-1)
//前進(jìn)一頁
history.go(1);
//前進(jìn)兩頁
history.go(2);
back
back()方法用于模仿瀏覽器的后退按鈕,相當(dāng)于history.go(-1)。
forward()
forward()方法用于模仿瀏覽器的前進(jìn)按鈕,相當(dāng)于history.go(1)。
??如果移動的位置超出了訪問歷史的邊界,以上三個方法并不報錯,而是靜默失敗 。
[注意]使用歷史記錄時,頁面通常從瀏覽器緩存之中加載,而不是重新要求服務(wù)器發(fā)送新的網(wǎng)頁。
pushState()
??history.pushState()方法向?yàn)g覽器歷史添加了一個狀態(tài)。pushState()方法帶有三個參數(shù):一個狀態(tài)對象、一個標(biāo)題(現(xiàn)在被忽略了)以及一個可選的URL地址。
history.pushState(state, title, url);
state object —— 狀態(tài)對象是一個由pushState()方法創(chuàng)建的、與歷史紀(jì)錄相關(guān)的JS對象。當(dāng)用戶定向到一個新的狀態(tài)時,會觸發(fā)popstate事件。事件的state屬性包含了歷史紀(jì)錄的state對象。如果不需要這個對象,此處可以填null。
title —— 新頁面的標(biāo)題,但是所有瀏覽器目前都忽略這個值,因此這里可以填null。
url —— 這個參數(shù)提供了新歷史紀(jì)錄的地址。新url必須和當(dāng)前url在同一個域,否則,pushState()將丟出異常。這個參數(shù)可選,如果它沒有被特別標(biāo)注,會被設(shè)置為文檔的當(dāng)前url。
??假定當(dāng)前網(wǎng)址是example.com/1.html,使用pushState方法在瀏覽記錄(history對象)中添加一個新記錄。
var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
??添加上面這個新記錄后,瀏覽器地址欄立刻顯示example.com/2.html,但并不會跳轉(zhuǎn)到2.html,甚至也不會檢查2.html是否存在,它只是成為瀏覽歷史中的最新記錄。假如這時訪問了google.com,然后點(diǎn)擊了倒退按鈕,頁面的url將顯示2.html,但是內(nèi)容還是原來的1.html。再點(diǎn)擊一次倒退按鈕,url將顯示1.html,內(nèi)容不變。
總之,pushState方法不會觸發(fā)頁面刷新,只是導(dǎo)致history對象發(fā)生變化,地址欄的顯示地址發(fā)生變化。
如果pushState的url參數(shù),設(shè)置了一個新的錨點(diǎn)值(即hash),并不會觸發(fā)hashchange事件,即使新的URL和舊的只在hash上有區(qū)別。
??如果設(shè)置了一個跨域網(wǎng)址,則會報錯。這樣設(shè)計的目的是,防止惡意代碼讓用戶以為他們是在另一個網(wǎng)站上。
// 報錯
history.pushState(null, null, 'https://twitter.com/hello');
replaceState()
history.replaceState()方法的參數(shù)與pushState方法一模一樣,不同之處在于replaceState()方法會修改當(dāng)前歷史記錄條目而并非創(chuàng)建新的條目。
??假定當(dāng)前網(wǎng)頁是example.com/example.html
history.pushState({page: 1}, 'title 1', '?page=1');
history.pushState({page: 2}, 'title 2', '?page=2');
history.replaceState({page: 3}, 'title 3', '?page=3');
history.back()
// url顯示為http://example.com/example.html?page=1
history.back()
// url顯示為http://example.com/example.html
history.go(2)
// url顯示為http://example.com/example.html?page=3
state
history.state屬性返回當(dāng)前頁面的state對象,
history.pushState({page: 1}, 'title 1', '?page=1');
history.state// { page: 1 }
popstate事件
每當(dāng)同一個文檔的瀏覽歷史(即history對象)出現(xiàn)變化時,就會觸發(fā)popstate事件。
需要注意的是,僅僅調(diào)用pushState方法或replaceState方法,并不會觸發(fā)該事件,只有用戶點(diǎn)擊瀏覽器倒退按鈕和前進(jìn)按鈕,或者使用JS調(diào)用back()、forward()、go()方法時才會觸發(fā)。另外,該事件只針對同一個文檔,如果瀏覽歷史的切換,導(dǎo)致加載不同的文檔,該事件也不會觸發(fā)。
使用的時候,可以為popstate事件指定回調(diào)函數(shù)。這個回調(diào)函數(shù)的參數(shù)是一個event事件對象,它的state屬性指向pushState和replaceState方法為當(dāng)前URL所提供的狀態(tài)對象(即這兩個方法的第一個參數(shù))。
window.onpopstate = function (event) {
console.log('location: ' + document.location);
console.log('state: ' + JSON.stringify(event.state));
};
screen
??screen對象用來表明客戶端的能力,其中包括瀏覽器窗口外部的顯示器的信息,如像素高度和寬度等。
屬性 說明
height 屏幕的像素高度
width 屏幕的像素寬度
availHeight 屏幕的像素高度減去系統(tǒng)部件高度之后的值(只讀)
availWidth 屏幕的像素寬度減去系統(tǒng)部件寬度之后的值(只讀)
left 當(dāng)前屏幕距左邊的像素距離[firefox返回0,chrome和IE不支持]
top 當(dāng)前屏幕距上方的像素距離[firefox返回0,chrome和IE不支持]
availLeft 未被系統(tǒng)部件占用的最左側(cè)的像素值(只讀)[chrome和firefox返回0,IE不支持]
availTop 未被系統(tǒng)部件占用的最上方的像素值(只讀)[chrome和firefox返回0,IE不支持]
bufferDepth 讀、寫用于呈現(xiàn)屏外位圖的位數(shù)[IE返回0,chrome和firefox不支持]
colorDepth 用于表現(xiàn)顏色的位數(shù)(只讀)[IE8-返回32,其他瀏覽器返回24]
pixelDepth 屏幕的位深(只讀)[IE8-不支持,其他瀏覽器返回24]
deviceXDPI 屏幕實(shí)際的水平DPI(只讀)[IE返回96,chrome和firefox不支持]
deviceYDPI 屏幕實(shí)際的垂直DPI(只讀)[IE返回96,chrome和firefox不支持]
logicalXDPI 屏幕邏輯的水平DPI(只讀)[IE返回96,chrome和firefox不支持]
logicalYDPI 屏幕邏輯的垂直DPI(只讀)[IE返回96,chrome和firefox不支持]
updateInterval 讀、寫以毫秒表示的屏幕刷新時間間隔[IE返回0,chrome和firefox不支持]
fontSmoothingEnabled 是否啟用了字體平滑(只讀)[IE返回true,chrome和firefox不支持]
navigator
??navigator對象現(xiàn)在已經(jīng)成為識別客戶端瀏覽器的事實(shí)標(biāo)準(zhǔn),navigator對象是所有支持JS的瀏覽器所共有的。
屬性 說明
appCodeName 瀏覽器名稱[所有瀏覽器都返回Mozilla]
userAgent 瀏覽器的用戶代理字符串
appVersion 瀏覽器版本
appMinorVersion 次版本信息[IE返回0,chrome和firefox不支持]
platform 瀏覽器所在的系統(tǒng)平臺[所有瀏覽器都返回Win32]
plugins 瀏覽器中安裝的插件信息的數(shù)組
mimeTypes 在瀏覽器中注冊的MIME類型數(shù)組
language 瀏覽器主語言[IE10-不支持,其他瀏覽器返回zh-CN]
systemLanguage 操作系統(tǒng)語言[IE返回zh-CN,chrome和firefox不支持]
userLanguage 操作系統(tǒng)默認(rèn)語言[IE返回zh-CN,chrome和firefox不支持]
product 產(chǎn)品名稱[IE10-不支持,其他瀏覽器返回Gecko]
productSub 產(chǎn)品次要信息[IE不支持,chrome返回20030107,firefox返回20100101]
vendor 瀏覽器品牌[chrome返回Google Inc.,IE和firefox不支持]
onLine 是否連接因特網(wǎng)[IE根據(jù)實(shí)際情況返回true或false,chrome和firefox始終返回true]
cookieEnabled 表示cookie是否啟用[所有瀏覽器都返回true]
javaEnabled 是否啟用java[IE8-瀏覽器返回{},其他瀏覽器返回function javaEnabled()]
buildID 瀏覽器編譯版本[firefox返回20170125094131,chrome和IE不支持]
cpuClass 計算機(jī)使用的CPU類型[IE返回x86,chrome和firefox不支持]
oscpu 操作系統(tǒng)或使用的CPU[firefox返回Windows NT 10.0; WOW64,chrome和IE不支持]
檢測插件
name:插件的名字
description:插件的描述
filename:插件的文件名
length:插件所處理的MIME類型數(shù)量
頁面性能
??頁面性能一直都是Web開發(fā)人員比較關(guān)注的領(lǐng)域。但在實(shí)際應(yīng)用中,度量頁面性能的指標(biāo),之前都是通過JS的Date對象的。Web Timing API的出現(xiàn)改變了這個局面,讓開發(fā)人員通過JS就能使用瀏覽器內(nèi)部的度量結(jié)果,給出了頁面加載和渲染過程的很多信息,對性能優(yōu)化非常有價值。
??Web計時機(jī)制的核心是window.performance對象。對頁面的所有度量信息,包括那些規(guī)范中已經(jīng)定義的和將來才能確定的,都包含在這個對象里面。performance對象包括navigation和timing對象,以及chrome擴(kuò)展的memory對象,還包括getEntries()和now()兩個方法。
memory
??memory屬性是chrome擴(kuò)展的對象,只有chrome瀏覽器支持,包含以下三個屬性:
jsHeapSizeLimit表示內(nèi)存大小限制
totalJSHeapSize表示可使用的內(nèi)存
usedJSHeapSize表示JS對象占用的內(nèi)存
navigation
??performance.navigation屬性是一個對象,包含著與頁面導(dǎo)航有關(guān)的redirectCount和type這兩個屬性。
其中redirectCount表示頁面加載前的重定向次數(shù);而type是一個數(shù)值常量,表示剛剛發(fā)生的導(dǎo)航類型。
timing
??performance.timing屬性也是一個對象,但這個對象的屬性都是時間戳,不同的事件會產(chǎn)生不同的時間值。
??通過timing屬性的這些時間值,就可以全面了解頁面在被加載到瀏覽器的過程中都經(jīng)歷了哪些階段,而哪些階段可能是影響性能的瓶頸。

【重定向時間】
times.redirect = timing.redirectEnd - timing.redirectStart;
console.log(times.redirect);//0
【DNS查詢時間】
times.lookupDomain = timing.domainLookupEnd - timing.domainLookupStart;
console.log(times.lookupDomain);//1
【TCP握手時間】
times.connect = timing.connectEnd - timing.connectStart;
console.log(times.connect);//48
【HTTP響應(yīng)時間】
通過瀏覽器發(fā)出HTTP請求,到瀏覽器接受完HTTP響應(yīng)的時間。
times.request = timing.responseEnd - timing.requestStart;
console.log(times.request);//182
getEntries()
??getEntries()方法將返回一個數(shù)組,包含了頁面中所有的HTTP資源請求。
now()
??now()方法返回從頁面初始化到調(diào)用該方法時的毫秒數(shù)。
??performance.now()與Date.now()不同的是,返回了以微秒為單位的時間,更加精準(zhǔn)。
Date.now()會受系統(tǒng)程序執(zhí)行阻塞的影響不同,performance.now()的時間是以恒定速率遞增的,不受系統(tǒng)時間的影響(系統(tǒng)時間可被人為或軟件調(diào)整)。
Date.now()輸出的是UNIX時間,即距離1970年1月1日0點(diǎn)的時間,而performance.now()輸出的是相對于performance.timing.navigationStart(頁面初始化)的時間。
定時器
定時器的應(yīng)用
??使用定時器來調(diào)整事件發(fā)生順序。
??【1】網(wǎng)頁開發(fā)中,某個事件先發(fā)生在子元素,然后冒泡到父元素,即子元素的事件回調(diào)函數(shù),會早于父元素的事件回調(diào)函數(shù)觸發(fā)。如果,我們先讓父元素的事件回調(diào)函數(shù)先發(fā)生,就要用到setTimeout(f, 0)
<div id="myDiv" style="height: 100px;width: 100px;background-color: pink;"></div>
<script>
myDiv.onclick = function(){
alert(0);
}
document.onclick = function(){
alert(1);
}
</script>
<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ā)。
<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取不到最新輸入的那個字符。
<input type="text" id="myInput">
<script>
myInput.onkeypress = function(event) {
setTimeout(function(){
myInput.value = myInput.value.toUpperCase();
});
}
</script>
requestAnimationFrame
??setTimeout和setInterval的問題是,它們都不精確。它們的內(nèi)在運(yùn)行機(jī)制決定了時間間隔參數(shù)實(shí)際上只是指定了把動畫代碼添加到瀏覽器UI線程隊列中以等待執(zhí)行的時間。如果隊列前面已經(jīng)加入了其他任務(wù),那動畫代碼就要等前面的任務(wù)完成后再執(zhí)行。
??requestAnimationFrame采用系統(tǒng)時間間隔,保持最佳繪制效率,不會因?yàn)殚g隔時間過短,造成過度繪制,增加開銷;也不會因?yàn)殚g隔時間太長,使用動畫卡頓不流暢,讓各種網(wǎng)頁動畫效果能夠有一個統(tǒng)一的刷新機(jī)制,從而節(jié)省系統(tǒng)資源,提高系統(tǒng)性能,改善視覺效果。
特點(diǎn)
??【1】requestAnimationFrame會把每一幀中的所有DOM操作集中起來,在一次重繪或回流中就完成,并且重繪或回流的時間間隔緊緊跟隨瀏覽器的刷新頻率。
【2】在隱藏或不可見的元素中,requestAnimationFrame將不會進(jìn)行重繪或回流,這當(dāng)然就意味著更少的CPU、GPU和內(nèi)存使用量。
【3】requestAnimationFrame是由瀏覽器專門為動畫提供的API,在運(yùn)行時瀏覽器會自動優(yōu)化方法的調(diào)用,并且如果頁面不是激活狀態(tài)下的話,動畫會自動暫停,有效節(jié)省了CPU開銷。
使用
??requestAnimationFrame的用法與setTimeout很相似,只是不需要設(shè)置時間間隔而已。requestAnimationFrame使用一個回調(diào)函數(shù)作為參數(shù),這個回調(diào)函數(shù)會在瀏覽器重繪之前調(diào)用。它返回一個整數(shù),表示定時器的編號,這個值可以傳遞給cancelAnimationFrame用于取消這個函數(shù)的執(zhí)行。
??cancelAnimationFrame方法用于取消定時器。
<div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
<button id="btn">run</button>
<script>
var timer;
btn.onclick = function(){
myDiv.style.width = '0';
cancelAnimationFrame(timer);
timer = requestAnimationFrame(function fn(){
if(parseInt(myDiv.style.width) < 500){
myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
myDiv.innerHTML = parseInt(myDiv.style.width)/5 + '%';
timer = requestAnimationFrame(fn);
}else{
cancelAnimationFrame(timer);
}
});
}
</script>
精確倒計時
??由定時器的運(yùn)行機(jī)制,我們知道每間隔1000ms去改變時間的作法并不可靠。更精確地做法,應(yīng)該是與系統(tǒng)的運(yùn)行時間作為參照,倒計時的時間變化與系統(tǒng)的時間變化同步,達(dá)到精確倒計時的效果。
<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>
<script>
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;
//原始系統(tǒng)時間值
var timeOri = (new Date()).getTime();
//現(xiàn)在所剩時間值
var setNow;
cancelAnimationFrame(timer);
timer = requestAnimationFrame(function fn(){
//當(dāng)前系統(tǒng)時間值
var timeNow = (new Date()).getTime();
//使系統(tǒng)時間的差值與設(shè)置時間的差值相等,來獲得正常的時間變化
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 = '計時結(jié)束';
for(var i = 0; i < 3; i++){
myDiv.getElementsByTagName('input')[i].removeAttribute('disabled');
}
setTimeout(function(){
btn.innerHTML = '確定';
},1000)
}
})
}
</script>
web worker
??web worker是HTML5為JS提供的多線程解決方案,可以將一些大計算量的代碼交由web worker運(yùn)行從而避免阻塞用戶界面,在執(zhí)行復(fù)雜計算和數(shù)據(jù)處理時,這個API非常有用。
??使用Web Worker有以下幾點(diǎn)限制:
- 同域限制。子線程加載的腳本文件,必須與主線程的腳本文件在同一個域。
- DOM限制。子線程所在的全局對象,與主進(jìn)程不一樣,它無法讀取網(wǎng)頁的DOM對象,即document、window、parent這些對象,子線程都無法得到。(但是,navigator對象和location對象可以獲得。)
- 腳本限制。子線程無法讀取網(wǎng)頁的全局變量和函數(shù),也不能執(zhí)行alert和confirm方法,不過可以執(zhí)行setInterval和setTimeout,以及使用XMLHttpRequest對象發(fā)出AJAX請求
- 文件限制。子線程無法讀取本地文件,即子線程無法打開本機(jī)的文件系統(tǒng)(file://),它所加載的腳本,必須來自網(wǎng)絡(luò)。
??從以上限制可以看出,web worker的設(shè)計目的是能夠執(zhí)行處理器密集型的運(yùn)算而不會阻塞UI線程,計算可以在獨(dú)立的子線程中進(jìn)行,只是在計算完成之后將結(jié)果發(fā)回主線程,并不會影響到主線程的代碼執(zhí)行。因此,利用web worker我們可以在前端執(zhí)行一些復(fù)雜的大量運(yùn)算而不會影響頁面的展示。