關於BOM瀏覽器文檔對象模型

前言

這兩天小落落讀《JavaScrpit高級程序設計》(第三版)依然讀到了很多的知識盲點,以此篇作一個記錄。如有錯誤也希望大家指正。

BOM對象是什麼

BOM(Browser Object Model 瀏覽器對象模型)
BOM提供了很多對象,用來訪問瀏覽器的功能,而這些功能與任何的網頁內容無關。

EcmaScript的核心 是JavaScript,而BOM無疑是JavaScript的核心。

BOM對象上的屬性

我們先以一張圖來表示BOM對象上的屬性。

BOM.png
BOM是用來訪問瀏覽器的功能。那麼,對於BOM來說,window便是BOM的核心對象。

2.1 Window

window對象是一個比較特殊的存在。在瀏覽器當中,window對象既是JavaScrpt訪問瀏覽器窗口的一個接口,又是ECMAScript規定的全局對象。

window在瀏覽器的具體功能:
全局作用域、窗口關係及框架、窗口位置、窗口大小、導航和打開窗口、間歇調用和超時調用、系統對話框

2.1.1 全局作用域

由於window對象在瀏覽器中是代表一個全局對象。因此所有在全局中定義的變量、函數、方法都會是window對象的屬性和方法。
以下爲例:
`var age = 29;
function sayAge(){
alert(this.age)
}
console.log(window.age)
window.sayAge();`

我們在全局中定義了一個變量age,以及一個函數sayAge。它們就會自動變成window對象的屬性或者方法。所以我們可以通過window. 的形式對它們進行調用。

知識點:
1、雖然定義在全局的變量 就會變成window對象的屬性。但與直接定義window對象的屬性還是不同的。
直接定義的全局變量不能使用delete刪除。
因爲使用var定義的變量都有一個Configurable的特性,這個特性的值被設置爲false,所以這樣定義的屬性不能被delete刪除。
image.png

2、IE9以下版本,使用delete刪除哪種定義的屬性方法,都會拋出錯誤。

2.1.2 窗口關係及框架

如果頁面中存在框架frame。那麼每一個框架都有自己的window對象。並且每個框架的window對象是相互獨立的。

在frame集中,可以通過數值索引(從0開始,從上到下,從左到右)或者框架的名稱來訪問相應的window對象。

如下代碼

<frameset>
    <frame name="topFrame" rows="160,*">
        <frameset>
            <frame name="leftFrame">
                <frame name="rightFrame">
        </frameset>
</frameset>

以上代碼,我們有三個frame框架。分爲上,左、右。獲取上面的框架

我們可以使用window.frames[0]、window.frames['topFrame']來獲取 。或者可以使用top來獲取top.frames[0]

2.1.3 窗口位置

用來確定和修改window對象位置的屬性和方法有很多,
IE、Safari、Opera、Chrome都提供了screenLeft、screenTop屬性,分別表示窗口距離屏幕左邊,窗口距離屏幕上邊的距離。
Firefox使用screenX、screenY表示。
Safari、Chrome同時支持兩個屬性。

這種情況,各個瀏覽器都有自己的支持屬性,如果想兼容各個瀏覽器,我們應該怎麼辦呢?

這時候就需要很好的利用三目運算了。利用三目運算符判斷瀏覽器是否支持對應的屬性。
三目運算符 表達式?true:false;
typeof(window.screenTop)=='number'?window.screenTop:window.screenY。

這樣,支持screenTop的瀏覽器就會返回window.screenTop,不支持的瀏覽器就會返回screenY.

2.1.4 窗口大小

IE9+、Firefox、Safari、Opera、Chrome有四個屬性:innerWidth、innerHeight、outerWidth、outerHeight

IE9+、Firefox、Safari:outerWidth,outerHeight返回的是瀏覽器窗口本身的大小
即:以屏幕分辨率爲1920的電腦爲例
console.log(window.outerWidth) 輸出一直都是1920
window.innerWidth 會根據你調節窗口的在大小而改變。

Opera:這兩個屬性表示的是單個標籤頁對應的瀏覽器窗口的大小。而innerWidth、innerHeight則表示容器中頁面視圖區的大小(不包括邊框寬度)

Chrome:outerWidth、outerHeight與innerWidth、innerHeight返回相同的值,即視口大小,而非瀏覽器窗口大小。

知識點:
在IE8及更早的版本里,並沒有提供取得當前瀏覽器窗口尺寸的屬性。但是它可以通過DOM獲取頁面可視區域的相關信息。

IE、Firefox、Safari、Opera、Chrome中,
document.documentElement.clientWidth
document.documentElement.clientHeight保存了頁面視口的信息。

在IE6中,以上的兩個屬性在標準的模式下才有效;
如果在混雜模式下就必須通過
document.body.clientWidth和document.body.clientHeight獲取相同的信息

2.1.5 導航和打開窗口

這裏主要應用的是window.open()方法
首先我們來看一下它的語法
window.open(URL,name,specs,replace)
URL:打開頁面的URL
name:指定target屬性或者窗口的名稱
specs:一個特性字符串。用來設置窗口的屬性,並以逗號隔開。
replace:規定了裝載到窗口的URL是在窗口瀏覽歷史中添加一個新條目,還是替換瀏覽歷史中的當前條目。

