ECMAScript是JavaScript的核心,而BOM
(瀏覽器對象模型,Browser Object Model)是在Web中使用JavaScript的核心。javascript
在BOM
對象中,window
對象是最頂層對象,在瀏覽器環境中它是一個Global
全局對象,其它對象是window
對象的子對象(屬性)。BOM
主要用於管理瀏覽器窗口及窗口之間的通信。下面是BOM
對象的組成結構。html
window
是BOM
的核心對象,表示瀏覽器的一個實例。有雙重角色,便是經過JavaScript訪問瀏覽器窗口的一個接口,又是ES
規定的Global
對象。這意味着在網頁中定義的任何一個對象、變量和函數,都以window
做爲其Global
對象。java
var age = 29; function sayAge() { console.log(this.age); } console.log(window.age); // 29 sayAge(); // 29 window.sayAge(); // 29
如上所示,在全局做用域中定義的變量和函數都被自動歸在了window
對象名下。而sayAge()
存在於全局做用域中,方法中的this.age
被映射到window.age
,所以顯示的仍然是正確的結果。跨域
然而,定義的全局變量不能經過delete
操做符刪除,定義在window
對象上的屬性卻能夠。數組
window
除了location
、navigator
、screen
、history
和document
外,還有一些屬性。瀏覽器
window.console
:返回Console
對象的引用,能夠向瀏覽器控制檯輸出日誌信息。僅用於調試,不該該給用戶呈現。(只讀)window.frames
:數組對象,列出當前窗口的全部直接子窗口。(只讀)window.frameElement
:當前窗口嵌入另外一個窗口(嵌入<object>、<iframe>
),若是當前窗口是頂層,返回null
。(只讀)window.innerHeight
:窗口的視圖可見高度(單位:像素),也包括滾動條高度。(只讀)window.innerWidth
:窗口的視圖可見寬度(單位:像素),也包括滾動條的寬度。(只讀)window.length
:當前窗口中包含框架數量。框架爲<frame>
與<iframe>
。(只讀)window.locationbar
:檢查visibility
屬性的地址欄對象,用來表示是否可見。(只讀)window.localStorage
:訪問Document
源的對象Storage
;將數據存儲在瀏覽器會話中。相似sessionStorage
,但數據可長期保留;而頁面會話結束時,sessionStorage
數據會清除。(只讀)window.menubar
:檢查visibility
屬性的菜單欄對象,用來表示是否可見。(只讀)window.outerHeight
:整個瀏覽器窗口的高度(單位:像素)。(只讀)window.outerWidth
:整個瀏覽器窗口的寬度(單位:像素)。(只讀)window.parent
:當前窗口或子窗口的父窗口的引用。(只讀)window.personalbar
:檢查visibility
屬性的我的工具欄對象,用來表示是否可見。(只讀)window.scrollX
:頁面水平方向滾動距離(單位:像素),window.pageXOffset
是別名。(只讀)window.scrollY
:頁面垂直方向已滾動距離(單位:像素),window.pageYOffset
是別名。(只讀)window.scrollbars
:檢查visibility
屬性的滾動條對象,用來表示是否可見。(只讀)window.self
:指向當前window
對象的引用。window.sessionStorage
:容許訪問當前源的sessionStorage
對象。與localStorage
類似,不一樣在於sessionStorage
在頁面會話結束時清除,而localStorage
沒有過時時間。window.top
:窗口層級最頂層窗口的引用。window.window
:window
對象自己。介紹了一些window
的屬性,下面咱們看一下關於window
的方法。緩存
window
有三種消息框:警告框 alert
、確認框confirm
和提示框prompt
。安全
window.alert(message)
會顯示一個警告對話框,上面顯示有指定的文本內容以及一個肯定按鈕。例如window.alert("警告框來襲");
的顯示以下:服務器
window.confirm(message)
是一個具備可選消息的模態框。用於驗證是否接受用戶操做的確認框。cookie
var result = window.confirm("你要離開嗎?"); if (result) { // 按下肯定後執行的操做 console.log("肯定"); } else { // 按下取消後執行的操做 console.log("取消"); }
運行結果:
window.prompt(text, value)
是用於顯示文字信息提示用戶輸入文字的提示框。
text
參數爲提示用戶輸入信息的提示內容,可省略。value
參數爲文本輸入框中的默認值,可省略。var result = window.prompt("你的生日是何時的?", "1997-01-01"); if (result == "2011-10-23") { alert("你和我生日同樣耶!"); }
效果以下:
點擊肯定後,文本輸入框中文字被返回。若是爲空,則返回一個空字符串。點擊取消後,返回null
。
三個方法都具備堵塞效應,一旦彈出對話框,整個頁面就暫停執行,等待用戶作出反應。
window
還有幾種方法控制窗口。例如open()
、close()
、stop()
、moveBy()/moveTo()
、resizeBy()/resizeTo()
。下面介紹一下他們的功能。
window.open(url, target, features, replace)
方法用於建立新的窗口。
url
參數爲新窗口加載的URL
。target
參數爲新窗口的名字。每一個窗口都有一個window.name
,這裏能夠指定窗口用於彈窗,若是不存在,新建窗口。這個名字可用做<a>
或<form>
的屬性target
的值。字符串中不能含有空白字符。注意:target
不是新窗口標題。features
參數爲字符串值,內容用逗號分隔,參數不能有空格,例如width=200,height=100
。var params = 'scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,width=0,height=0,left=-1000,top=-1000'; window.open('/', 'test', params);
features
能夠設置的值有:
left/top
:新窗口的最左邊(left
)與最頂部(top
)的距離(單位:像素)。新窗口可見,不能設置在屏幕之外。width/height
:新窗口的寬度和高度(單位:像素)。寬高不得小於100
。outerWidth/outerHeight
:整個瀏覽器窗口的寬高。(單位:像素)。寬高不得小於100
。menubar
:是否顯示菜單欄。toolbar
:是否顯示工具欄。location
是否顯示地址欄。personalbar
:是否顯示用戶安裝的工具欄。status
:是否顯示狀態欄。resizable
:新窗口是否可調整大小。scrollbars
:是否出現滾動條。titlebar
:是否顯示標題欄。close
:是否顯示關閉按鈕。同源策略,窗口只可訪問相同協議下的內容(相同協議://domain:port
)。
window.close()
方法用於關閉當前窗口,通常只用來關閉window.open()
方法新建的窗口。使用window.closed
屬性來判斷窗口是否被關閉。
在當前窗口中關閉窗口:
window.close();
window.stop()
方法等同於單擊瀏覽器的中止按鈕。因爲腳本加載順序,該方法不能阻止已經包含在加載中的文檔,但能阻止圖片、新窗口和延遲加載的對象的加載。
window.stop();
window.moveBy(deltaX, deltaY)
方法根據指定的值,移動當前窗口。
deltaX
:窗口在水平方向移動的像素值。deltaY
:窗口在垂直方向移動的像素值。window.moveTo(x, y)
方法將當前窗口移動到指定的座標位置。
x
:水平方向移動的橫座標y
:豎直方向移動的縱座標moveBy()
產生的是相對移動,moveTo()
產生的是絕對移動。
當符合下列狀況時,普通網頁中的JavaScript沒法經過調用該函數來移動瀏覽器窗口:
window.open
方法建立的;window.resizeBy(xDelta, yDelta)
方法用於調整窗口的大小。
xDelta
:窗口水平方向變化的像素值。yDelta
:窗口垂直方向變化的像素值。window.resizeTo(aWidth, aHeight)
方法用於調整窗口的大小。
aWidth
:整數,表示新的outerWidth
(單位:像素)。aHeight
:整數,表示新的outerHeight
(單位:像素)。resizeBy()
相對大小方式調整窗口大小,resizeTo()
絕對大小方式調整窗口大小。
依據下面的規則,普通網頁中的JavaScript沒法經過調用該函數來調整瀏覽器窗口大小:
window.open
建立的窗口或Tab
的大小;Tab
時,沒法設置窗口的大小。window.scroll()
滾動窗口至文檔中的特定位置, window.scrollBy()
按窗口指定偏移量滾動文檔, window.scrollTo()
滾動窗口至文檔中的特定位置。
上面的三個方法的參數均可以是x-coord
和y-coord
兩個參數,或者options
一個參數。
x-coord
:水平方向像素點橫座標。y-coord
:垂直方向像素點縱座標。或者
options
:一個ScrollToOptions
字典。// 在橫軸上移動到第100個像素置於窗口左邊,在縱軸上移動到第100個像素置於窗口頂部 window.scroll(100, 100); // 或者 window.scroll({ top: 100, left: 100, behavior: 'smooth' });
options
有三個屬性:
top
:垂直方向滾動的像素值left
:水平方向滾動的像素值behavior
:滾動方式,smooth
、instant
和auto
,默認值auto
。寫法也同樣,可是功能不同。window.scrollBy()
滾動指定的距離,window.scroll()
滾動至文檔中的絕對位置,window.scrollTo()
實際上和window.scroll()
方法是相同的。
window.print()
方法打開打印對話框打印當前文檔。
在開發項目中,有網頁提供打印服務的話,咱們能夠在頁面中設置一個按鈕,調用打印功能;但在以前,咱們須要判斷是否支持打印功能。
if (typeof window.print === 'function') { // 支持打印功能 document.getElementById('printLink').onclick = function () { window.print(); } }
使用window.focus()
和window.blur()
方法能夠是窗口得到或失去焦點。
還有一些方法,這裏就不介紹了。
location
對象提供當前窗口中加載的文檔有關信息,還提供了一些導航功能。便是window
對象的屬性,也是document
對象的屬性。還能夠解析URL
。下面列出一些location
的屬性。
location.href
:完整的URL
值,容許更新。location.origin
:域名標準形式。包含協議、域名、端口號。location.protocol
:當前URL
的協議,包括冒號(:
)。location.host
:域名,包含:
後面的端口號。location.hostname
:域名,不包括端口號。location.port
:端口號。location.pathname
:URL
中路徑的部分,從/
開始。location.search
:URL
參數部分,從問號?
開始。location.hash
:塊標識符部分,從#
開始。location.username
:URL
域名前的用戶名。location.password
:URL
域名前的密碼。只有origin
屬性是隻讀的,其它屬性均可寫。
咱們給出一個網址http://localhost:8088/mall/?page=1&userid=2#part=top
,使用上面的屬性來獲取它。
location.href; // http://localhost:8088/mall/?page=1&userid=2#part=top location.origin; // http://localhost:8088 location.protocol; // http: location.host; // localhost:8080 location.hostname; // localhost location.port; // 8088 location.pathname; // /mall/ location.search; // ?page=1&userid=2 location.hash; // #part=top
然而location.search
獲取的是全部內容,沒辦法逐個獲取每一個查詢字符串參數。咱們能夠建立一個函數用以解析並返回包含全部參數的對象。
function getQueryArgs() { // 取的查詢字符串並去掉開頭問號 var qa = (location.search.length > 0 ? location.search.substring(1) : ""), // 保存數據的對象 args = {}, // 取的每一項 items = qa.length ? qa.split("&") : [], // 每一項和該項的鍵值 item = null,name = null,value = null, len = items.length; // 逐個將每一項添加到args對象中 for (let 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; }
注意,若是對location.href
寫入新的URL
地址,瀏覽器會馬上跳轉到這個新地址。
除了上述的屬性外,location
還有幾個方法。
location.assign(url)
方法接收URL
字符串來使瀏覽器當即跳轉。而參數無效時會報錯。
location.assign('http://www.sample.com');
而給window.location
和location.href
兩個屬性賦值與調用assign()
方法效果同樣。
location.replace()
與location.assign()
方法相似,都是跳轉到新的URL
,但不會在瀏覽歷史History
裏面生成新的記錄,後退按鈕沒法回到當前頁面。當腳本發現當前是移動設備時,可使用replace
跳轉到移動版網頁。
// 跳轉到新的網址 location.replace('http://www.sample.com');
location.reload(boolean)
方法用於從新加載當前頁面。當參數爲false
或爲空時,瀏覽器將該網頁從本地緩存從新加載並定位到當前位置。參數爲true
時,瀏覽器向服務器從新請求,並定位到頂部(即scroillTop===0
)。
location.reload(); // 從新加載(有可能從緩存中加載) location.reload(true); // 從新加載(從服務器從新加載)
在reload()
以後的代碼有可能不會執行,取決於網絡延遲或系統資源等因素。最好將reload()
放在代碼最後一行。
location.toString()
方法返回整個URL字符串,至關於讀取location.href
屬性。
navigator
用於獲取當前瀏覽器信息。可使用window.navigator
屬性檢索navigator
對象。
appCodeName
:瀏覽器的代號名稱。Mozilla,Netscape 6和IE5的內部名稱都是Mozilla
。(只讀)appName
:瀏覽器的名稱。因爲兼容性問題,HTML5規範容許該屬性返回Netscape
。(只讀)appVersion
:瀏覽器版本號。通常不與實際版本對應。(只讀)connection
:提供NetworkInformation
對象來獲取設備的網絡鏈接信息。(只讀)cookieEnabled
:瀏覽器當前頁面是否啓用cookie
。(只讀)geolocation
:返回Geolocation
對象,可訪問設備的位置信息。安全考慮會提示受權。(只讀)hardwareConcurrency
:瀏覽器環境擁有的CPU核心數。(只讀)keyboard
:返回Keyboard
對象,提供檢索鍵盤佈局圖和切換從物理鍵盤捕獲按鍵的功能。(只讀)language
:瀏覽器主語言。(只讀)languages
:訪客所使用的語言數組,按優先順序排列。第一個元素賦給language
,當值改變時,window
觸發languagechange
事件。(只讀)mimeTypes
:返回MimeTypeArray
對象,包含可被識別的MimeType
對象的數組。(只讀)maxTouchPoints
:返回當前設備同時支持觸摸接觸點的最大數量。(只讀)onLine
:表示瀏覽器當前是否聯網。(只讀)oscpu
:返回客戶端計算機的操做系統或使用的CPU。在Firefox
中能夠獲取此值。permissions
:返回一個可用於查詢或更新某些APIs的權限狀態的對象。(只讀)platform
:瀏覽器所在系統平臺類型。不肯定此值是否有效。(只讀)plugins
:返回PluginArray
對象,包含瀏覽器安裝的全部插件。(只讀)product
:當前瀏覽器產品名稱。以兼容爲目的,返回"Gecko"
值。(只讀)serviceWorker
:返回ServiceWorkerContainer
對象,提供對ServiceWorker
的註冊、刪除、升級和通訊的訪問。(只讀)storage
:返回單例StorageManager
對象,用於維護數據的持久化存儲,大體肯定存儲數據的空間。(只讀)userAgent
:返回當前瀏覽器的用戶代理。(只讀)vendor
:瀏覽器的供應商。例如Chrome
中顯示Google Inc.
。vendorSub
:有關供應商的次要信息。在介紹一下navigator
對象中的一些方法。
javaEnabled()
代表瀏覽器是否啓用Java。是當前配置文件是否容許使用Java,而不是瀏覽器是否支持Java。
if (window.navigator.javaEnabled()) { // 瀏覽器中Java可用 }
sendBeacon(url, data)
是用於經過HTTP將少許數據異步傳輸到Web服務器。當傳輸成功時會返回true
。
url
爲發送的地址;data
是ArrayBufferView
、Blob
、DOMString
或者FormData
類型的數據。下面的例子展現了一個理論的統計代碼——卸載事件處理器中嘗試經過一個同步的XMLHttpRequest
向服務器發送數據。這致使了頁面卸載被延遲。
window.addEventListener('unload', logData, false); func logData() { var client = new XMLHttpRequest(); client.open("POST", "/log", flase); // 第三個參數代表是同步的xhr client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); client.send(analyticsData); }
這就是sendBeacon()
方法存在的意義。使用sendBeacon()
方法會使用戶代理在有機會時異步地向服務器發送數據,同時不會延遲頁面的卸載或影響下一導航的載入性能。這就解決了提交分析數據時的全部的問題:數據可靠,傳輸異步而且不會影響下一頁面的加載。此外,代碼實際上還要比其它技術簡單許多!
下面的例子展現了一個理論上的統計代碼模式——經過使用sendBeacon()
方法向服務器發送數據。
window.addEventListener('unload', logData, false); function logData() { navigator.sendBeacon("/log", analyticsData); }
registerProtocolHandler(scheme, url, title)
可讓Web站點爲自身註冊能用於打開或處理特定協議的功能。
scheme
:包含站點處理協議的字符串。例如,傳入"sms"
來註冊處理SMS
文本信息連接。url
:處理器的URL
字符串。應該包含一個"%"
佔位符,會被將要受理的文檔的escaped
連接所替換。這個連接多是一個真實URL
,或者是一個電話號碼,郵件地址之類的。title
:處理器標題。展現給用戶,例如彈出"容許站點處理[scheme]連接嗎?"或者在瀏覽器設置中列出註冊的處理器時。處理器的URL
必須以http
或者https
協議標記開頭,最好是https
,以知足一些瀏覽器出於安全考慮的要求。
screen
對象表示當前屏幕窗口,每每指當前正被渲染的window
對象,提供顯示設備的信息。用處不大。主要介紹幾種屬性。
availTop
:返回瀏覽器可用空間在屏幕上邊的像素值。availLeft
:返回瀏覽器可用空間在屏幕左邊的像素值。availWidth
:返回瀏覽器可用空間的水平寬度。availHeight
:返回瀏覽器可用空間的垂直高度。colorDepth
:返回屏幕的顏色深度(color depth)。根據CSSOM(CSS對象模型)視圖,爲兼容起見,該值總爲24。height
:返回屏幕的高度(單位:像素)。orientation
:返回一個ScreenOrientation
實例,表示當前屏幕的方向。pixelDepth
:返回屏幕的位深度/色彩深度(bit depth)。根據CSSOM(CSS對象模型)視圖,爲兼容起見,該值總爲24。width
:返回屏幕的寬度(單位:像素)。history
對象保存着瀏覽器的歷史記錄。出於安全考慮,開發人員沒法得知用戶瀏覽器的URL。但能經過歷史列表實現後退和前進。下面是history
對象主要的屬性。
length
:返回當前窗口歷史列表中的URL
數量。scrollRestoration
:容許Web應用程序在歷史列表上顯示地設置默認滾動恢復行爲。state
:history
堆棧最上層的狀態值。const scrollRestoration = history.scrollRestoration; if (scrollRestoration) { // 防止自動恢復頁面位置 history.scrollRestoration = 'manual'; } else { // 查看當前頁面滾動恢復行爲 console.log('The location on the page is not restored, user will need to scroll manually.'); }
還能夠經過history
提供的方法來訪問歷史記錄。
go()
方法能夠在用戶的歷史記錄中任意跳轉。傳遞數值爲跳轉的頁數。
history.go(-1); // 返回一頁 history.go(2); // 前進兩頁
也能夠傳遞歷史記錄中存在的字符串參數,若是歷史記錄中不包含傳遞的字符串,那什麼也不作。
history.go("sample.com");
還可使用 back()
方法後退和使用forward()
方法前進來代替go()
方法的功能。
注意,移動到之前訪問過的頁面時,頁面一般是從瀏覽器緩存之中加載,而不是從新要求服務器發送新的網頁。
pushState(state, title, url)
方法可以在不加載頁面的狀況下在歷史中添加一條記錄。這個方法接收三個參數:
state
參數是狀態對象,與pushState
添加的記錄相關聯。表示瀏覽器的state
屬性。title
參數是document.title
的值,通常設定爲null
。瀏覽器大多會忽略。url
參數指定新歷史記錄,用以改變當前url
。這個參數不能跨域,即協議,域名,端口必須是相同的,若是出現跨域的狀況,即會提示。history.pushState({id:1}, null, '?page=1');
replaceState(stateObj, title, url)
方法用來修改history
對象的當前記錄,它是替換當前頁面在瀏覽器的歷史記錄。假設當前網頁是sample.com/index.html
history.pushState({id:1}, 'title1', '?page=1'); // URL顯示爲http://sample.com/index.html?page=1 history.pushState({id:2}, 'title2', '?page=2'); // URL顯示爲http://sample.com/index.html?page=2 history.replaceState({id:3}, 'title3', '?page=3'); // URL顯示爲http://sample.com/index.html?page=3 history.back(); // URL顯示爲http://sample.com/index.html?page=1 history.back(); // URL顯示爲http://sample.com/index.html history.go(2); // URL顯示爲http://sample.com/index.html?page=3
當添加或更改歷史記錄時,會觸發popstate
事件。若是被激活的歷史記錄條目是經過對history.pushState()
的調用建立的,或者受到對history.replaceState()
的調用的影響,popstate
事件的state
屬性包含歷史條目的狀態的副本。
須要注意的是調用history.pushState()
或history.replaceState()
不會觸發popstate
事件。只有在作出瀏覽器動做時,纔會觸發該事件,如用戶點擊瀏覽器返回按鈕(或者在JavaScript代碼中調用history.back()
或者history.forward()
方法)。
BOM
是以window
對象爲依託的瀏覽器對象模型,它將瀏覽器看成一個對象,用於與瀏覽器窗口進行交互。window
對象仍是Global
對象,全局變量和函數都是它的屬性和方法,且全部原生的構造函數及其它函數也在它的命名空間下。但每一個瀏覽器廠商都有本身的BOM
實現,所以兼容性較差。
更多內容請關注公衆號「海人的博客」,回覆「資源」便可得到免費學習資源!