第八章 BOM
1. window對象 :
BOM的核心對象是 window,他表示瀏覽器的一個實例沙郭。在瀏覽器中,window 對象有雙重角色辟拷,它既是通過JavaScript訪問瀏覽器窗口的一個接口缴阎,又是ECMAScript規(guī)定的 Global 對象蝙斜。這意味著在網(wǎng)頁中定義的任何一個對象,變量泌绣,函數(shù)钮追,都以 window 作為其 Global 對象。
2. 全局作用域 :
var age = 29;
function sayAge(){
alert(this.age);
}
alert(window.age); //29
sayAge(); //29
window.sayAge(); //29
3. 窗口關(guān)系及框架 :
如果頁面包含框架阿迈,那么每個框架都將擁有自己的 window 對象元媚,并且保存在 frames 集合中,在 frames 集合中,可以通過數(shù)值索引(從0開始刊棕,從左到右炭晒,從上到下)或者框架名稱來訪問相應(yīng)的 window 對象,每個 window 對象都有一個 name 屬性甥角,其中包含框架的名稱网严。
<html>
<head>
<title>Framest Example</title>
</head>
<frameset row = "160,*">
<frame src = "frame.htm" name = "topFrame">
<frameset cols = "50%,50%">
<frame src = "bottomLeft.htm" name = "leftFrame">
<frame src = "bottomRight.htm" name = "rightFrame">
</frameset>
</frameset>
</html>
以上代碼創(chuàng)建了一個框架集,其中一個框架居上嗤无,兩個居下震束。下面我們來列舉幾種方法用來表示這三個框架集。
上部的框架集:
window.frames[0]
window.frames[“topFrame”]
top.frames[0]
top.frames[“topFrame”]
frames[0]
frames[“topFrame”]
下部的左側(cè)框架集:
window.frames[1]
window.frames[“l(fā)eftFrame”]
top.frames[1]
top.frames[“l(fā)eftFrame”]
frames[1]
frames[“l(fā)eftFrame”]
下部的右側(cè)框架集:
window.frames[2]
window.frames[“rightFrame”]
top.frames[2]
top.frames[“rightFrame”]
frames[2]
frames[“rightFrame”]
這里來解釋下 top,top是一個對象当犯,始終指向最外層的框架驴一,也就是瀏覽器窗口。
與 top 相對的另一個 window 對象是 parent灶壶,顧名思義肝断,parent 對象始終指向當(dāng)前框架的直接上層框架。在某些情況下驰凛,parent 有可能等于 top,但在沒有框架的時候胸懈,parent 肯定等于 top(此時它們都等于 window)
另外,與框架有關(guān)的最后一個對象是 self,它始終指向 window恰响,實際上 self 和 window 對象可以互換著使用趣钱。
最后,要說明的是這些對象都是 window 的屬性胚宦,可以通過 window.top,window.parent 等形式來訪問首有。同時,這也意味著可以將不同層次的 window 對象連輟起來枢劝,如 window.parent.parent.frames[0]井联。
4. 窗口位置 :
用來確定和修改窗口位置屬性和方法有很多,先來說獲取窗口位置的方法...
比如 IE您旁,Safari,Opera,Chrome提供了 screenLeft 和 screenTop 屬性烙常,分別用于表示窗口相當(dāng)于屏幕左邊和上邊的位置.
fireFox則使用 screenX 和 screenY 來表示。
所以鹤盒,萬全之策應(yīng)該可以跨瀏覽器來取得窗口位置蚕脏。
var leftPos = (typeof window.screenleft == "number") ? window.screenleft : window.screenX;
var rightPos = (typeof window.screenright == "number") ? window.screenright : window.screenY;
接下來說改變窗口位置的方法:
- moveBy() : 接收兩個參數(shù),分別是水平和垂直所要移動的像素數(shù)侦锯。
- moveTO() : 接收兩個參數(shù)驼鞭,分別是新位置的X坐標(biāo)值和Y坐標(biāo)值。
//將窗口移動到屏幕左上角
window.moveTo(0,0);
//將窗口向下移動100像素
window.moveBy(0,100);
//將窗口向左移動50像素
window.moveBy(-50,0);
需要說明的是尺碰,這兩個方法可能會被瀏覽器給禁用挣棕,而且這兩個方法都不適用于框架汇竭,只適用于window對象使用。
5. 窗口大小 :
窗口大小分兩種穴张,一種是獲取整個瀏覽器的寬和高细燎,這時就要用到 outerHeight 和 outerWidth 屬性。
另一種是除去工具欄皂甘,狀態(tài)欄玻驻,邊框等占位元素后剩余的凈長寬,這時要用到 innerHeight 和 innerWidth 屬性偿枕。
6. 導(dǎo)航和打開窗口 :
window.open() 方法接收4個參數(shù) : 要加載的URL璧瞬,窗口目標(biāo),一個特性字符串以及一個表示新頁面是否取代瀏覽器歷史記錄中當(dāng)前加載頁面的布爾值渐夸。通常只需傳入一個參數(shù)嗤锉,最后一個參數(shù)只在不打開新窗口的情況下使用。
//等同于<a target = "topFrame"></a>
window.open("http://www.fanyank.com","topFrame");
調(diào)用這行代碼墓塌,就如同用戶點擊了 href 屬性為 http://www.fanyank.com/ , target 屬性為 ”topFrame” 的鏈接瘟忱,如果有一個名叫“topFrame”的框架或者窗口,就會在該窗口或框架中加載這個URL苫幢;否則访诱,就會創(chuàng)建一個名叫“topFrame”的新窗口。
如果利用該方法創(chuàng)建了一個新窗口韩肝,那么那么第三個參數(shù)就是用來調(diào)整新窗口的各項屬性的触菜,如果沒有第三個參數(shù),將會創(chuàng)建一個默認(rèn)的新窗口哀峻。
第三個參數(shù)是一個逗號分隔的設(shè)置字符串涡相,下表列出了可以出現(xiàn)在這個字符串的設(shè)置選項。

