理解JavaScript中的window對象
- 2022 年 7 月 27 日
- 筆記
前言
每個JavaScript環境都有一個全局對象(global object)。在全局範圍內創建的任何變數實際上都是這個對象的屬性,而任何函數都是它的方法。在瀏覽器環境中,全局對象是window
對象,它代表了包含網頁的瀏覽器窗口。
在這篇文章中,我們將介紹Window
對象的一些重要用途:
- 瀏覽器對象模型(Browser Object Model)
- 獲取瀏覽器資訊
- 獲取並使用瀏覽器
history
對象 - 創建並控制瀏覽器窗口
- 獲取螢幕尺寸以及顯示細節
瀏覽器對象模型
瀏覽器對象模型(簡稱BOM)是一個屬性和方法的集合,包含了關於瀏覽器和電腦螢幕的資訊。比如說,我們可以找出哪個瀏覽器正在被用來瀏覽一個頁面,儘管這種辦法不可靠。我們還可以找出它被瀏覽的螢幕尺寸,以及在當前頁面之前已經訪問過哪些頁面。它還可以用於創建彈出式窗口這種相當可疑的做法,如果你喜歡惹惱你的用戶的話。
BOM沒有官方的標準,儘管所有主流瀏覽器都支援許多屬性和方法,但這已經成為了一種事實上的標準。這些屬性和方法是通過window
對象提供的,每一個瀏覽器窗口,tab頁,彈窗,frame以及iframe都具有window
對象。
瀏覽器環境
請記住,JavaScript可以在不同的環境上運行。BOM只在瀏覽器環境中有意義。這意味著其他環境可能沒有window
對象,儘管他們仍有全局對象。比如說,Node.js擁有一個稱為global
的對象。
如果你不知道全局對象的名稱,你可以在全局作用域中使用關鍵字this
來引用全局對象。下面的程式碼提供了一種將變數global
賦值給全局對象的快捷方式:
const global = this;
深入全局變數
全局變數是不使用const
、let
或var
關鍵字創建的變數。全局變數可以在整個程式中進行訪問。
全局變數是全局對象的屬性。在瀏覽器環境中,全局對象就是window
對象。這意味著任何創建的全局變數都是window
對象的屬性,可以從如下示例中看出:
x = 6; // 創建的全局變數
>> 6
window.x // 同一個變數可以作為window對象的一個屬性被訪問
>> 6
// window.x === x
>> true
通常情況下,你應該在不使用window
對象的情況下引用全局變數。這樣可以減少字元輸入,並且你的程式碼在不同的環境中也更容易移植。如果你需要檢查一個全局變數是否已經被定義,則是一個例外。比如說,如果x
沒有被定義,下面的程式碼將會拋出ReferenceError
錯誤:
if (x) {
// do something
}
然而,如果變數作為window
對象的屬性進行訪問,那麼程式碼仍然可以正常運行,window.x
會直接返回false
,意味著程式碼塊將不會被執行:
if (window.x) {
// do something
}
有些函數比如說parseInt()
和isNaN()
,就是全局對象的方法。在瀏覽器環境中,它們就是window
對象的方法。與變數一樣,習慣上省略通過window
對象而直接訪問它們。
對話框
在瀏覽器中,有三個函數用來生成對話框:alert()
,confirm()
以及prompt()
。這些都不是ECMAScript標準的一部分,儘管所有主流瀏覽器都支援它們作為window
對象的方法。
Alert Dialog
window.alert()
會暫停程式的執行,並在對話框中顯示消息。消息被作為參數提供給方法,方法總是返回undefined
:
window.alert('Hello');
>> undefined
Confirm dialog
window.confirm()
方法會停止程式的執行,並顯示一個確認對話框。展示作為參數提供的資訊,並給出確定或取消的選項。如果用戶點擊確定,則返回布爾值true
,如果用戶點擊取消,則返回布爾值false
:
window.confirm('Do you wish to continue?');
>> undefined
Prompt dialog
window.prompt()
方法會停止程式的執行,並顯示一個對話框。展示作為參數提供的資訊,以及一個允許用戶輸入文本的輸入欄位。當用戶點擊確定時,該文本會作為字元串進行返回。如果用戶點擊取消時,將會返回null
:
window.prompt('Please enter your name:');
謹慎使用原生對話框
值得再次強調的是,這些方法會在程式執行過程中讓程式停止執行。這意味著在方法被調用的時刻,一切都將停止處理,直到用戶點擊確認或者取消。如果程式需要同時處理其他東西,或者程式在等待回調函數,那麼這種方式就會造成問題。
在一些場合,這種功能因具備一些優勢從而可以使用。比如說,window.confirm()
對話框可以被用來當做最終確認,檢查用戶是否想要刪除資源。這將阻止程式繼續進行並阻止刪除資源,直到用戶來決定如何處理。
還值得注意的是,大多數瀏覽器允許用戶禁用任意重複出現的對話框,這意味著該功能是不可靠的。
瀏覽器資訊
window
對象有一系列的屬性和方法,這些屬性和方法提供了有關用戶瀏覽器的資訊。
Navigator對象
window
對象有一個屬性叫做navigator
,該屬性返回Navigator
對象的引用。Navigator
對象包含有關正在使用的瀏覽器的資訊。上面的userAgent
屬性將會返回有關正在使用的瀏覽器和作業系統的資訊。比如說,如果運行下面的程式碼,它將顯示我正在使用Mac OS上的Safari 10版本:
window.navigator.userAgent
>>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8"
不過,不要依賴這些資訊,因為用戶可以修改這些資訊,從而偽裝成其他瀏覽器。對返回的字元串也很難有任何意義,因為在某種程度上,所有的瀏覽器都會假裝成其他瀏覽器。
比如說,每個瀏覽器都會在其自身的userAgent
屬性上包含Mozilla
字元串,因為遺留的Netscape兼容性的原因。userAgent
已經從官方標準中廢棄,但是它仍然在所有主流瀏覽器中得到很好的支援。
URL
window.location
是一個對象,該對象包含有關當前頁面URL的資訊。它包含一些屬性,提供關於URL的不同片段的資訊。
href
屬性將完整的URL作為字元串進行返回:
window.location.href
>> "<//www.sitepoint.com/javascript-window-object/>"
該屬性(以及本節其他大多數屬性)是可讀/可寫屬性,這意味著可以通過賦值被更改。如果完成賦值操作,當前頁面將會使用新的屬性值進行重新載入。比如說,輸入下面的程式碼到瀏覽器的控制台中,瀏覽器將會重定向到指定頁面:
window.location.href = '<//www.sitepoint.com/>'
>> "<//www.sitepoint.com/>"
protocol
屬性返回一個描述所使用的協議(比如http
, https
, pop2
, ftp
等等)的字元串。注意字元串的末尾有冒號:
window.location.protocol
>> "https:"
host
屬性返回一個描述當前URL的域名以及埠號的字元串。如果使用的默認埠號80,那麼埠號通常會被省略:
window.location.host
>> "www.sitepoint.com"
hostname
屬性返回一個描述當前URL域名的字元串:
window.location.hostname
>> "www.sitepoint.com"
port
屬性返回一個描述埠號的字元串,如果埠沒有顯式地在URL中聲明,它將返回空字元串:
window.location.port
>> ""
pathname
屬性返回域名後面的路徑字元串:
window.location.pathname
>> "/javascript-window-object/"
search
屬性返回一個以”?”開頭的字元串,後面是查詢字元串參數。如果沒有查詢字元串參數,將會返回空字元串:
window.location.search
>> ""
hash
屬性返回一個以”#”開頭的字元串,後面是片段標識符。如果沒有片段標識符,將返回空字元串:
window.location.hash
>> ""
origin
屬性返回一個字元串,展示當前頁面來源的協議和域名。這個屬性是只讀的,所以不能被改變:
window.location.origin
>> "<//www.sitepoint.com>"
window.location
還具有以下方法:
-
reload()
方法可以用來強制重新載入當前頁面。如果傳遞參數true
,會強制瀏覽器從服務端重新載入頁面,而不是使用快取的頁面。 -
assign()
方法可以用來從參數提供的URL中載入另一個資源。比如說:window.location.assign('<//www.sitepoint.com/>')
-
replace()
方法與assign()
方法作用幾乎相同,除了當前頁面不會存儲於瀏覽器歷史記錄中。所以用戶不能使用返回按鈕進行返回。 -
toString()
方法返回一個包含整個URL的字元串:window.location.toString(); >> "<//www.sitepoint.com/javascript/>"
瀏覽器歷史
window.history
屬性可用於訪問當前瀏覽器會話中任何先前訪問過的頁面的資訊。避免將其與新的HTML5 History API混淆。
window.history.length
屬性顯示在到達當前頁面之前已經訪問了多少個頁面。
window.history.go()
方法可以用於跳轉至指定頁面,0表示跳轉至當前頁面:
window.history.go(1); // 前進一個頁面
window.history.go(0); // 重新載入當前頁面
window.history.go(-1); // 後退一個頁面
還有window.history.forward()
以及window.history.back()
方法,可分別用於前進或後退一個頁面,就好像使用了瀏覽器的前進和後退按鈕。
控制窗口
可以使用window.open()
方法打開一個新的窗口。該方法接收將要打開的頁面URL作為第一個參數,窗口的標題作為第二個參數,以及一系列屬性作為第三個參數。這也可以賦值給一個變數,這樣窗口就可以在以後的程式碼中被引用:
const popup = window.open('<//sitepoint.com>','SitePoint','width=700,height=700,resizable=yes');
close()
方法可用於關閉一個窗口,假設你有一個窗口引用:
popup.close();
也可以使用window.moveTo()
方法移動窗口。該方法接收兩個參數,分別是窗口要移動到的螢幕的X軸和Y軸坐標:
window.moveTo(0,0);
// 移動窗口到螢幕的左上角
你可以使用window.resizeTo()
方法來調整窗口大小。該方法接收兩個參數,用來指定調整後的窗口尺寸的寬度和高度:
window.resizeTo(600,400);
煩人的彈框
這些方法在很大程度上負責給JavaScript一個壞名聲,因為它們被用來創建煩人的彈出式窗口,這些窗口通常包含侵入性的廣告。從可用性的角度來看,調整或移動用戶窗口的大小也是一個壞主意。
許多瀏覽器阻止彈出式窗口,並在某些情況下不允許調用其中的一些方法。例如,如果有一個以上的標籤打開,你就不能調整一個窗口的大小。你也不能移動或調整一個不是用window.open()
創建的窗口的大小。
盡量少的使用這些方法是明智的,所以在使用它們之前要仔細考慮。幾乎總是會有一個更好的替代方案,而一個優秀程式設計師會努力找到它。
螢幕資訊
window.screen
對象包含了關於瀏覽器所顯示的螢幕的資訊。你可以分別使用height
和width
屬性找出螢幕的高度和寬度,單位為像素:
window.screen.height
>> 1024
window.screen.width
>> 1280
availHeight
和availWidth
可用於查找螢幕的高度和寬度,其中不包括任何作業系統的菜單:
window.screen.availWidth
>> 1280
window.screen.availHeight
>> 995
colorDepth
屬性可用於查找用戶顯示器的顏色位深度,儘管除了收集用戶統計數據外,很少有這樣做的用例:
window.screen.colorDepth;
>> 24
更適用於移動平台
螢幕對象對移動設備有更多的用途。它還允許你做一些事情,如關閉設備的螢幕,檢測其方向的變化或將其鎖定在一個特定的方向。
謹慎使用
上一節中所涉及的許多方法和屬性在過去被濫用於可疑的活動,如用戶代理嗅探,或檢測螢幕尺寸以決定是否顯示某些元素。這些做法現在已經被更好的做法所取代了,比如媒體查詢和特徵檢測。
文檔對象
每個window
對象包含一個document
對象。該對象有一系列的屬性和方法,用來處理已經載入到窗口的頁面。document
對象包含一些值得關注的方法。
document.write()
write()
方法只是將一串文本寫到頁面上。如果頁面已經載入,它將徹底替換當前文檔:
document.write('Hello, world!');
這將用字元串Hello, world!
替換整個文檔。可以在字元串中包含HTML,這將成為DOM樹的一部分。例如,下面這段程式碼將創建一個<h1>
標籤節點和一個文本子節點:
document.write('<h1>Hello, world!</h1>');
document.write()
方法也可以在文檔中的<script>
標籤內使用,用於將字元串注入到標記中。這不會覆蓋頁面上的其他HTML。下面的例子將把文本 "Hello, world!"
放在<h1>
標籤內,頁面的其他部分將正常顯示:
<h1>
<script>document.write("Hello, world!")</script>
</h1>
document.write()
的使用是非常不受歡迎的,因為它只能通過在HTML文檔中混合JavaScript來進行使用。仍然有一些極其罕見的合法用途,但一個出色的程式設計師幾乎不需要使用它。
總結
以上就是有關window
對象的所有主要內容,感謝你的閱讀。如果讓你學到了知識,歡迎點贊收藏轉發~