javascript快速入門13--BOM——瀏覽器物件模型(Browser Object Model)

水之原發表於2013-12-01

什麼是BOM?

  • BOM是Browser Object Model的縮寫,簡稱瀏覽器物件模型
  • BOM提供了獨立於內容而與瀏覽器視窗進行互動的物件
  • 由於BOM主要用於管理視窗與視窗之間的通訊,因此其核心物件是window
  • BOM由一系列相關的物件構成,並且每個物件都提供了很多方法與屬性
  • BOM缺乏標準,JavaScript語法的標準化組織是ECMA,DOM的標準化組織是W3C(WHATWG,WebHypertextApplicationTechnologyWorkingGroup——網頁超文字應用程式技術工作組目前正在努力促進BOM的標準化)
  • BOM最初是Netscape瀏覽器標準的一部分

基本的BOM體系結構圖

能利用BOM做什麼?

BOM提供了一些訪問視窗物件的一些方法,我們可以用它來移動視窗位置,改變視窗大小,開啟新視窗和關閉視窗,彈出對話方塊,進行導航以及獲取客戶的一些資訊如:瀏覽器品牌版本,螢幕解析度。但BOM最強大的功能是它提供了一個訪問HTML頁面的一入口——document物件,以使得我們可以通過這個入口來使用DOM的強大功能!!!

window物件是BOM的頂層(核心)物件,所有物件都是通過它延伸出來的,也可以稱為window的子物件。由於window是頂層物件,因此呼叫它的子物件時可以不顯示的指明window物件,例如下面兩行程式碼是一樣的:

    document.write("BOM");
    window.document.write("BOM");

 

window -- window物件是BOM中所有物件的核心。window物件表示整個瀏覽器視窗,但不必表示其中包含的內容。此外,window還可用於移動或調整它表示的瀏覽器的大小,或者對它產生其他影響。

JavaScript中的任何一個全域性函式或變數都是window的屬性

window子物件

  • document 物件
  • frames 物件
  • history 物件
  • location 物件
  • navigator 物件
  • screen 物件

window物件關係屬性

  • parent:如果當前視窗為frame,指向包含該frame的視窗的frame (frame)
  • self :指向當前的window物件,與window同意。 (window物件)
  • top :如果當前視窗為frame,指向包含該frame的top-level的window物件
  • window :指向當前的window物件,與self同意。
  • opener :當視窗是用javascript開啟時,指向開啟它的那人視窗(開啟者)

window物件定位屬性

  • IE提供了window.screenLeft和window.screenTop物件來判斷視窗的位置,但未提供任何判斷視窗大小的方法。用document.body.offsetWidth和document.body. offsetHeight屬性可以獲取視口的大小(顯示HTML頁的區域),但它們不是標準屬性。
  • Mozilla提供window.screenX和window.screenY屬性判斷視窗的位置。它還提供了window.innerWidth和window.innerHeight屬性來判斷視口的大小,window.outerWidth和window.outerHeight屬性判斷瀏覽器視窗自身的大小。

window物件的方法

窗體控制
moveBy(x,y)——從當前位置水平移動窗體x個畫素,垂直移動窗體y個畫素,x為負數,將向左移動窗體,y為負數,將向上移動窗體
moveTo(x,y)——移動窗體左上角到相對於螢幕左上角的(x,y)點,當使用負數做為引數時會吧窗體移出螢幕的可視區域
resizeBy(w,h)——相對窗體當前的大小,寬度調整w個畫素,高度調整h個畫素。如果引數為負值,將縮小窗體,反之擴大窗體
resizeTo(w,h)——把窗體寬度調整為w個畫素,高度調整為h個畫素
窗體滾動軸控制
scrollTo(x,y)——在窗體中如果有滾動條,將橫向滾動條移動到相對於窗體寬度為x個畫素的位置,將縱向滾動條移動到相對於窗體高度為y個畫素的位置
scrollBy(x,y)—— 如果有滾動條,將橫向滾動條移動到相對於當前橫向滾動條的x個畫素的位置(就是向左移動x畫素),將縱向滾動條移動到相對於當前縱向滾動條高度為y個畫素的位置(就是向下移動y畫素)
窗體焦點控制
focus()—— 使窗體或控制元件獲取焦點
blur()——與focus函式相反,使窗體或控制元件失去焦點
新建窗體
open()——開啟(彈出)一個新的窗體
close()——關閉窗體
opener屬性——新建窗體中對父窗體的引用,中文"開啟者"的意思