例:
window.open("https://www.baidu.com/", "selfWindow", "width:400,height:400")
這樣,就在頁面的右下角打開了一個400*400的新窗口

知識點:
出於安全的考慮,很多瀏覽器在彈出窗口配置方面作了很多限制。例如,大多數的瀏覽器都內置了屏蔽程序,屏蔽彈出窗口。
如果瀏覽器屏蔽了彈出窗口,window.open()會拋出一個錯誤。基於此

1、檢測瀏覽器是否屏蔽了彈出窗口,檢測window.open()的返回值,並將它的調用放入到try catch中

var blocked = false;
try{
var wroxWin = window.open("https://www.baidu.com/", "selfWindow")
if (wroxWin == null){
    blocked = true;
}
}catch(error){
    blocked = true;
}
if(blocked){
alert('彈出窗口被屏蔽')
}

2、對於沒有屏蔽彈出窗口的瀏覽器,可以安裝 Yahoo,Toolbar等帶有內置屏蔽程序的實用工具。

2.1.6 間歇調用和超時調用

名字聽起來很晦澀難懂,但其實這一塊主要運用的是
window的setTimeoutsetInterval方法

名詞解釋:
間歇調用:是指程序每隔一斷時間就執行一次
超時調用:指程序在指定的時間過後,執行一次

根據以上的名詞解釋,便可以得知,間歇調用也就是setInterval,超時調用指setTimeout方法。

兩個方法用法相同,此處我們就不再過多介紹。

2.1.7 系統對話框

所謂系統對話框,也就是系統內置的對話框方法。

常用的alert、comfirm、prompt
三者具體的使用方式
三個都是彈出一個對話框,不同的是他們與用戶的交互程度會依次(從左到右)遞增

alert:只是一個對話框。只有一個關閉按鈕('關閉對話框')
image.png

comfirm:比alert更功能豐富一點,多了一個選擇的。
image.png

prompt:在comfirm的基礎上,還添加了一個文本框,可以輸入內容。
image.png
點擊確定後,會返回文本框中的值。
點擊取消會返回null

系統對話框有以下幾個特點
1、樣式由系統決定
這些是由系統內置的對話框,不存在於html中,它的樣式也不由css來決定。而是由瀏覽器決定。瀏覽器內置什麼樣子,展示出來便是什麼樣子。所以每個瀏覽器的對話框各不相同

2、調用系統對話框時,代碼會結束運行
當程序在運行過程中,遇到系統對話框,如alert,系統會暫停運行程序。直到對話框關閉,程序再繼續運行。

2.2 Location

location是最有用的BOM對象之一。它提供了與當前窗口中加載的文檔有關的信息。

它也是一個非常特別的屬性。因爲,它即是window的屬性,也是document的屬性。即
window.location == document.location

我們通常用它來訪問地址欄的信息,如

方法名 返回值 說明
hash #name=test 返回地址欄中#後面的信息
host baidu.com:80 服務器名及端口號
search ?name=a 返回地址中查詢字符串。字符串以?開頭
href https://baidu.com?name=test 返回當前地址欄中完整的URL地址

2.2.1 查詢字符串參數

以上表中所列的location的一些方法,我們可以獲取出大部分的地址欄 信息。但大部分都是完整的。如果我們想獲取單個的變量。
例如:想要獲取地址欄中name的參數及參數值,我們又該怎麼做呢?

這時候,我們可以將從地址欄 獲取的信息,整合到一起,並轉換成一個對象,這樣,我們需要的參數就變成了對象的一個屬性。

function getStringArgs(){
    var locationURL = (location.search.length>0?location.search.substring(1):"")//獲取查詢字符串,如果有值,則返回?之後的內容,沒有值則返回空串
    args = {};
    items = locationURL.length?locationURL.split("&"):[];
    name = null;
    value = null;
    len = items.length;
    for(let i=0;i<len;i++){
        item = items[i].split("=")
        name = decodeURIComponent(item[0]);
        value =decodeURIComponent(item[1]);
        args[name] = value;
    }
    return args;
}

知識點:
1、decodeURIComponent用於解碼。一般用於獲取中文情況。因爲中文在地址欄中會被編碼,所以,我們獲取值時,應該先進行解碼。

2.2.2 位置操作

我們也可以通過location改變瀏覽器的位置
最常見的
window.location.href = "http://baidu.com"
我們便可以由當前的頁面,跳轉到百度頁

localtion中還有一個assign方法
location.assign("http://baidu.com")
同樣能達到跳轉頁面的效果

我們可以通過修改location的值,達到刷新當前頁面,或者跳轉其它頁面的效果。如下圖
image.png
圖片截自JavaScript高級程序設計(第三版)

知識點:
1、修改location的值,除了修改hash外,頁面都會重新加載

2、通過location修改地址後,瀏覽器會在歷史記錄裏添加一條訪問記錄。這也意味着,我們可以通過“後退”“前進”按鈕導航到前一個/後一個頁面

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章