BOM
(瀏覽器對象模型)則無疑纔是真正的核心。window
對象window
,它表示瀏覽器的一個實例。在瀏覽器中window
對象既是經過JavaScript訪問瀏覽器窗口的一個接口,又是ECMAScript規定的Global
對象,所以有權訪問parseInt()
等方法window
對象的屬性和方法。window
對象上定義屬性仍是有一點差異:全局變量不能經過delete
操做符刪除,而直接定義在window
對象上的屬性能夠var age = 29; window.color = "red"; // 在IE < 9 時拋出錯誤,在其餘瀏覽器裏返回 false delete window.age; // 在IE < 9 時拋出錯誤,在其餘瀏覽器裏返回 true delete window.color; console.log(window.age); // 29 console.log(window.color); // undefined
var
語句添加的window
屬性有一個名爲[[Configruable]]的特性,這個特性的值被設置爲false
,所以不可經過delete
刪除。IE8及更早版本在遇到使用delete
刪除window
屬性的語句時,無論該屬性最初如何建立的,都會拋出錯誤,以示警告。window
對象,能夠知道某個可能未聲明的變量是否存在// 這裏會拋出錯誤 oldValue 未定義 var newValue = oldValue; // 這裏不會拋出錯誤,由於這是一次屬性查詢 // newValue的值是 undefined var newValue = window.oldValue;
window
對象,而且保存在frames
集合中。frames
集合中,能夠經過數值索引(從0開始,從左至右,從上到下)或者框架名稱來訪問相應的window
對象。每一個window
對象都有一個name
屬性,其中包含框架的名稱。<html> <head> <title> Frameset Example</title> </head> <frameset rows="160, *"> <frame src="frame.htm" name="topFrame"> <frameset cols="50%, 50%"> <frame src="anotherframe.htm" name="leftFrame"> <frame src="yetanotherframe.htm" name="rightFrame"> </frameset> </frameset> </html>
window.frames[0]
或者window.frames["topFrame"]
來引用上方的框架,不過最好使用top
而非window
。例如 top.frames[0]
top
對象始終指向最高(最外層)的框架,也就是瀏覽器窗口。top
相對的另外一個window
對象是parent
。parent
(父)對象始終指向當前框架的直接上層框架。在某些狀況下parent
有可能等於top
,但在沒有框架的狀況下,parent
必定等於top
。此時他們都是window
用來肯定和修改window
對象位置的屬性和方法有不少。javascript
screenLeft
和 screenTop
屬性,分別用於表示相對屏幕左邊和上邊的位置。screenX
和 screenY
屬性中提供相同的窗口位置信息, Safari, Chrome也同時支持這兩個屬性。screenX
和 screenY
屬性,但與 screenLeft
和 screenTop
並不對應,所以建議你們不要在 Opera中使用。// 肯定 screenLeft 和 screenTop 屬性是否存在 // 存在,是在 IE, Safari, Opera, Chrome // 不然,是在 Firefox中 var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX; var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;
top.screenX
top.screenY
值。即便在頁面因爲被設置了外邊距發生偏移的狀況下,相對於window
對象使用top.screenX
top.screenY
每次也都會返回相同的值。而IE Opera則會給出框架相對於屏幕辯解的精確座標值。moveTo()
和 moveBy()
方法,卻是有可能將窗口的精確地移動到一個新位置。這兩個方法都接受兩個參數// 將窗口移動到屏幕左上角 window.moveTo(0, 0); // 將窗口向下移動100像素 window.moveBy(0, 100); // 將窗口移動到(200, 300) window.moveTo(200, 300); // 將窗口向左移動50像素 window.moveBy(-50, 0);
window
對象使用。跨瀏覽器肯定一個窗口的大小不是一件簡單的事情。html
innerwidth
innerHeight
outerWidth
outerHeight
。outerWidth
outerHeight
返回瀏覽器窗口自己的尺寸(不管是從最外層的window
對象仍是從某個框架訪問)。innerwidth
innerHeight
則表示容器中頁面視圖區的大小(減去邊框寬度)。var pageWidth = window.innerWidth; var pageHeight = window.innerHeight; // document.compatMode 這個屬性將在第10章討論 if (typeof pageWidth != "number") { if (document.compatMode == "CSS1Compat") { pageWidth = document.documentElement.clientWidth; pageHeight = document.documentElement.clientHeight; } else { pageWidth = document.body.clientWidth; pageHeight = document.body.clientHeight; } }
resizeTo()
和 resizeBy()
方法能夠調整瀏覽器窗口的大小。須要注意,這兩個方法也可能被瀏覽器禁用。在Opera和IE7+中默認禁止window
對象使用// 調整到 100 x 100 window.resizeTo(100, 100); // 調整到 200 x 150 window.resizeBy(100, 50); // 調整到 300 x 300 window.resizeTo(300, 300);
window.open()
方法既能夠導航到一個特定的URL,也能夠打開一個新的瀏覽器窗口。接受四個參數:java
_self
, _parent
, _top
, _blank
)// 等同於 <a href="http://www.wrox.com" target="topFrame"></a> window.open("http://www.wrox.com", "topFrame");
window.open()
傳遞的第二個參數並非一個已經存在的窗口或者框架,那麼該方法就會根據在第三個參數位置上傳入的字符串建立一個新窗口或者新標籤。設置 | 值 | 說明 |
---|---|---|
fullscreen | yes/no | 表示瀏覽器窗口是否最大化。僅限IE |
height | 數值 | 表示新窗口的高度。不能小於100 |
width | 數值 | 表示新窗口的寬度。不能小於100 |
left | 數值 | 左座標,不能是負值 |
top | 數值 | 上座標。不能是負值 |
location | yes/no | 表示是否在瀏覽器窗口中顯示地址欄。不一樣瀏覽器的默認值不一樣。若是設置爲no,地址欄可能會隱藏,也可能會禁用,取決於瀏覽器 |
menubar | yes/no | 是否顯示菜單欄。默認no |
resizeable | yes/no | 是能夠拖動窗口大小。默認值no |
scrollbars | yes/no | 是否容許滾動。默認no |
status | yes/no | 是否顯示狀態欄。默認no |
toolbar | yes/no | 是否顯示工具欄。默認no |
window.open()
方法會返回一個指向新窗口的引用,大體與其餘window
對象一致,但咱們能夠進行更多操做控制。數組
window.open()
建立的還口不容許咱們針對朱瀏覽器窗口調整大小或移動位置,但卻容許咱們針對經過window.open()
建立的窗口調整大小或移動位置。var wroxWin = window.open("http://www.wrox.com", "wroxWindow", "height=400,width=400,top=10,left=10,resizable=yes"); // 新建立的window對象有一個opener屬性 // 保存打開它的原始窗口對象 // 而原始窗口不跟蹤打開的新窗口,沒有指向新窗口對象的屬性 console.log(wroxWin.opener == window); // true // 調整大小 wroxWin.resizeTo(500, 500); // 移動位置 wroxWin.moveTo(100, 100); // 關閉新打開的窗口 // 這個方法僅限於經過 window.open() 打開的彈出窗口 // 對於主窗口若是沒有獲得用於的容許是不能關閉它的。 wroxWin.close(); // 彈窗關閉後,窗口的引用仍然還在 // 但除了檢測其closed屬性沒有其餘用處 console.log(wroxWin.closed); // true
window
對象之間須要彼此通訊,那麼新標籤就不能運行在獨立的進程中。null
,即表示在單獨的進程中運行新標籤var wroxWin = window.open("http://www.wrox.com", "wroxWindow", "height=400,width=400,top=10,left=10,resizable=yes"); wroxWin.opener = null;
window.open()
極可能返回null
。此時只要檢查這個返回值就能夠肯定彈窗是否被屏蔽。var wroxWin = window.open("http://www.wrox.com", "_blank"); if (wroxWin == null) { console.log("The popup was blocked!"); }
window.open()
一般會拋出錯誤。所以不但要檢測返回值,還要將對 window.open()
的調用封裝在一個 try-catch
塊中var bloacked = false; try { var wroxWin = window.open("http://www.wrox.com", "_blank"); if (wroxWin == null) { bloacked = true; } } catch (ex) { bloacked = true; } if (blocked) { console.log("The popup was blocked!"); }
// 第一個參數傳遞字符串,不推薦! setTimeout('alert("Hello World!");', 1000); // 推薦的方式 setTimeout(() => { alert("Hello World!"); }, 1000);
var timeoutId = setTimeout(() => { alert("Hello World!"); }, 1000); // 取消執行 clearTimeout(timeoutId);
this
的值在非嚴格模式下 指向 window
,在嚴格模式下是 undefined
。setInterval()
用法與上述相似alert()
, confirm()
, prompt()
方法能夠調用系統對話框向用戶顯示消息。系統對話框與瀏覽器中顯示的網頁沒有關係,不包含HTML,外觀由操做系統和瀏覽器設置決定。打開對話框都是同步和模態的。也就是說,這些對話顯示的時候,代碼會中止執行,而關掉這些對話框又會恢復執行。confim()
返回一個布爾值,表明用戶選擇"ok"仍是"cancel"prompt()
返回一個字符串或者null
,輸入了值並肯定,返回字符串,其餘方法關閉返回null
print()
find()
。沒什麼卵用location
對象location
是最有用的BOM對象之一,它提供了與當前窗口中加載的文檔有關的信息,還提供一些導航功能。location
對象既是window
對象的屬性,也是document
對象的屬性;換言之,window.location
document.location
引用的是同一個對象。屬性名 | 例子 | 說明 |
---|---|---|
hash | "#contents" | 返回 URL 中的hash(#號後跟零或多個字符),若是URL中不包含散列,則返回空字符串 |
host | "www.wrox.com:80" | 返回服務器名稱和端口號(若是有) |
hostname | "www.wrox.com" | 返回服務器名稱不帶端口號 |
href | "http:/www.wrox.com" | 返回當前加載頁面的完整URL。而location對象的toString()方法也返回這個值 |
pathname | "/WileyCDA/" | 返回URL中的目錄或者文件名 |
port | "www.wrox.com" | 返回端口號。若是沒有端口號,返回空字符串 |
protocol | "http:" | 返回頁面使用的協議。一般是 http: https: |
search | "?q=javascript | 返回URL查詢字符串。這個字符串以問號開頭 |
location
對象大多數信息,可是其中訪問URL包含查詢字符串的屬性並不方便。儘管location.search
返回從問號到URL末尾的全部內容,但卻沒有辦法逐個訪問其中的每一個查詢字符串參數。funcction getQueryStringArgs() { // 取得查詢字符串並去掉開頭的問號 var qs = (location.search.length > 0 ? location.search.substring(1) : ""); // 保存數據的對象 var args = {}; // 取得每一項 var items = qs.length ? qs.split("&") : []; var item = null; var name = null; var value = null; // 在for循環中使用 var i = 0; var len = items.length; // 逐個將每一項添加到args對象中 for (var i = 0; i < len; i++) { item = items[i].split("="); name = decodeURIComponent(item[0]); value = decodeURIComponent(item[1]); if (name.length) { args[name] = value; } } return args; }
assign()
方法,併爲其傳遞一個URL。當即打開新的URL並在瀏覽器的歷史記錄中生成一條記錄。若是是將location.href
或window.location
設置爲一個URL值,也會以該值調用assign()
方法。location.assign("http://www.wrox.com"); window.location = "http://www.wrox.com"; location.href = "http://www.wrox.com";
hash
, search
, hostname
, pathname
, prot
屬性設置爲新值來改變URL// 假設初始URL爲 http://www.wrox.com/WileyCDA/ // 將URL修改成 http://www.wrox.com/wileyCDA/#section1 location.hash = "#section1"; // 將URL修改成 http://www.wrox.com/wileyCDA/?q=javascript location.search = "?q=javascript"; // 將URL修改成 http://www.wrox.com/wileyCDA/ location.hostname = "www.yahoo.com" // 將URL修改成 http://www.yahoo.com/mydir/ location.pathname = "mydir" // 將URL修改成 http://www.yahoo.com:8080/wileyCDA/ location.port = 8080;
replace()
方法。這個方法只接受一個參數,即要盜號的URL。雖然結果會致使瀏覽器位置改變,但不會在歷史記錄中生成新記錄。在調用replace()
方法後,用戶不能回到前一個頁面reload()
做用是從新加載當前頁面的顯示。若是不傳參,頁面就會以最有效的方式從新加載。若是頁面上次請求一來並無改變過,頁面就會從瀏覽器緩存中從新加載。若是要強制從服務器從新加載,則須要像下面這樣爲該方法傳遞參數true
reload()
調用以後的代碼可能會也可能不會執行,這要取決於網絡延遲或系統資源等因素。爲此最好將reload()
放在代碼的最後一行navigator
對象navigator
對象表現是一致的,也有一套本身的屬性屬性或方法 | 說明 | IE | Firefox | Safari/Chrome | Opera |
---|---|---|---|---|---|
appCodeName | 瀏覽器的名稱。一般都是Mozilla ,即便在非Mozilla瀏覽器中也是如此 |
3.0+ | 1.0+ | 1.0+ | 7.0+ |
appMinorVersion | 次版本 | 4.0+ | - | - | 9.5+ |
appName | 完整的瀏覽器名稱 | 3.0+ | 1.0+ | 1.0+ | 7.0+ |
appVersion | 瀏覽器的版本。通常不與實際的瀏覽器版本對應 | 3.0+ | 1.0+ | 1.0+ | 7.0+ |
buildID | 瀏覽器變異版本 | - | 2.0+ | - | - |
cookieEnabled | 表示cookie是否啓用 | 4.0+ | 1.0+ | 1.0+ | 7.0+ |
cpuClass | 客戶端計算機中使用的cpu類型 | 4.0+ | - | - | - |
javaEnabled() | 表示當前瀏覽器中是否啓用了java | 4.0+ | 1.0+ | 1.0+ | 7.0+ |
language | 瀏覽器的主語言 | - | 1.0+ | 1.0+ | 7.0+ |
mineTypes | 表示當前瀏覽中註冊的MIME類型數組 | 4.0+ | 1.0+ | 1.0+ | 7.0+ |
onLine | 表示瀏覽器是否鏈接到了因特網 | 4.0+ | 1.0+ | - | 9.5+ |
oscpu | 客戶端計算機的操做系統或使用的CPU | - | 1.5+ | - | - |
platform | 瀏覽器所在的系統平臺 | 4.0+ | 1.0+ | 1.0+ | 7.0+ |
plugins | 瀏覽器中安裝的插件信息的數組 | 4.0+ | 1.0+ | 1.0+ | 7.0+ |
preference | 設置用戶的首選項 | - | 1.5+ | - | - |
product | 產品名稱 如Gecko | - | 1.0+ | 1.0+ | - |
productSub | 關於產品的次要信息 | - | 1.0+ | 1.0+ | - |
registerContentHandler() | 針對特定的MIME類型將一個站點註冊爲處理程序 | - | 2.0+ | - | - |
registerProtocolHandler() | 針對特定的協議將一個站點註冊爲處理程序 | - | 2.0+ | - | - |
securityPolicy | 已經廢棄。安全策略的名稱。爲了與Netscape Navigator4向後兼容而保留下來 | - | 1.0+ | - | - |
systemLanguage | 操做系統的語言 | 4.0+ | - | - | - |
taintEnabled() | 已廢棄。表示是否容許變量被修改。爲了與Netscape Navigator3向後兼容而保留下來 | 4.0+ | 1.0+ | - | 7.0 |
userAgent | 瀏覽器的用戶代碼字符串 | 3.0+ | 1.0+ | 1.0+ | 7.0+ |
userLanguage | 操做系統的默認語言 | 4.0+ | - | - | 7.0+ |
userProfile | 藉以訪問用戶我的信息的對象 | 4.0+ | - | - | - |
vendor | 瀏覽器的品牌 | - | 1.0+ | 1.0+ | - |
vendorSub | 有關供應商的次要信息 | - | 1.0+ | 1.0+ | - |
檢測瀏覽器中是否安裝了特定的插件是一種最多見的檢測歷程。對於非IE瀏覽器,可使用plugins數組來達到這個目的。該數組中的每一項都包含下列屬性。瀏覽器
// 檢測插件(在IE中無效) function hasPlugin(name) { name = name.toLowerCase(); for (var i=0; i < navigator.plugins.length; i++) { if (navigator.plugins[i].name.toLowerCase().indexOf(name) > -1) { return true; } } return false; } // 檢測flash console.log(hasPlugin("Flash")); // 檢測QuickTime console.log(hasPlugin("QuickTime"));
ActiveXObject
類型,並嘗試建立一個特定插件的實例。IE是以COM對象的方式實現插件的,而COM對象使用惟一標識符來標識。所以要想檢測特定的插件,就必須知道其COM標識符,例如Flash的標識符是ShockwaveFlash.ShockwaveFlash
。知道惟一標識符後,就能夠編寫下面的函數來檢測// 檢測IE中的插件 function hasIEPlugin(name) { try { new ActiveXObject(name); return true } catch (ex) { return false; } } // 檢測flash console.log(hasIEPlugin("ShockwaveFlash.ShockwaveFlash")); // 檢測QuickTime console.log(hasIEPlugin("QuickTime.QuickTime"));
// 檢測全部瀏覽器中的Flash function hasFlash() { var result = hasPlugin("Flash"); if (!result) { result = hasIEPlugin("ShockwaveFlash.ShockwaveFlash"); } return result; }
plugins
集合有一個名叫refresh()
的方法,用於刷新plugins
以反映最新安裝的插件。這個方法接收一個參數:表示是否應該從新加載頁面的一個布爾值。若是將這個值設爲true,則會從新加載包含插件的全部頁面;不然只更新plugins
集合,不從新加載頁面。registerContentHandler()
和 registerProtocolHandler()
方法可讓一個站點知名它能夠處理特定類型的信息。隨着RSS閱讀器和在線電子郵件程序的信息,註冊處理程序就爲像使用桌面應用程序同樣默認使用這些在線應用程序提供了一種方式。registerContentHandler()
接收三個參數:緩存
// 要將一個站點註冊爲處理RSS源的處理程序 navigator.registerContentHandler("application/rss+xml", "http://www.somereader.com?feed=%s", "Some Reader");
registerProtocolHandler()
也是三個參數安全
// 要將一個應用程序註冊爲默認的郵件客戶端 navigator.registerProtocolHandler("mailto", "http://www.somemailclient.com?cmd=%s", "Some Mail Client");
history
對象history
對象保存着用戶上網的歷史記錄,從窗口被打開的那一刻算起。由於history
是window
對象的屬性,所以每一個瀏覽器窗口,每一個標籤頁,乃至每一個框架都有本身的history
對象與特定的window
對象關聯。go()
方法能夠在用戶的歷史記錄中任意跳轉,能夠向前向後,接受一個參數整數值或者字符串。// 後退一頁 history.go(-1); // 前進一頁 history.go(1); // 前進兩頁 history.go(2); // 傳入字符串會跳轉到歷史記錄中包含該字符串的第一個位置 // 若是沒有包含的記錄,則什麼都不作 history.go("wrox.com");
back()
和 forward()
。這兩個方法模仿瀏覽器的「後退」「前進」按鈕history
還有一個length
屬性,保存着歷史記錄的數量。包括全部的歷史記錄,即全部向前和向後的記錄。對於加載到窗口、標籤頁或框架中的第一個頁面而言,hitosty.length
等於0if (history.length == 0) { // 這裏應該是用戶打開窗口後的第一個頁面 ... }