概念:BOM 的核心對象是 window,它表示瀏覽器的一個實例。在瀏覽器中,window 對象有雙重角色,它既是經過 JavaScript 訪問瀏覽器窗口的一個接口,又是 ECMAScript 規定的 Global 對象。這意味着在網頁中定義的任何一個對象、變量和函數,都以 window 做爲其 Global 對象,所以有權訪問parseInt()等方法javascript
全局做用域:html
全部在全局做用域中聲明的變量、函數都會變成 window 對象的屬性和方法java
var age = 29; function sayAge(){ alert(this.age); } alert(window.age); //29 sayAge(); //29 window.sayAge(); //29
全局變量不能經過 delete 操做符刪除,而直接在 window 對象上的定義的屬性能夠編程
var age = 29; window.color = "red"; //在 IE < 9 時拋出錯誤,在其餘全部瀏覽器中都返回 false delete window.age; //在 IE < 9 時拋出錯誤,在其餘全部瀏覽器中都返回 true delete window.color; //returns true alert(window.age); //29 alert(window.color); //undefined
嘗試訪問未聲明的變量會拋出錯誤,但經過查詢 window 對象,能夠知道某個可能未聲明的變量是否存在數組
//這裏會拋出錯誤,由於 oldValue 未定義 var newValue = oldValue; //這裏不會拋出錯誤,由於這是一次屬性查詢 //newValue 的值是 undefined var newValue = window.oldValue;
窗口關係及框架瀏覽器
窗口位置緩存
肯定和修改 window 對象位置的屬性和方法安全
var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX; var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;
將窗口精確地移動到一個新位置:服務器
moveTo():接收兩個參數,新位置的 x 和 y 座標值app
//將窗口移動到屏幕左上角 window.moveTo(0,0); //將窗口移動到(200,300) window.moveTo(200,300);
moveBy():在水平和垂直方向上移動的像素數
//將窗向下移動 100 像素 window.moveBy(0,100); //將窗口向左移動 50 像素 window.moveBy(-50,0);
窗口大小
肯定一個窗口的大小
肯定頁面視口的大小
在 IE、Firefox、Safari、Opera 和 Chrome 中,document.documentElement.clientWidth 和
document.documentElement.clientHeight 中保存了頁面視口的信息
在 IE6 的混雜模式,就必須經過 document.body.clientWidth 和 document.body.
clientHeight 取得相同信息
混雜模式下的 Chrome,則不管經過 document.documentElement仍是 document.body 中的 clientWidth 和 clientHeight 屬性,均可以取得視口的大小
var pageWidth = window.innerWidth; var pageHeight = window.innerHeight; if (typeof pageWidth != "number"){ if (document.compatMode == "CSS1Compat"){ pageWidth = document.documentElement.clientWidth; pageHeight = document.documentElement.clientHeight; } else { pageWidth = document.body.clientWidth; pageHeight = document.body.clientHeight; } }
調整瀏覽器窗口的大小的方法:
//調整到 100×100 window.resizeTo(100, 100); //調整到 200×150 window.resizeBy(100, 50); //調整到 300×300 window.resizeTo(300, 300);
導航和打開窗口
window.open()方法
4 個參數:要加載的 URL、窗口目標、一個特性字符串以及一個表示新頁面是否取代瀏覽器歷史記錄中當前加載頁面的布爾值
一般只須傳遞第一個參數,最後一個參數只在不打開新窗口的狀況下使用
若是爲 window.open()傳遞了第二個參數,並且該參數是已有窗口或框架的名稱,那麼就會在具備該名稱的窗口或框架中加載第一個參數指定的 URL,第二個參數也能夠是下列任何一個特殊的窗口名
稱:_self、_parent、_top 或_blank;
//等同於< a href="http://www.wrox.com" target="topFrame"></a> window.open("http://www.wrox.com/", "topFrame");
彈出窗口
若是給 window.open()傳遞的第二個參數並非一個已經存在的窗口或框架,那麼該方法就會根
據在第三個參數位置上傳入的字符串建立一個新窗口或新標籤頁
若是沒有傳入第三個參數,那麼就會打開一個帶有所有默認設置(工具欄、地址欄和狀態欄等)的新瀏覽器窗口(或者打開一個新標籤頁——根據瀏覽器設置)
在不打開新窗口的狀況下,會忽略第三個參數
第三個參數是一個逗號分隔的設置字符串,表示在新窗口中都顯示哪些特性
window.open("http://www.wrox.com/","wroxWindow", "height=400,width=400,top=10,left=10,resizable=yes");
window.open()方法會返回一個指向新窗口的引用
var wroxWin = window.open("http://www.wrox.com/","wroxWindow", "height=400,width=400,top=10,left=10,resizable=yes"); //調整大小 wroxWin.resizeTo(500,500); //移動位置 wroxWin.moveTo(100,100);
調用 close()方法還能夠關閉新打開的窗口
wroxWin.close(); alert(wroxWin.closed); //true
新建立的 window 對象有一個 opener 屬性,其中保存着打開它的原始窗口對象
var wroxWin = window.open("http://www.wrox.com/","wroxWindow", "height=400,width=400,top=10,left=10,resizable=yes"); alert(wroxWin.opener == window); //true
在 Chrome中,將新建立的標籤頁的 opener 屬性設置爲 null,即表示在單獨的進程中運行新標籤頁
var wroxWin = window.open("http://www.wrox.com/","wroxWindow", "height=400,width=400,top=10,left=10,resizable=yes"); wroxWin.opener = null;
安全限制
彈出窗口屏蔽程序
大多數瀏覽器都內置有彈出窗口屏蔽程序,若是是瀏覽器內置的屏蔽程序阻止的彈出窗口,那麼 window.open()極可能會返回 null
var wroxWin = window.open("http://www.wrox.com", "_blank"); if (wroxWin == null){ alert("The popup was blocked!"); }
若是是瀏覽器擴展或其餘程序阻止的彈出窗口,那麼 window.open()一般會拋出一個錯誤,綜合兩種狀況,封裝函數以下:
var blocked = false; try { var wroxWin = window.open("http://www.wrox.com", "_blank"); if (wroxWin == null){ blocked = true; } } catch (ex){ blocked = true; } if (blocked){ alert("The popup was blocked!"); }
間歇調用和超時調用
間歇調用:每隔指定的時間就執行一次代碼
使用 window 對象的 setTimeout()方法,它接受兩個參數:要執行的代碼和以毫秒錶示的時間(即在執行代碼前須要等待多少毫秒)
第一個參數能夠是一個包含 JavaScript 代碼的字符串(就和在 eval()函數中使用的字符串同樣),也能夠是一個函數
//不建議傳遞字符串! setTimeout("alert('Hello world!') ", 1000); //推薦的調用方式 setTimeout(function() { alert("Hello world!"); }, 1000);
第二個參數是一個表示等待多長時間的毫秒數,但通過該時間後指定的代碼不必定會執行
調用 setTimeout()以後,該方法會返回一個數值 ID,表示超時調用。這個超時調用 ID 是計劃執行代碼的惟一標識符,能夠經過它來取消超時調用。要取消還沒有執行的超時調用計劃,能夠調用clearTimeout()方法並將相應的超時調用 ID 做爲參數傳遞給它
//設置超時調用 var timeoutId = setTimeout(function() { alert("Hello world!"); }, 1000); //注意:把它取消 clearTimeout(timeoutId);
超時調用的代碼都是在全局做用域中執行的,所以函數中 this 的值在非嚴格模式下指向 window 對象,在嚴格模式下是 undefined
超時調用:在指定的時間事後執行代碼
使用 window 對象的 是 setInterval()方法,它接受兩個參數:要執行的代碼和以毫秒錶示的時間(即在執行代碼前須要等待多少毫秒)
//不建議傳遞字符串! setInterval ("alert('Hello world!') ", 10000); //推薦的調用方式 setInterval (function() { alert("Hello world!"); }, 10000);
調用 setInterval()方法一樣也會返回一個間歇調用 ID,該 ID 可用於在未來某個時刻取消間歇調用。要取消還沒有執行的間歇調用,可使用 clearInterval()方法並傳入相應的間歇調用 ID。取消間歇調用的重要性要遠遠高於取消超時調用,由於在不加干涉的狀況下,間歇調用將會一直執行到頁面卸載
//間歇調用方式 var num = 0; var max = 10; var intervalId = null; function incrementNumber() { num++; //若是執行次數達到了 max 設定的值,則取消後續還沒有執行的調用 if (num == max) { clearInterval(intervalId); alert("Done"); } } intervalId = setInterval(incrementNumber, 500); //超時調用實現(最佳模式) var num = 0; var max = 10; function incrementNumber() { num++; //若是執行次數未達到 max 設定的值,則設置另外一次超時調用 if (num < max) { setTimeout(incrementNumber, 500); } else { alert("Done"); } } setTimeout(incrementNumber, 500);
系統對話框
alert()方法:接受一個字符串並將其顯示給用戶。具體來講,調用alert()方法的結果就是向用戶顯示一個系統對話框,其中包含指定的文本和一個 OK(「肯定」)按鈕
confirm()方法:向用戶顯示一個系統對話框,除了顯示 OK 按鈕外,還會顯示一個 Cancel(「取消」)按鈕,兩個按鈕可讓用戶決定是否執行給定的操做;true 表示單擊了 OK,false 表示單擊了 Cancel 或單擊了右上角的 X 按鈕
if (confirm("Are you sure?")) { alert("I'm so glad you're sure! "); } else { alert("I'm sorry to hear you're not sure. "); }
prompt()方法:這是一個「提示」框,用於提示用戶輸入一些文本。提示框中除了顯示 OK 和 Cancel 按鈕以外,還會顯示一個文本輸入域,以供用戶在其中輸入內容;接受兩個參數:要顯示給用戶的文本提示和文本輸入域的默認值(能夠是一個空字符串);若是用戶單擊了 OK 按鈕,則 prompt()返回文本輸入域的值;若是用戶單擊了 Cancel 或沒有單擊OK 而是經過其餘方式關閉了對話框,則該方法返回 null
var result = prompt("What is your name? ", ""); if (result !== null) { alert("Welcome, " + result); }
除了上述三種對話框以外,Google Chrome 瀏覽器還引入了一種新特性。若是當前腳本在執行過程當中會打開兩個或多個對話框,那麼從第二個對話框開始,每一個對話框中都會顯示一個複選框,以便用戶阻止後續的對話框顯示,除非用戶刷新頁面
還有兩個能夠經過 JavaScript 打開的對話框,即「查找」和「打印」。這兩個對話框都是異步顯示的,可以將控制權當即交還給腳本。這兩個對話框與用戶經過瀏覽器菜單的「查找」和「打印」命令打開的對話框相同。而在 JavaScript 中則能夠像下面這樣經過 window 對象的 find()和 print()方法打開它們
//顯示「打印」對話框 window.print(); //顯示「查找」對話框 window.find();
屬性:
屬 性 名 | 例 子 | 說 明 |
---|---|---|
hash | "#contents" | 返回URL中的hash(#號後跟零或多個字符),若是URL中不包含散列,則返回空字符串 |
host | "www.wrox.com:80" | 返回服務器名稱和端口號(若是有) |
hostname | "www.wrox.com" | 返回不帶端口號的服務器名稱 |
href | "http://www.wrox.com" | 返回當前加載頁面的完整URL。而location對象的<brtoString()方法也返回這個值 |
pathname | "/WileyCDA/" 返回URL中的目錄和(或)文件名port "8080" | 返回URL中的目錄和(或)文件名 |
port | "8080" | 返回URL中指定的端口號。若是URL中不包含端口號,則這個屬性返回空字符串 |
protocol | "http:" | 返回頁面使用的協議。一般是http:或https: |
search | "?q=javascript" | 返回URL的查詢字符串。這個字符串以問號開頭 |
查詢字符串參數
function getQueryStringArgs(){ //取得查詢字符串並去掉開頭的問號 var qs = (location.search.length > 0 ? location.search.substring(1) : ""), //保存數據的對象 args = {}, //取得每一項 items = qs.length ? qs.split("&") : [], item = null, name = null, value = null, //在 for 循環中使用 i = 0, len = items.length; //逐個將每一項添加到 args 對象中 for (i=0; i < len; i++){ item = items[i].split("="); name = decodeURIComponent(item[0]); value = decodeURIComponent(item[1]); if (name.length) { args[name] = value; } } return args; } //假設查詢字符串是?q=javascript&num=10 var args = getQueryStringArgs(); alert(args["q"]); //"javascript" alert(args["num"]); //"10"
位置操做
assign()方法
location.assign("http://www.wrox.com");
location.href屬性
location.href = "http://www.wrox.com";
每次修改 location 的屬性(hash 除外),頁面都會以新 URL 從新加載
//假設初始 URL 爲 http://www.wrox.com/WileyCDA/ //將 URL 修改成"http://www.wrox.com/WileyCDA/#section1" location.hash = "#section1"; //將 URL 修改成"http://www.wrox.com/WileyCDA/?q=javascript" location.search = "?q=javascript"; //將 URL 修改成"http://www.yahoo.com/WileyCDA/" location.hostname = "www.yahoo.com"; //將 URL 修改成"http://www.yahoo.com/mydir/" location.pathname = "mydir"; //將 URL 修改成"http://www.yahoo.com:8080/WileyCDA/" location.port = 8080;
replace()方法:不會在歷史記錄中生成新記錄
<!DOCTYPE html> <html> <head> <title>You won't be able to get back here</title> </head> <body> <p>Enjoy this page for a second, because you won't be coming back here.</p> <script type="text/javascript"> setTimeout(function () { location.replace("http://www.wrox.com/"); }, 1000); </script> </body> </html>
reload()方法:從新加載當前顯示的頁面
location.reload(); //從新加載(有可能從緩存中加載) location.reload(true); //從新加載(從服務器從新加載)
屬性
window.navigator
檢測插件
對於非 IE 瀏覽器,可使用plugins 數組來達到這個目的。該數組中的每一項都包含下列屬性
//檢測插件(在 IE 中無效) function hasPlugin(name){ name = name.toLowerCase(); for (var i=0; i < navigator.plugins.length; i++){ if (navigator. plugins [i].name.toLowerCase().indexOf(name) > -1){ return true; } } return false; } //檢測 Flash alert(hasPlugin("Flash")); //檢測 QuickTime alert(hasPlugin("QuickTime"));
在 IE 中檢測插件的惟一方式就是使用專有的 ActiveXObject 類型,並嘗試建立一個特定插件的實例
//檢測 IE 中的插件 function hasIEPlugin(name){ try { new ActiveXObject(name); return true; } catch (ex){ return false; } } //檢測 Flash alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash")); //檢測 QuickTime alert(hasIEPlugin("QuickTime.QuickTime"));
典型的作法是針對每一個插件分別建立檢測函數
//檢測全部瀏覽器中的 Flash function hasFlash(){ var result = hasPlugin("Flash"); if (!result){ result = hasIEPlugin("ShockwaveFlash.ShockwaveFlash"); } return result; } //檢測全部瀏覽器中的 QuickTime function hasQuickTime(){ var result = hasPlugin("QuickTime"); if (!result){ result = hasIEPlugin("QuickTime.QuickTime"); } return result; } //檢測 Flash alert(hasFlash()); //檢測 QuickTime alert(hasQuickTime());
plugins 集合有一個名叫 refresh()的方法,用於刷新 plugins 以反映最新安裝的插件。這個方法接收一個參數:表示是否應該從新加載頁面的一個布爾值。若是將這個值設置爲 true,則會從新加載包含插件的全部頁面;不然,只更新 plugins集合,不從新加載頁面
註冊處理程序
registerContentHandler()方法接收三個參數:要處理的 MIME 類型、能夠處理該 MIME類型的頁面的 URL 以及應用程序的名稱
navigator.registerContentHandler("application/rss+xml", "http://www.somereader.com?feed=%s", "Some Reader");
registerProtocolHandler()方法接收三個參數:要處理的協議(例如,mailto 或 ftp)、處理該協議的頁面的 URL 和應用程序的名稱
navigator.registerProtocolHandler("mailto", "http://www.somemailclient.com?cmd=%s", "Some Mail Client");
screen 對象基本上只用來代表客戶端的能力,其中包括瀏覽器窗口外部的顯示器的信息,如像素寬度和高度等;這些信息常常集中出如今測定客戶端能力的站點跟蹤工具中,但一般不會用於影響功能。不過,有時候也可能會用到其中的信息來調整瀏覽器窗口大小,使其佔據屏幕的可用空間
window.resizeTo(screen.availWidth, screen.availHeight);
涉及移動設備的屏幕大小時,狀況有點不同。運行 iOS 的設備始終會像是把設備豎着拿在手裏一
樣,所以返回的值是 768×1024。而 Android 設備則會相應調用 screen.width 和 screen.height 的值
history 對象保存着用戶上網的歷史記錄,從窗口被打開的那一刻算起。由於 history 是 window對象的屬性,所以每一個瀏覽器窗口、每一個標籤頁乃至每一個框架,都有本身的 history 對象與特定的window 對象關聯
使用 go()方法能夠在用戶的歷史記錄中任意跳轉,能夠向後也能夠向前。這個方法接受一個參數,表示向後或向前跳轉的頁面數的一個整數值。負數表示向後跳轉(相似於單擊瀏覽器的「後退」按鈕),正數表示向前跳轉(相似於單擊瀏覽器的「前進」按鈕)
//後退一頁 history.go(-1); //前進一頁 history.go(1); //前進兩頁 history.go(2);
也能夠給 go()方法傳遞一個字符串參數,此時瀏覽器會跳轉到歷史記錄中包含該字符串的第一個位置——可能後退,也可能前進,具體要看哪一個位置最近。若是歷史記錄中不包含該字符串,那麼這個方法什麼也不作
//跳轉到最近的 wrox.com 頁面 history.go("wrox.com"); //跳轉到最近的 nczonline.net 頁面 history.go("nczonline.net");
另外,還可使用兩個簡寫方法 back()和 forward()來代替 go()。顧名思義,這兩個方法能夠模仿瀏覽器的「後退」和「前進」按鈕
//後退一頁 history.back(); //前進一頁 history.forward();
history 對象還有一個 length 屬性,保存着歷史記錄的數量。這個數量包括全部歷史記錄,即全部向後和向前的記錄。對於加載到窗口、標籤頁或框架中的第一個頁面而言,history.length 等於 0。經過像下面這樣測試該屬性的值,能夠肯定用戶是否一開始就打開了你的頁面
if (history.length == 0){ //這應該是用戶打開窗口後的第一個頁面 }
一、瀏覽器對象模型(BOM)以 window 對象爲依託,表示瀏覽器窗口以及頁面可見區域。同時,window
對象仍是 ECMAScript 中的 Global 對象,於是全部全局變量和函數都是它的屬性,且全部原生的構造函數及其餘函數也都存在於它的命名空間下。本章討論了下列 BOM 的組成部分:
二、BOM 中還有兩個對象:screen 和 history,但它們的功能有限。screen 對象中保存着與客戶端顯示器有關的信息,這些信息通常只用於站點分析。history 對象爲訪問瀏覽器的歷史記錄開了一個小縫隙,開發人員能夠據此判斷歷史記錄的數量,也能夠在歷史記錄中向後或向前導航到任意頁面