前端開發系列031-基礎篇之BOM
title: '前端開發系列031-基礎篇之BOM'
tags:
- javaScript系列
categories: []
date: 2017-08-14 08:20:13
本文介紹BOM相關的知識點,介紹的重點在於BOM核心Window物件的成員細節。
BOM簡單介紹
我們已經知道JavaScript的範圍包括ECMAScript(語言核心) + DOM(文件物件模型) + BOM(瀏覽器物件模型)
。
BOM 是 Browser Object Model(瀏覽器物件模型)的縮寫,它提供了獨立於內容 而與瀏覽器視窗進行互動的物件。由於BOM主要用於管理視窗與視窗之間的通訊,因此其核心物件是window,它表示流瀏覽器的一個例項。BOM由一系列相關的物件構成,並且每個物件都提供了很多方法與屬性,window作為最頂層的物件,BOM中所有的物件都是通過它延伸出來的。
標準化 JavaScript語法的標準化組織是ECMA,DOM的標準化組織是W3C, 而BOM因為缺乏標準,BOM最初其實是Netscape瀏覽器標準的一部分,而這也正是各種瀏覽器不相容的根源所在。此外需要指出的是,W3C為了把瀏覽器中JavaScript最基本的部分標準化,已經將BOM的主要方面納入了HTML5的規範中。
window和全域性作用域
在瀏覽器中,window物件擁有著雙重的角色,它既是通過JavaScript訪問瀏覽器視窗的介面,也是ECMAScript規定中的Global全域性物件。因此,所有在全域性作用域中宣告的變數、函式都會自動成為window物件的屬性和方法。
全域性作用域
> ✧ 定義在全域性環境下的變數和函式都會成為 `window` 物件的成員(屬性和方法)
> ✧ 編碼的時候應該儘可能少的使用全域性變數,以避免汙染全域性環境
> ✧ 沒有用var宣告的變數會成為全域性變數,即 `window` 物件的屬性
> ✧ 在編碼時`window` 字首可以被省略,如 `window.console.log()` 通常寫成 `console.log()`;
程式碼示例
/*01-全域性作用域示例*/ console.log(window.age); //undefined var age = 12; console.log(age, window.age); //12 12 age自動成為window的屬性 console.log(window.arr); //undefined var arr = [1,2,3,"T"]; console.log(arr == window.arr); //true arr.push("V"); console.log(window.arr); //[1,2,3,"T","V"]; function sum(a,b) { return a + b; } console.log(sum(1, 2)); //3 console.log(window.sum(1, 3)); //4 /*02-沒有使用var宣告的變數預設成為全域性變數*/ address = "北京市海淀區"; console.log(window.address); //"北京市海淀區"; function f() { var a = "我是a"; b = "我是b"; } f(); /*呼叫函式f,執行函式體中的程式碼*/ //console.log(a); //報錯 無法訪問變數a 因為a是f函式中的區域性變數 console.log(b); //"我是b" b預設成為全域性變數 console.log(window.a); //undefined console.log(window.b); //"我是b" /*03-省略window字首*/ console.log(window.console == console); //true
因為全域性作用域中宣告的所有變數都會自動成為window的屬性,而實際的開發中程式碼量可能是巨大的,且專案可能是由很N多人一起維護的,因此應該儘可能的減少全域性變數的數量,以防止汙染全域性環境。
關於這個問題的解決方案可以有兩種,一種是根據具體的業務和功能將部分程式碼封裝到匿名函式(閉包)中
保持獨立性,一種是把很多變數和函式封裝到特定的物件中
處理。當然,更成熟的方案是使用 模組化 的方式來組織專案和程式碼結構,其實模組化的開發方式也是使用匿名函式封裝的一種變形,在這裡我們暫不作具體的展開。
注意 delete
用於刪除物件的屬性,需注意雖然使用delete
關鍵字可以刪除直接定義在 window
上面的屬性,但卻無法直接刪除用 var
宣告的全域性變數(在嚴格模式下不能禁止使用 delete
來刪除遍歷,錯誤資訊為 Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. )。
/*測試1:使用delete刪除物件的屬性*/
var obj = {id:"1001"};
console.log(delete obj.id); //true
console.log(obj.id); //undefined
/*測試2:使用delete刪除全域性變數的屬性*/
var className = 'H5-1904';
console.log(delete className); //false
console.log(className); //"H5-1904"
console.log(delete window.className); //false
console.log(window.className); //"H5-1904"
/*測試3:使用delete刪除直接定義在window物件上面的屬性*/
window.test = "測試的屬性";
console.log(delete window.test); //true
console.log(window.test); //undefined
window核心成員詳解
接下來,我將分門別類的講解瀏覽器視窗的大小、滾動、導航、開啟、彈窗、位置操作、歷史記錄以及事件處理等內容,所以這些功能都通過 window
的核心成員來提供和實現。
window的 location 物件
location
物件是window中最有用最重要的物件之一,它提供了與當前視窗中載入的文件有關的資訊,而且它非常特殊,它既是window
的屬性也是document
的屬性。
location 物件的主要屬性
hash 設定/返回從井號 (#) 開始的 URL(錨點)==>雜湊值。
href 設定/返回完整的 URL。
search 設定/返回從問號 (?) 開始的 URL(引數部分)。
host 伺服器名稱和埠號
hostname 伺服器名稱
pathname URL中的目錄和檔名
port 返回指定的埠號,如果沒有指定則返回空字串
protocol 返回網路協議
location 物件的主要方法
assign() 載入新的頁面
reload() 重新載入(重新整理)
replace(newurl) 使用新的頁面來替換當前頁面
url
的組成http://www.baidu.com:10086/api/reg.php?username=zs&password=123&age=18#123
協議:http
域名:baidu.com
埠:10086 (預設:80)
路徑:/api/
引數:username=zs&password=123&age=18
雜湊:#123
視窗的主要屬性
跨瀏覽器確定視窗的大小可以使用window的innerWidth
、innerHeight
、outerWidth
和outerHeight
四個屬性,它們分別對應的是頁面檢視容器的寬高和瀏覽器視窗本身的尺寸。需要注意的是,這幾個屬性存在相容性問題,在IE8-中需要通過DOM來獲取大小資訊。
頁面檢視容器也稱為瀏覽器的視口(
viewport
),相比視窗本身來說它不包括工具欄和滾動條。
/*01-獲取頁面可視區域的大小(寬 | 高)*/
var w =window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
var h =window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
/*相容IE8-
* 如果是標準模式則使用document.documentElement.clientWidth,
* 如果是混雜模式則使用document.body.clientWidth
* */
console.log(w); //877 可視區域的寬度
console.log(h); //410 可視區域的高度
/*02-獲取window視窗本身的大小*/
console.log(window.outerWidth); //877 視窗的寬度
console.log(window.outerHeight);//778 視窗的高度
/*03-獲取滾動條位置相關的資訊*/
console.log(window.scrollX); //水平滾動條滾動過的距離(只讀)
console.log(window.scrollY); //垂直滾動條滾動過的距離(只讀)
/*04-操作滾動的相關方法*/
window.scrollTo(100,100); //指定滾動位置
window.scrollBy(-100,100); //設定基於當前位置的滾動距離
視窗的開啟和關閉
語法
window.open([ URL ],[ name ],[ features ],[ replace ])
作用
open()
方法用於開啟一個新的瀏覽器視窗或查詢一個已命名的視窗。
/* 作用:開啟新的視窗
* 語法:window.open(URL,name,features,replace)
* 引數:
* URL 開啟指定頁面的URL,沒有指定則開啟空白視窗。
* name 指定target屬性或視窗的名稱。
* _blank - 在新的視窗載入頁面(預設)
_parent - 在視窗中載入頁面
_self - 在當前視窗中載入頁面(替換)
_top - URL替換任何可載入的框架集
name - 視窗名稱
features 可選的字串,聲明瞭新視窗要顯示的標準瀏覽器的特徵
replace 可選的布林值,設定瀏覽歷史的處理(true表示替換當前條目,false表示新建條目)
*/
/*01-開啟空白視窗*/
window.open();
/*02-開啟新的標籤頁,載入www.wendingding.com站點*/
window.open("http://www.wendingding.com");
/*03-開啟新的視窗並控制視窗的外觀*/
//toolbar 瀏覽器工具欄是否顯示
//location 是否顯示地址欄位
//directories 是否新增目錄按鈕(IE)
//status 是否新增狀態列
//menubar 是否顯示選單欄
//scrollbars 是否顯示滾動條
//resizable 視窗是否可調節尺寸
//width 視窗的寬度
//height 視窗的高度
window.open("http://www.wendingding.com","_blank","toolbar=yes, location=yes, " +
"directories=no, status=no, menubar=yes, scrollbars=yes, " +
"resizable=no,width=400, height=400");
/*04-關閉當前視窗*/
window.close();
/*05-該方法用來調出列印視窗*/
window.print();
系統彈框
alert( )
彈出對話方塊(確定)
confirm( )
彈出警告框,返回布林值(確定&取消)
prompt( )
彈出輸入框,返回訊息或 null
//console.log(alert("確定")); /*提示框 該方法沒有返回值*/
//console.log(confirm("確定刪除嗎?"));; /*警示窗 確定返回true,取消返回false*/
var res = prompt("好漢請留下尊姓大名","座山雕");
//如果點選了取消那麼就返回null
//如果點選了確定那麼就返回輸入框的內容
console.log(res);
window的 history 物件
window物件中有一個history
屬性,它本身也是一個物件儲存著網頁的歷史記錄(從視窗開啟時計算)。出於安全方面的考慮,開發人員無法得知使用者瀏覽過的URL詳情,但卻可以利用history
物件來實現前進和後退的功能。
history
物件通過內部的length
屬性來記錄瀏覽歷史的數量,該資料包含了向前和向後的所有瀏覽記錄,預設載入到視窗的第一個頁面其history.length
的值為0。
go( )
跳轉到任意的瀏覽歷史記錄,負數表示後退。back( )
後退一頁forward( )
前進一頁
/*方法演示 下面程式碼中的window字首可以省略*/
console.log(window.history.length); //獲取歷史記錄長度
window.history.go(1); //前進1頁
window.history.go(-1); //後退1頁
window.history.back(); //回退
window.history.forward(); //前進
window的事件補充
onresize
事件會在視窗大小調整的時候被觸發。
onscroll
事件在頁面滾動條滾動的時候會被觸發。
onload
事件會在頁面載入完成(HTML+CSS+其它資源)後觸發。