天天看點

javascript之有趣的【BOM】(深入)

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

表示的是視圖區域的大小。

javascript之有趣的【BOM】(深入)

在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('請輸入您的昵稱')           

顯示如下:

javascript之有趣的【BOM】(深入)

confirm()代碼:

var con = confirm('您輸入的昵稱為:villin')
if(con){
  console.log('使用者點選了确定')
  // 在此可以寫确定後的執行代碼
}else{
  console.log('使用者點選了取消')
  // 在此可以寫取消後的執行代碼
}                  
// 這樣可以得到使用者輸入的傳回值,記住,在chrome中,var後邊定義的變量不能為name,本人嘗試後得到的結果不準。           
javascript之有趣的【BOM】(深入)

prompt()代碼:

var con = prompt('您輸入名字','villin')
if(con){
  console.log('使用者點選了确定')
  // 在此可以寫确定後的執行代碼
}else{
  console.log('使用者點選了取消')
  // 在此可以寫取消後的執行代碼
}                             
javascript之有趣的【BOM】(深入)

這種對話框也很有趣,有興趣的,可以做一個反複彈出的對話框,惡搞你的朋友,可以練習一下。

--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

歡迎提出寶貴意見

繼續閱讀