Bom知識不難,就是東西比較多,耐心了解此篇文章,會讓你收獲滿滿。相信自己,認真看完。
BOM(全稱:BrowserObjectModel)浏覽器模型
有很多小白同學一聽到
Bom
這個詞,瞬間暈倒,根本不懂到底是什麼,看以上的全稱來翻譯,就是浏覽器中的東西,我們前端浏覽器的主要方式在開發中來講,核心就是window。很多同學還聽過一個詞叫
Dom
,初學者來講,這兩個很容易讓人有“跳樓”的想法,其實學好了這兩個,js中也就明白了一半的知識。
先說說這兩個的差別,學過
html
的同學都知道,html主要是使用标簽,标簽在頁面中其實就是以節點的方式存在的,比如各種嵌套,就是分了很多的标簽節點,然後才能開發出想要的布局頁面。那麼
Dom
其實就是在用js控制這些标簽節點,然後操作各種事情。比如用js建立一個a标簽,就可以說建立了一個節點;再或者,用js寫出a标簽的樣式,就可以說控制了節點的樣式。完全可以這樣了解,但心裡要明白,這個标簽是js建立出來的,js控制了Dom節點,而非html寫出來的,兩者是有本質上的差別。那麼
Bom
是來操作浏覽器視窗的,比如你alert出一個彈窗,就是在操作Bom,你打開一個新的視窗,也是在操作Bom。是以了解為Bom是操作浏覽器window的,這樣兩者的差別就很顯然了。
--window對象和全局作用域--
bom的核心對象是
window
,它表示浏覽器的一個執行個體。在浏覽器中,window對象有雙重角色,即是javascript通路浏覽器視窗的一個接口,又是ECMAscript規定的Global(全局)對象。是以所有在全局作用域中聲明的變量、函數都會變成window對象的屬性和方法。如:
var name = 'xiaoming';
function lookName(){
alert(this.name);
}
console.log(window.name); //xiaoming
lookName(); //xiaoming
window.lookName(); //xiaoming
從上看出,我們在全局作用域下定義的name,被歸在了window對象下,是以可以通過window.name通路,也可以用通過window.lookName()通路函數lookName()。由于是全局作用域,是以this指向了window對象,那麼this.name自然也能通路到。
delete操作符
️注意:
全局定義的屬性不能用delete操作符删除,在window對象上直接定義的屬性可以。
var name1 = 'xiaoming'; // 全局定義name1
window.name2 = 'xiaoli'; // 在window上定義name2
console.log(delete window.name1); // 由于全局定義的不能用delete删除,是以會傳回false
console.log(delete window.name2); // window上的可以被delete删除,會傳回true
--window視窗--
視窗位置:
在各個浏覽器當中,IE、Safari、Opera、Chrome 都提供了位置屬性:
screenLeft
和
screenTop
。
分别表示:“浏覽器視窗相對于螢幕左邊和上邊的位置”。
但是火狐 (firefox) 卻提供了不同的屬性:
screenX
screenY
來表示上述位置。
更有趣的是歐朋浏覽器(Opera),四個屬性都提供,但
screenX、screenY 和 screenLeft、screenTop
屬性卻不對應,是以不建議在Opera中使用。
我們可以用自己的電腦試着列印一下你的視窗位置(用Chrome)舉例:
var left = window.screenLeft;
var top = window.screenTop;
console.log(left);
console.log(top);
但是這個案例并不能跨浏覽器相容,因為剛才提到過,firefox不支援
screenLeft
screenTop
,是以我們要跨浏覽器相容,需要做個判斷:
var left = (typeof window.screenLeft == 'number') ? window.screenLeft : window.screenX
var top = (typeof window.screenTop == 'number') ? window.screenTop : window.screenY
這樣使用一個三目運算就可以相容firefox來擷取浏覽器視窗的位置。
視窗大小:
如果需要跨浏覽器相容,來确定一個視窗的大小也略有不同。
IE9+、firefox、Safari、Opera、Chrome都提供了4個屬性:
innerHeight
、
innerWidth
outerHeight
outerWidth
這四個屬性均可以傳回浏覽器視窗大小,不過略有不同:
IE9+、firefox、Safari中,
outerHeight
outerWidth
傳回浏覽器視窗本身的尺寸。
Opera、Chrome中,
innerHeight
innerWidth
表示視窗容器的大小;
outerHeight
outerWidth
表示的是視圖區域的大小。