注意 :整個特性字符串中不允許出現(xiàn)空格
window.open("http://www.fanyank.com/","newWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
這行代碼會打開一個新的可以調(diào)節(jié)大小的窗口剩蟀,窗口的初始大小為400*400像素催蝗,并且距離屏幕上邊和左邊各10像素。
window.open() 方法會返回一個指向新窗口的引用喻旷。引用的對象與其他的 window 對象大致類似生逸,但我們可以對其進(jìn)行更多的控制牢屋。例如且预,有的瀏覽器在默認(rèn)的情況下可能不允許我們針對主瀏覽器窗口調(diào)節(jié)大小或移動位置,但卻允許我們針對通過 window.open() 創(chuàng)建的窗口調(diào)節(jié)大小和移動位置烙无。通過這個返回對象锋谐,可以像操作其他窗口一樣操作新打開的窗口。
var newObject = window.open("http://www.fanyank.com/","newWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
//調(diào)整大小
newObject.resizeTo(500,500);
//移動位置
newObject.moveTo(100,100);
//關(guān)閉新打開的窗口
newObject.close();
7. 間歇調(diào)用和超時調(diào)用 :
JavaScript是單線程語言截酷,但它允許通過設(shè)置超時值和間歇時間值來調(diào)度代碼在特定的時刻執(zhí)行涮拗。
-
超時調(diào)用 : 在指定的時間過后執(zhí)行代碼。
超時調(diào)用需要使用 window 對象的 setTimeout() 方法,該方法接收兩個參數(shù):要執(zhí)行的代碼和以毫秒表示的時間三热,其中第一個參數(shù)可以是一個包含JavaScript代碼的字符串(和 eval() 函數(shù)中使用的字符串一樣)鼓择,也可以是一個函數(shù)。
//不建議傳遞字符串,這樣做可能會損失性能
setTimeout("alert('Hello world!')",1000);
//推薦的調(diào)用方式
setTimeout(function(){
alert("Hello world!");
},1000);
調(diào)用 **setTimeout()** 之后該方法會返回一個數(shù)值ID就漾,表示超時調(diào)用呐能。這個超值調(diào)用ID是計劃執(zhí)行代碼的唯一標(biāo)識符,可以用它來取消超時調(diào)用抑堡。
可以調(diào)用 **clearTimeout()** 方法來取消超時調(diào)用摆出。
```javascript
//設(shè)置超時調(diào)用
var timeoutId = setTimeout(function(){
alert("Hello world!");
},1000);
//取消超時調(diào)用
clearTimeout(timeoutId);
-
間歇調(diào)用 : 每隔一段時間就執(zhí)行一次代碼。
間歇調(diào)用要使用 window 對象的 setInterval() 方法首妖,接受的參數(shù)與 setTimeout() 相同偎漫,要執(zhí)行的代碼和每次執(zhí)行之前需要等待的毫秒數(shù)。
//和上面一樣有缆,不建議傳遞字符串
//推薦調(diào)用方式
setInterval(function(){
alert("Hello world!");
},10000);
調(diào)用 setInterval 方法后也會返回一個間歇調(diào)用ID象踊,該ID也是用來在將來的某個時刻取消間歇調(diào)用,但是在不加干涉的情況下棚壁,間歇調(diào)用將一直進(jìn)行通危,直到頁面關(guān)閉。
var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber(){
if(num == max){
clearInterval(intervalId);
alert("Done");
}
}
intervalId = setInterval(incrementNumber,1000);
需要說明的是灌曙,在開發(fā)中菊碟,很少真正的使用間歇調(diào)用,原因是后一個間歇調(diào)用可能會在前一個間歇調(diào)用之前啟動在刺。解決方法是我們可以通過超時調(diào)用來模擬間歇調(diào)用逆害。
var num = 0;
var max = 10;
function incrementNumber(){
num++;
if(num < max){
setTimeout(incrementNumber,1000);
}
else
alert("Done");
}
setTimeout(increment,1000);
8. 系統(tǒng)對話框 :
- alert() : 這里不再贅述。

- confirm() : 用戶將有兩個選擇(確定和取消)蚣驼,用戶點擊后魄幕,可以通過檢查 confirm() 方法返回的布爾值來確定用戶的點擊行為。

if(confirm("Are you sure"))
{
alert("I'm glad to hear you're sure!");
}
else
{
alert("I'm sorry to hear you're not sure");
}
- prompt() : 用于提示用戶輸入一些內(nèi)容颖杏,提示框中除了有確定和取消按鈕外纯陨,還有一個文本框來接受用戶的輸入。
該方法接受兩個參數(shù)留储,要顯示給用戶的文本提示和文本輸入域的默認(rèn)值(可以是一個空字符串)
返回值:返回用戶所輸入的值

var result = prompt("What's your name","Michael");
if(result !== null){
alert("Welcome," + result);
}
9. location對象 :
location 對象是最有用的BOM對象之一翼抠,它提供了與當(dāng)前窗口加載的文檔有關(guān)的信息,還提供了一些導(dǎo)航功能获讳。它的作用還表現(xiàn)在講URL解析為獨立的片段阴颖,讓開發(fā)人員可以通過不同的屬性來訪問這些字段。下表列出了 location 對象的所有屬性丐膝。

來看一個完整的URL
http://www.wrox.com:8080/wileyCDA/?q=javascript#contents
分解后就是:
location.protocol:”http:”
location.href:”http://www.wrox.com”
location.host:”www.wrox.com:80”
location.post:”8080”
location.pathname:”/wileyCDA/”
location.search:”?q=javascript”
location.hash:”#contents”
位置操作:
使用 location 對象可以改變?yōu)g覽器的URL量愧。
//常用的方式有兩種:
//使用assign方法
location.assign("http://www.wrox.com");
//使用href屬性
location.;
當(dāng)我們修改URL后钾菊,瀏覽器的歷史記錄就會增加一條新記錄,因此用戶點擊后退按鈕時偎肃,會導(dǎo)航到前一個頁面煞烫,要想禁用這種行為,可以使用 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>
與位置有關(guān)的最后一個方法是 reload()累颂。
作用是重新加載當(dāng)前頁面,如給方法不傳遞任何參數(shù)红竭,頁面就會以最有效的方法來重新加載,也就是說喘落,頁面自上次請求以來并沒有改變過茵宪,頁面就會從瀏覽器的緩存中加載,如果強制從服務(wù)器端加載瘦棋,就應(yīng)該給這個方法傳入一個參數(shù) true稀火。
//可能從瀏覽器緩存中加載
location.reload();
//強制從服務(wù)器端加載
location.reload(true);
10. navigator對象 :
navigator對象 現(xiàn)在已成為識別客戶端瀏覽器的標(biāo)準(zhǔn),與其他BOM對象一樣赌朋,每個瀏覽器的 navigator對象 也有著自己的一套屬性凰狞。下表列出了存在于所有瀏覽器的屬性和方法以及支持他們的瀏覽器版本。


這些 navigator對象 的屬性通常用于檢測瀏覽器的類型沛慢。
檢測插件 :
檢測瀏覽器中是否安裝了特定的插件是一種最常見的檢測例程赡若,對于非IE瀏覽器,可以使用 plugins數(shù)組 來達(dá)到這個目的团甲,該數(shù)組中的每一項都包含下列屬性逾冬。
- name : 插件的名字。
- description : 插件的描述躺苦。
- filename : 插件的文件名身腻。
- length : 插件所處理的MIME類型數(shù)量。
//檢測插件(在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中插件的方法匹厘,檢測IE中的插件比較麻煩嘀趟,因為IE不支持Netspace式的插件。在IE中檢測插件的唯一辦法就是使用專有的 ActiveXObject 類型愈诚,并嘗試創(chuàng)建一個特定插件的實例她按。IE是以COM對象的方式實現(xiàn)插件的,而COM對象使用唯一的標(biāo)識符來標(biāo)識炕柔,因此酌泰,要想檢查特定的插件就必須知到插件的標(biāo)識符。
//檢測IE中的插件
function hasIEplugin(name){
try{
new ActiveXObject(name);
return true;
}
catch(ex){
return fasle;
}
}
//檢測Flash
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash"));
//檢測QuickTime
alert(hasIEPlugin("QuickTime.QuickTime"));
最后是通用的方法汗唱。
//檢測所有瀏覽器中的Flash
//ShockwaveFlash.ShockwaveFlash是Flash的標(biāo)識符
function hasFlash(){
var result = hasPlugin("Flash");
if(!result){
result = hasIEplugin("ShockwaveFlash.ShockwaveFlash");
}
return result;
}
//檢測所有瀏覽器中的QuickTime
//QuickTime.QuickTime是Quick的標(biāo)識符
function hasQuick{
var result = hasPlugin("QuickTime");
if(!result)
{
result = hasIEplugin("QuickTime.QuickTime");
}
return result;
}
//檢測Flash
alert(hasFlash());
//檢測QuickTime
alert(hasQuickTime());
11. screen對象 :
JavaScript有幾個對象在編程中用處不大宫莱,Screen對象 就是其中一個。
Screen對象 基本上只用來表明客戶端的能力哩罪。其中包括瀏覽器外部窗口的信息授霸,如像素的寬度和高度等。每個瀏覽器中的 Screen對象 都包含著各不相同的屬性际插,下表列出了所有屬性及支持相應(yīng)屬性的瀏覽器碘耳。


12. history對象 :
history對象 保存著用戶上網(wǎng)的歷史記錄。因為 history 是 window 對象的屬性框弛,因此每個瀏覽器窗口辛辨,每個標(biāo)簽頁甚至每個框架,都有著自己的 history對象 與特定的 window對象 相關(guān)聯(lián)瑟枫。出于安全性方面考慮斗搞,開發(fā)人員無法得知用戶瀏覽過的URL,但是借助用戶訪問過的頁面列表慷妙,可以再不知道用戶實際URL的情況下實現(xiàn)后退和前進(jìn)僻焚。
history對象 有下列幾種方法:
go() : 在用戶的歷史記錄中任意跳轉(zhuǎn),接受一個參數(shù)膝擂,該參數(shù)表示跳轉(zhuǎn)頁面的一個整數(shù)值(負(fù)數(shù)表示向后跳轉(zhuǎn)虑啤,正數(shù)表示向前跳轉(zhuǎn))。
也可以給該方法傳遞一個字符串參數(shù)架馋,此時瀏覽器會跳轉(zhuǎn)到包含該字符串最近的歷史記錄的頁面上(可能前進(jìn)狞山,也可能后退),如果歷史記錄不包含該字符串叉寂,那么這個方法什么也不做萍启。
//go()方法
history.go(-1); //后退一頁
history.go(1); //前進(jìn)一頁
history.go(2); //前進(jìn)兩頁
//還可以使用兩個簡寫的方法來代替go()方法
history.back(); //后退一頁
history.forward(); //前進(jìn)一頁
除了上述幾個方法外,history對象 還有一個 length 屬性屏鳍,保存著歷史記錄的數(shù)量伊约。對于加載窗口,標(biāo)簽頁或框架中的第一個頁面而言孕蝉,history.length 等于0屡律,通過測試該屬性的值可以確定用戶是否一開始就打開了你的頁面。
//檢測用戶是否一開始就打開你的頁面
if(history.length == 0)
{
alert("Welcome");
}