window.open方法語法

    window.open(url, name, features, replace);

 

open方法引數說明

  • url -- 要載入窗體的URL
  • name -- 新建窗體的名稱(目標,將在a 標籤的target屬性中用到,當與已有窗體名稱相同時將覆蓋窗體內容).open函式預設的開啟窗體的方式為target的_blank彈出方式,因此頁面都將以彈出的方式開啟
  • features -- 代表窗體特性的字串,字串中每個特性使用逗號分隔
  • replace -- 一個布林值,說明新載入的頁面是否替換當前載入的頁面,此引數通常不用指定

open函式features引數說明,如果不使用第三個引數,將開啟一個新的普通視窗

引數名稱型別說明
height Number 設定窗體的高度,不能小於100
left Number 說明建立窗體的左座標,不能為負值
location Boolean 窗體是否顯示位址列,預設值為no
resizable Boolean 窗體是否允許通過拖動邊線調整大小,預設值為no
scrollbars Boolean 窗體中內部超出視窗可視範圍時是否允許拖動,預設值為no
toolbar Boolean 窗體是否顯示工具欄,預設值為no
top Number 說明建立窗體的上座標,不能為負值
status Boolean 窗體是否顯示狀態列,預設值為no
width Number 建立窗體的寬度,不能小於100

  特性字串中的每個特性使用逗號分隔,每個特性之間不允許有空格

open方法返回值為一個新窗體的window物件的引用

對話方塊
alert(str)—— 彈出訊息對話方塊(對話方塊中有一個“確定”按鈕)
confirm(str)—— 彈出訊息對話方塊(對話方塊中包含一個“確定”按鈕與“取消”按鈕)
prompt(str,defaultValue)——彈出訊息對話方塊(對話方塊中包含一個“確定”按鈕、“取消”按鈕與一個文字輸入框),由於各個瀏覽器實現的不同,若沒有第二個引數(文字框中的預設值)時也最好提供一個空字串
狀態列
window.defaultStatus 屬性——改變瀏覽器狀態列的預設顯示(當狀態列沒有其它顯示時),瀏覽器底部的區域稱為狀態列,用於向使用者顯示資訊
window.status 屬性——臨時改變瀏覽器狀態列的顯示
時間等待與間隔函式
setTimeout()—— 暫停指定的毫秒數後執行指定的程式碼
clearTimeout()——取消指定的setTimeout函式將要執行的程式碼
setInterval()——間隔指定的毫秒數不停地執行指定的程式碼
clearInterval()——取消指定的setInterval函式將要執行的程式碼

setTimeout與setInterval方法有兩個引數,第一個引數可以為字串形式的程式碼,也可以是函式引用,第二個引數為間隔毫秒數,它們的返回是一個可用於對應clear方法的數字ID

    var tid = setTimeout("alert('1')",1000);
    alert(tid);
    clearTimeout(tid);

 

History物件,在瀏覽器歷史記錄中導航

History 物件的屬性:length 返回瀏覽器歷史列表中的 URL 數量

History 物件的方法

  • back() 載入 history 列表中的前一個 URL
  • forward() 載入 history 列表中的下一個 URL
  • go(num) 載入 history 列表中的某個具體頁面

Location 物件