在IE、firefox、Safari、Opera、Chrome中,有兩個相同的方法均提供了頁面可視視窗的大小,分别為:
document.documentElement.clientHeight // 視圖區域的高度
document.documentElement.clientWidth // 視圖區域的寬度
上述圖檔的視圖區域寬高,就是用此方法列印出來的。
不過,這兩個方法必須要在标準模式
css1Compat
下才有效;混雜模式
BackCompat
下需要通過下邊方法才能有效擷取寬高資訊:
document.body.clientHeight // 視圖區域的高度
document.body.clientWidth // 視圖區域的寬度
兩種模式我們可以用
console.log(document.compatMode == "CSS1Compat" ? "目前處于标準模式" : "目前處于混雜模式")
來判斷,現在目前幾乎都是标準模式了。(如果不清楚兩種模式的差別,推薦一篇簡書中的文章:
https://www.jianshu.com/p/4aa37da38b81,看起來還不錯。)
是以,要跨模式擷取可視區域的視窗大小,需要進行判斷目前的模式:
// 判斷方法:document.compatMode
if(document.compatMode == 'css1Compat'){
var h = document.documentElement.clientHeight
var w = document.documentElement.clientWidth
}else{
var h = document.body.clientHeight
var w = document.body.clientWidth
}
console.log(h)
console.log(w)
// 這樣就擷取到了目前可視區域的大小
當然,移動端開發也有視窗的大小,如果你沉迷于技術上的鑽研,推薦一位移動開發咨詢師寫的文章:
https://quirksmode.org/mobile/viewports2.html全英文版,如果你的英語不好,可以使用浏覽器編譯出中文,也能了解到大概的含義。
--導航和打開視窗--
window.open()
window.open()
方法即可以導航到一個特定的URL,也可以打開一個新的浏覽器視窗。
window.open()
可接收4個參數:
1.url位址 2.視窗目标target 3.視窗設定的字元串 4.取代目前頁面的布爾值
,分别說一下:
url位址:就是要加載的浏覽器位址。
視窗目标:類似與
a
标簽中的target屬性。如果目前有與target相同的視窗,則會在目前視窗加載url。當然,我們也可以傳遞特殊的名稱,例如經常見到的
_blank
,
_top
_self
_parent
視窗設定的字元串:設定這個的前提是我們加載的url就跳轉到一個新的視窗,而不是在目前視窗加載,那麼這個參數就很有趣了。我們可以随意設定新視窗的大小,和彈出的位置。如設定寬500,高500的正方形視窗,也可以設定視窗上邊坐标與左邊的坐标。但要記住,這個參數是以字元串的形式展現的。我們以部落客的部落格位址
https://yq.aliyun.com/u/villin
舉例:
window.open('https://yq.aliyun.com/u/villin','_blank','width=500,height=500,top=100,left=100')
可以複制這個代碼到你的浏覽器,會看到彈出一個部落格視窗,并且視窗寬高為500,位于螢幕下移100像素,左移100像素。
同時我們還可以通過
resizeTo()
moveTo()
兩個方法再次操作新打開視窗的大小和位置,也可以通過
close()
方法關閉視窗:
var winURL = window.open('https://yq.aliyun.com/u/villin','_blank','width=500,height=500,top=100,left=100');
// 再次調整大小
winURL.resizeTo(500,300); // resizeTo()接收兩個參數,一個是寬度,一個是高度,當視窗打開時,再次調整為寬500px,高300px。
// 再次移動位置
winURL.moveTo(200,200); // moveTo()接收兩個參數,一個是距螢幕top的距離,一個是距螢幕left的距離。
// 3s後關閉視窗
setTimeout(() => {
winURL.close()
},3000) // setTimeout方法:等待一定時間後才開始執行某個任務,兩個參數,第一個是方法,第二個是等待時間。
當然,這個參數不僅僅隻有這四個屬性,還有
location,menubar,resizable,scrollbars,toolbar
等等。都代表着視窗所顯示的菜單欄或其他狀态欄,不過目前用到的也比較少,因為每個浏覽器相容性并不一緻。
取代目前頁面的布爾值:這個參數隻有在不打開新的視窗下使用,使用目前頁面的浏覽曆史記錄,然後打開新的浏覽頁面。
--逾時調用和間歇調用--
setTimeout()/setInterval()
setTimeout()
逾時調用:
等待特定時間後,執行某個方法
。兩個參數,一個是要執行的代碼方法,一個是要等待執行的時間(毫秒mm):
setTimeout(function(){
alert('hello,world')
},2000) // 等待2秒後,彈出hello,world
setTimeout(()=>{
alert('hello,world')
},2000) // 也可以使用箭頭函數
setTimeout("alert('hello,world')") // 也可以直接寫成字元串方法,不過本方法不推薦使用。
setInterval()
間歇調用:
每間隔一段時間後,都執行某個方法
間歇調用與逾時調用的方法一樣,就是間歇調用是重複不斷的執行某個方法,是以可能會某個執行程式還沒執行完,就再次的調用了該方法,一般再我們開發中,不到不得已不建議用這個方法。要是用此方法,那麼要在頁面關閉前,一定要用
clearInterval()
清空這個方法,防止報錯:
id = setInterval(function(){
console.log('hello,world')
},1000) // 每隔一秒就列印一次hello,world
clearInterval(id) // 在頁面執行後,記得清空這個方法
--系統對話框--
浏覽器通過三種對話框方式向使用者展示消息:
1.alert() 帶有一個确認按鈕的彈出框
2.confirm() 帶有一個确認按鈕和一個取消按鈕的彈出框
3.prompt() 帶有輸入框的對話彈出框,兩個參數:一個是提示資訊,一個是輸入框預設文本
alert()代碼:
alert('請輸入您的昵稱')
顯示如下:
confirm()代碼:
var con = confirm('您輸入的昵稱為:villin')
if(con){
console.log('使用者點選了确定')
// 在此可以寫确定後的執行代碼
}else{
console.log('使用者點選了取消')
// 在此可以寫取消後的執行代碼
}
// 這樣可以得到使用者輸入的傳回值,記住,在chrome中,var後邊定義的變量不能為name,本人嘗試後得到的結果不準。
prompt()代碼:
var con = prompt('您輸入名字','villin')
if(con){
console.log('使用者點選了确定')
// 在此可以寫确定後的執行代碼
}else{
console.log('使用者點選了取消')
// 在此可以寫取消後的執行代碼
}
這種對話框也很有趣,有興趣的,可以做一個反複彈出的對話框,惡搞你的朋友,可以練習一下。
--location對象--
重要
`
重要
重要
location
對象對于Bom來講,是最有用的對象之一,它提供了目前視窗中加載的文檔有關的資訊,還提供了一些導航功能。
location
對象即是window對象的屬性,又是document對象的屬性。可以說
window.location
document.location
引用的是同一個對象。
location中提供了一些屬性:
hash : 傳回url中的hash(#号後邊的參數),如果url不包含散列,則傳回空字元串。如:"#villin"
host : 傳回伺服器名稱和端口号(如果有端口号的話會傳回)。如:“www.villin.com:8080”
hostname : 傳回不帶端口号的伺服器名稱。如:“www.villin.com”
href : 傳回目前加載頁面的完整url。
pathname : 傳回url的目錄檔案名或檔案路徑。
port : 傳回url中指定的端口号。
protocol : 傳回頁面使用的協定,“http”或“https”。
search : 傳回url的查詢字元串,這個字元串以“?”開頭。
舉例:(每次修改屬性後,頁面都會重新加載,hash除外)
假設原位址:www.villin.com/name/
1.添加一個hash位址:
location.hash = "#aaa" 改變後: www.villin.com/home/#aaa
2.添加一個搜尋條件:
location.search = "?q=html" 改變後: www.villin.com/home/?q=html
3.将伺服器名稱修改為 www.abc.com ,後邊home路徑不變:
location.hostname = "www.abc.com" 改變後: www.abc.com/home/
4.修改原檔案路徑為/name:
location.pathname = "name" 改變後:www.villin.com/name/
5.添加一個8080端口号:
location.port = 8080 改變後:www.villin.com:8080/name/
打開一個新的頁面的方法:
window.location(www.baidu.com)
location.href(www.baidu.com)
location.assign(www.baidu.com)
location.replace(www.baidu.com)
️這幾種方法都可以跳轉到新的頁面,目前常用的是
location.href()
方法。修改url後都會生成一條新的記錄,是以使用者可以通過浏覽器單擊“後退”按鈕,傳回到前一個頁面,若想禁用後退按鈕,使用
location.replace()
方法,即可禁用後退按鈕。
與其相關的方法還有一個
location.reload()
,此方法可以重新重新整理目前頁面。不過值得注意的是,這個方法會根據最有效的方式重新整理頁面,如果頁面自上一次請求以來沒有改變過,頁面就會從浏覽器緩存中重新加載。如果要強制從伺服器中重新加載,傳遞一個參數true即可。
location.reload(true) // 從伺服器重新加載
--history對象--
儲存着使用者浏覽頁面的曆史記錄
簡單介紹幾個常見方法:
history.go(-1) // 後退一頁
history.go(1) // 前進一頁
history.go(2) // 前進兩頁
history.go(0) // 重新加載目前頁
--navigator對象--
--screen對象--
由于window中以上兩個個對象并不常用,在這裡不做講解。若有需要,我們可以自己去查閱相關資料。
navigator
對象,我們可以自己在代碼中列印一下
console.log(window.navigator)
,自己可以擴充多了解一下浏覽器的其他屬性。
本問參考文獻:Javascript進階程式設計(第3版)
部落客聯系方式:
e-mail:[email protected]
weChat:VillinWeChat
歡迎提出寶貴意見