window對象是客戶端JavaScript程序的全局對象,包含多數的屬性和方法。
計時器
Window對象包含2個方法可以進行計時操作:
- setTimeout()用來注冊在指定的時間后單次調用的函數,返回一個值,這個值可以傳遞給clearTimeout()用于取消函數的執行。
- setInterval()用來注冊在指定時間后重復調用的函數,返回一個值,這個值可以傳遞給clearInterval()用于取消后續函數的調用。
如果以0毫秒的超時時間來調用setTimeout(),那么指定的函數不會立即執行。相反,會把指定函數放到隊列中,等到前面處理等待狀態的事件處理程序全部執行完成后,再調用它。
瀏覽器定位 location
window對象的location屬性引用的是Location對象,它表示該窗口中當前顯示的文檔的URL。
Document對象的Location屬性也引用到Location對象:
window.location === document.location // 總是返回true
解析URL
Location對象包含一些屬性:protocol, host, hostname, port, pathname和search,分別表示URL的各個部分。hash屬性返回URL中的"片段標識符"(#top
)部分,search屬性返回的是問號之后的URL,這部分通常是某種類型的查詢字符串。
比如,提取URL的搜索字符串中的參數:
function urlArgs() {
var args = {};
// 查找到查詢串,并去掉'?'
var query = location.search.substring(1);
var pairs = query.split("&");
for(var i=0; i < pairs.length; i++) {
var pos = pairs[i].indexOf('=');
if(pos == -1) continue;
var name = pairs[i].substring(0, pos);
var value = pairs[i].substring(pos + 1);
value = decodeURIComponent(value);
args[name] = value;
}
return args;
}
載入新的文檔
- Location對象的assign()方法可以使窗口載入并顯示你指定的URL中的文檔。
- replace()方法也類似,但是它在載入新文檔之前會從瀏覽器歷史中把當前文檔刪除。所有如果檢測到用戶瀏覽器不支持某些特性來顯示功能齊全的版本,可以用location.replace()來載入靜態的HTML版本,防止"后退"按鈕把瀏覽器帶回到原始文檔。
- 可以直接給location進行賦值實現頁面的跳轉:
location = "http://www.example.com"; // location直接賦值實現跳轉
如果將片段標識賦值給location,則不會讓瀏覽器載入新文檔,只會使它滾動到文檔的某個位置。
location = "#top"; // 跳轉到文檔的頂部
同時,location的分解屬性是可寫的,對它們重新賦值也會改變URL的位置。
location.search = "?page=" + (pagenum + 1); // 載入下一個頁面
瀏覽歷史
Window對象的history屬性引用的是該窗口的History對象,History對象是用來把窗口的瀏覽歷史用文檔和文檔狀態列表的形式表示。
- History對象的length屬性表示瀏覽歷史列表中的元素數量,但出于安全考慮,腳本不能訪問已保存的URL。
- History對象的back()和forward()方法與瀏覽器的"后退"和"前進"按鈕一樣。
- History對象還包含一個go()方法,可以在歷史列表中向前或向后跳過任意多個頁。
history.go(-2); // 后退2個歷史記錄,相當于單擊"后退"按鈕2次
注:如果窗口包含多個子窗口(比如<iframe>
元素),子窗口的瀏覽歷史會按時間順序穿插在主窗口的歷史中。這意味著主窗口調用history.back()可能會導致其中一個子窗口往回跳轉到前一個顯示的文檔,但主窗口保持不變。
Navigator對象
Window對象的navigator屬性引用的是包含瀏覽器廠商和版本信息的Navigator對象。
以下4個屬性用于提供關于運行中的瀏覽器的版本信息:
屬性 | 含義 |
---|---|
appName | web瀏覽器的全稱。在IE中為"Microsoft Internet Explorer",在Firefox中為"Netscape",為了兼容現存的瀏覽器嗅探代碼,其他瀏覽器通常也取值為"Netscape"。 |
appVersion | 此屬性通常以數字開始,并跟著瀏覽器廠商和版本信息的詳細字符串。appVersion字符串沒有標準的格式,所以沒有辦法直接用它來判斷瀏覽器的類型。 |
userAgent | 瀏覽器在它的USER-AGENT HTTP頭部中發送的字符串。這個屬性通常包含appVersion中的所有信息,并且也可能包含其他的細節。和appVersion一樣,它也沒有標準格式。但由于這個屬性包含絕大部分信息,因此瀏覽器嗅探代碼通常用它來嗅探。 |
platform | 在其上運行瀏覽器的操作系統(并且可能是硬件)的字符串。 |
onLine | 表示瀏覽器當前是否連接網絡。 |
geolocation | 用于確定用戶位置信息的接口。 |
javaEnabled() | 一個非標準的方法,當瀏覽器可以運行java小程序時返回true。 |
cookieEnable() | 非標準的方法,如果瀏覽器可以保存永久的cookie時,返回true。 |
比如,使用navigator.userAgent來進行瀏覽器嗅探:
//
// "webkit": Safari或Chrome
// "opera": Opera
// "mozilla": FireFox或者其他基于gecko內核的瀏覽器
// "msie": IE
//
var browser = (function() {
var s = navigator.userAgent.toLowerCase();
var match = /(webkit)[ \/]([\w.]+)/.exec(s) ||
/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(s) ||
/(msie)([\w.]+)/.exec(s) ||
!/compatible/.test(s) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(s) ||
[];
return { name: match[1] || "", version: match[2] || "" };
}());
Screen對象
Window對象的screen屬性引用的是Screen對象,它提供有關窗口顯示的大小和可用的顏色信息。
- 屬性width和height指定的是以像素為單位的窗口大小。
- 屬性availWidth和availHeight指定的是實際可用的顯示大小,排除了像桌面任務欄占用的空間。
- 屬性colorDepth指定的是顯示的BPP(bits-per-pixel)值。
可以使用Screen對象來確定web應用是否運行在一個小屏幕的設備上(比如上網本),然后選擇更小的字體和圖片等。
對話框
Window對象提供了4個方法來向用戶顯示對話框,3個簡單方法:alert()、confirm()、prompt()。1個復雜方法:showModalDialog()。
- 方法ocnfirm()和prompt()都會產生阻塞,也就是說,在用戶關掉對話框前,它們不會返回。
- alert()方法也會產生阻塞,但并不總是這樣。
- showModalDialog()顯示一個"模態對話框"(顯示出來就可點選位于其下面的對話框),第1個參數指定對話框HTML內容的URL,第2個參數是一個任意值(數組和對象均可),這個值在對話框里的腳本可以通過window.dialogArguments屬性的值訪問。第3個參數是一個非標準的列表,包含name=value對,可以配置對話框的尺寸或其他屬性。
var p = showModalDialog("multiprompt.html",
["Enter 3D point coordinates", "x", "y", "z"],
"dialogwidth:400; dialogheight:300; resizable:yes");
錯誤處理
Window對象的onerror屬性是一個事件處理程序,當未捕獲的異常傳播到調用棧上時就會調用它。
onerror處理程序是早期的JavaScript的遺物,那里語言核心不包含try/catch異常處理語句,現在很少使用它,使用try/catch即可。
作為Window對象屬性的文檔元素
- 如果在HTML文檔中用id屬性來為元素命名,Window對象會賦予一個屬性,它的名字是id屬性的值,而它們的值指向表示文檔元素的HTMLElement對象,可以通過GetElementById()來獲取。但是,如果Window對象已經具有此名字的屬性時,這就不會發生,比如,id是"history"、"location"等。
- id元素在文檔中必須是唯一的,但是name屬性不一定唯一,如果HTML元素有多于一個相同的name屬性(或者一個元素有name屬性,而另一個元素有相同值的id屬性),則該名稱的隱式全局變量會引用一個類數組對象,這個類數組對象的元素是所有命名的元素。
- 有name或id屬性的
<iframe>
元素是個特殊的例子,為它們創建的變量不會引用表示自身的Element對象,而是引用表示<iframe>
元素創建的嵌套窗體的window對象。
多窗口和窗體
如果瀏覽器窗口包含多個標簽頁,則每一個標簽頁都是獨立的Window對象上下文,而且相互之間互不干擾。由<iframe>
所創建的嵌套瀏覽上下文是用它自己的Window對象所表示。
和相互獨立的標簽頁不同,嵌套的瀏覽上下文之間并不是相互獨立的。在一個窗體中運行的JavaScript程序總是可以看到它的祖先和子孫窗體,盡管腳本查看這些窗體的文檔受到同源策略的限制。
打開窗口
使用Window對象的open()方法可以打開一個新的瀏覽器窗口(或標簽頁,這通常和瀏覽器配置有關)。
- open()的第一個參數是要在新窗口中顯示的文檔URL。
- open()的第二個參數是新打開的窗口的名字。如果指定的是一個已經存在的窗口的名字,則會直接使用已存在的窗口。如果省略此參數,會使用指定的名字"_blank"打開一個新的、未命名的窗口。
- open()的第三個參數是可選的,一個以逗號分隔的列表,包含大小和各種屬性,此參數是非標準的,HTML5規范也主張瀏覽器應該忽略它。
- open()的第四個參數只在第二個參數命名是一個存在的窗口時才有用。它是一個布爾值,聲明了由第一個參數指定的URL是否應該替換掉窗口瀏覽歷史的當前條目(true),默認是不替換。
- open()的返回值是新創建窗口的Window對象。
var w = window.open("smallwin.html", "smallwin",
"width=400, height=350, status=yes, resizable=yes");
- 在新創建的窗口中,opener屬性引用的是打開它的腳本的Window對象。
w.open.opener === w; // true,對于任意窗口w
關閉窗口
就像方法open()打開一個新窗口一樣,方法close()將關閉一個窗口。
- 在表示窗體而不是窗口或標簽頁上的Window對象上執行close()方法不能關閉一個窗體,相反,只能從包含它的文檔中刪除iframe。
- 即使用一個窗口關閉了,代表它的Window對象仍然存在。但是它的closed屬性為true、它的document會是null、它的方法通常也不會再工作。
窗體之間的關系
- 任何窗口和窗體都可以引用為window或self。
- 窗體可以用parent屬性引用包含它的窗口或窗體的Window對象。如果一個窗口是頂級窗口或標簽,而不是窗體,那么其parent屬性引用是這個窗口本身。
- 無論窗體被嵌套了幾層,它的top屬性引用的都是包含它的頂級窗口。
-
<iframe>
元素有contentWidow屬性,引用該窗體的Window對象,同樣,可以進行反向操作--從表示窗體的Window對象來獲取該窗體的<iframe>
元素,使用Window對象的frameElement屬性。窗體中的Window對象的frameElement屬性不是null,但頂級窗口的Window對象的frameElement屬性是null。 - 每個Window對象都有一個frames屬性,它引用自身包含的窗口或窗體,frames屬性引用的是類數組對象,frames[0]引用窗口的第一個子窗體,依次類推。
交互窗口中的JavaScript
每個窗口和窗體都有它自身的執行上下文,以Window作為全局對象。
- 當用構造函數定義一個類,這個類只在一個單獨的窗口定義。如果要在另一個窗口中使用,則需要顯式的引用。
- 和用戶定義的類不同,內置的類(String,Date,RegExp...)都會在所有的窗口中自動預定義。但要注意,每個窗口都有構造函數的一個獨立副本和構造函數對應原型對象的一個獨立副本。這意味著instanceof操作符不能跨窗口使用。例如,當用instanceof來比較窗體B的一個字符串和窗體A的String()構造函數時,結果會是false。