Location 物件的屬性

  • hash 設定或返回從井號 (#) 開始的 URL(錨)
  • host 設定或返回主機名和當前 URL 的埠號
  • hostname 設定或返回當前 URL 的主機名
  • href 設定或返回完整的 URL
  • pathname 設定或返回當前 URL 的路徑部分
  • port 設定或返回當前 URL 的埠號
  • protocol 設定或返回當前 URL 的協議
  • search 設定或返回從問號 (?) 開始的 URL(查詢部分)

Location 物件的方法

  • assign() 載入新的文件,這與直接將一個URL賦值給Location物件的href屬性效果是一樣的
  • reload() 重新載入當前文件,如果該方法沒有規定引數,或者引數是 false,它就會用 HTTP 頭 If-Modified-Since 來檢測伺服器上的文件是否已改變。如果文件已改變,reload() 會再次下載該文件。如果文件未改變,則該方法將從快取中裝載文件。這與使用者單擊瀏覽器的重新整理按鈕的效果是完全一樣的。如果把該方法的引數設定為 true,那麼無論文件的最後修改日期是什麼,它都會繞過快取,從伺服器上重新下載該文件。這與使用者在單擊瀏覽器的重新整理按鈕時按住 Shift 健的效果是完全一樣。
  • replace() 用新的文件替換當前文件,replace() 方法不會在 History 物件中生成一個新的紀錄。當使用該方法時,新的 URL 將覆蓋 History 物件中的當前紀錄。

Navigator物件

Navigator 物件的屬性

  • appCodeName 返回瀏覽器的程式碼名
  • appName 返回瀏覽器的名稱
  • appVersion 返回瀏覽器的平臺和版本資訊
  • browserLanguage 返回當前瀏覽器的語言
  • cookieEnabled 返回指明瀏覽器中是否啟用 cookie 的布林值
  • cpuClass 返回瀏覽器系統的 CPU 等級
  • onLine 返回指明系統是否處於離線模式的布林值
  • platform 返回執行瀏覽器的作業系統平臺
  • systemLanguage 返回 OS 使用的預設語言
  • userAgent 返回由客戶機傳送伺服器的 user-agent 頭部的值
  • userLanguage 返回 OS 的自然語言設定

框架與多視窗通訊

子視窗與父視窗

只有自身和使用window.open方法開啟的視窗和才能被JavaScript訪問,window.open方法開啟的視窗通過window.opener屬性來訪問父視窗。 而在opener視窗中,可以通過window.open方法的返回值來訪問開啟的視窗!

框架

window.frames集合:在框架集或包含iframe標籤的頁面中,frames集合包含了對有框架中視窗的引用

    alert(frames.length);//框架的數目
    alert(frames[0].document.body.innerHTML);//使用下標直接獲取對框架中視窗的引用
    //不但可以使用下標,還可以使用frame標籤的name屬性
    alert(frames["frame1"].document.title);

 

在框架集中還可以使用ID來獲取子視窗的引用

    var frame1 =document.getElementById("frame1");//這樣只是獲取了標籤
    var frame1Win = frame1.contentWindow;//frame物件的contentWindow包含了視窗的引用
    //還可以直接獲取框架中document的引用
    var frameDoc = frame1.contentDocument;
    alert(frameDoc);//但IE不支援contentDocument屬性

 

子視窗訪問父視窗——window物件的parent屬性

子視窗訪問頂層——window物件的top屬性

瀏覽器檢測

市場上的瀏覽器種類多的不計其數,它們的解釋引擎各不相同,期待所有瀏覽器都一致的支援JavaScript,CSS,DOM,那要等到不知什麼時候,然而開發者不能幹等著那天。歷史上已經有不少方法來解決瀏覽器相容問題了,主要分為兩種:1.userAgent字串檢測,2.物件檢測;當然,也不能考慮所有的瀏覽器,我們需要按照客戶需求來,如果可以確信瀏覽網站的使用者都使用或大部分使用IE瀏覽器,那麼你大可放心的使用IE專有的那些豐富的擴充套件,當然,一旦使用者開始轉向另一個瀏覽,那麼痛苦的日子便開始了。下面是市場上的主流瀏覽器列表:

  • Internet Explorer
  • Mozilla Firefox
  • Google Chrome
  • Opera
  • Safari

注意,瀏覽器總是不斷更新,我們不但要為多種瀏覽器作相容處理,還要對同一瀏覽器多個版本作相容處理。比如IE瀏覽器,其6.0版本和7.0版本都很流行,因為微軟IE隨著作業系統繫結安裝(之前也是同步發行,微軟平均每兩年推出一款個人桌面,同樣IE也每兩年更新一次;直到現在,由於火狐的流行,IE工作組才加快IE的更新),所以更新的較慢,6.0版和7.0版有很大差別。

市場上還存在一些其它瀏覽器,但由於它們都是使用的上面所列瀏覽器的核心,或與上面瀏覽器使用了相同的解釋引擎,所以無需多作考慮。下面是主流的瀏覽器解釋引擎列表:

  1. Trident

    Trident (又稱為MSHTML),是微軟的視窗作業系統(Windows)搭載的網頁瀏覽器—Internet Explorer的排版引擎的名稱,它的第一個版本隨著1997年10月Internet Explorer第四版釋出,之後不斷的加入新的技術並隨著新版本的Internet Explorer釋出。在未來最新的Internet Explorer第七版中,微軟將對Trident排版引擎做了的重大的變動,除了加入新的技術之外,並增加對網頁標準的支援。儘管這些變動已經在相當大的程度上落後了其它的排版引擎。使用該引擎的主要瀏覽器:IE,TheWorld,MiniIE,Maxthon,騰訊TT瀏覽器。事實上,這些瀏覽器是直接使用了IE核心,因為其userAgent字串中返回的資訊與IE是一模一樣的!

  2. Gecko

    壁虎,英文為"Gecko"。Gecko是由Mozilla基金會開發的佈局引擎的名字。它原本叫作NGLayout。Gecko的作用是讀取諸如HTML、CSS、XUL和JavaScript等的網頁內容,並呈現到使用者螢幕或列印出來。Gecko已經被許多應用程式所使用,包括若干瀏覽器,例如Firefox、Mozilla Suite、Camino,Seamonkey等等

  3. Presto

    Presto是一個由Opera Software開發的瀏覽器排版引擎,供Opera 7.0及以上使用。Presto取代了舊版Opera 4至6版本使用的Elektra排版引擎,包括加入動態功能,例如網頁或其部分可隨著DOM及Script語法的事件而重新排版。Presto在推出後不斷有更新版本推出,使不少錯誤得以修正,以及閱讀Javascript效能得以最佳化,併成為速度最快的引擎。

  4. KHTML

    是HTML網頁排版引擎之一,由KDE所開發。KDE系統自KDE2版起,在檔案及網頁瀏覽器使用了KHTML引擎。該引擎以C++程式語言所寫,並以LGPL授權,支援大多數網頁瀏覽標準。由於微軟的Internet Explorer的佔有率相當高,不少以FrontPage製作的網頁均包含只有IE才能讀取的非標準語法,為了使KHTML引擎可呈現的網頁達到最多,部分IE專屬的語法也一併支援。目前使用KHTML的瀏覽器有Safari和Google Chrome。而KHTML也產生了許多衍生品,如:WebKit,WebCore引擎

利用userAgent檢測

下面是各大瀏覽器使用彈窗顯示的userAgent字串

IE瀏覽器:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)

