1. 程式人生 > 其它 >前端開發系列031-基礎篇之BOM

前端開發系列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的innerWidthinnerHeightouterWidthouterHeight四個屬性,它們分別對應的是頁面檢視容器的寬高和瀏覽器視窗本身的尺寸。需要注意的是,這幾個屬性存在相容性問題,在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+其它資源)後觸發。