火狐瀏覽器:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4

Opera瀏覽器:Opera/9.64 (Windows NT 5.1; U; Edition IBIS; zh-cn) Presto/2.1.1

Safari瀏覽器:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16

Google Chrome瀏覽器:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/2.0.172.33 Safari/530.5

可以使用下面的程式碼進行瀏覽器檢測

    var Browser = {
        isIE:navigator.userAgent.indexOf("MSIE")!=-1,
        isFF:navigator.userAgent.indexOf("Firefox")!=-1,
        isOpera:navigator.userAgent.indexOf("Opera")!=-1,
        isSafari:navigator.userAgent.indexOf("Safari")!=-1
    };

 

但這樣做並不是萬無一失的,一個特例便是Opera可以使用userAgent偽裝自己。下面是偽裝成IE的userAgent:Mozilla/5.0 (Windows NT 5.1; U; Edition IBIS; zh-cn; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.64;在完全偽裝的情況下,最後的“Opera 9.64”這個字串也不會出現,但Opera也有特殊的識別自身的方法,它會自動宣告一個opera全域性變數!

不但如此,我們的檢測還忽略了一點,就是那些使用相同引擎而品牌不同的瀏覽器,所以,直接檢測瀏覽器是沒有必要的,檢測瀏覽器的解釋引擎才是有必要的!

    var Browser = {
        isIE:navigator.userAgent.indexOf("MSIE")>-1 && !window.opera,
        isGecko:navigator.userAgent.indexOf("Gecko")>-1 && !window.opera 
        && navigator.userAgent.indexOf("KHTML") ==-1,
        isKHTML:navigator.userAgent.indexOf("KHTML")>-1,
        isOpera:navigator.userAgent.indexOf("Opera")>-1
    };

 

相關文章