1. 程式人生 > >JS學習7(BOM)

JS學習7(BOM)

BOM是瀏覽器物件模型,它提供了很多用於訪問瀏覽器的功能。

window物件

BOM的核心物件是window,它表示瀏覽器的一個例項。在瀏覽器中window既是JS訪問瀏覽器視窗的一個介面,又是ES裡規定的Global物件。也就是說在網頁中定義的任何一個物件,變數和函式都以window作為其Global物件。

全域性作用域

在全域性作用域中宣告的變數,函式都會變成window物件的屬性和方法。

var age = 29;
window.color = "red";
function sayAge(){ 
    alert(this.age);
}
alert(window.age); //29 
sayAge(); //29 window.sayAge(); //29

不過定義全域性變數和直接在window上定義屬性還是不同的,全域性變數不能通過delete操作符刪除:

delete window.age;  //returns false
delete window.color; //returns true

這是因為直接使用var新增的全域性變數的[[Configurable]]為false。
在嘗試訪問未宣告的變數會丟擲錯誤,但是通過查詢window物件可以知道某個可能未宣告的變數是否存在:

var newValue = oldValue;   //因為oldValue未定義,這樣做會報錯
var newValue = window.oldValue; //這裡就不會有錯誤,這是一次屬性查詢,newValue的值是undefined

視窗關係及框架

如果頁面中包含框架,則每個框架都有自己的window物件,且儲存在frames集合中。可以通過數值索引或框架名稱來訪問響應的window物件。每個window物件都有一個name屬性其中包含框架名稱。不過最高層視窗例外,除非是通過window.open()開啟的,否則最高層視窗的window物件的name屬性不會包含任何值。

<html>
    <head>
        <title
>
Frameset Example</title> </head> <frameset rows="160,*"> <frame src="frame.htm" name="topFrame"> <frameset cols="50%,50%"> <frame src="anotherframe.htm" name="leftFrame"> <frame src="yetanotherframe.htm" name="rightFrame"> </frameset> </frameset> </html>

這裡一共有三個框架,在最高層視窗中,你可以使用window.frames[0]或window.frames[“topFrame”]來訪問這些框架。不過鑑於在這些框架中每個都有自己的window物件,最好使用top物件來代替windows。top很確定的指向最外層的框架的window物件,也就是瀏覽器視窗。即便是在某個內層框架使用時也不會出錯。top.frames[0]或top.frames[“topFrame”]。
與上面top相對的window物件就是parent,parent始終指向當前框架的直接上層框架。
最後還有一個self物件,這個物件始終指向windows,它倆是等價的。
window.parent window.top,因為這兩個返回的同樣是其他框架的window物件,所以可以鏈式的繼續訪問下去。
要注意的是,在使用框架的情況下,瀏覽器中會出現多個Global物件,每個框架中定義的全域性變數都會變成本框架中Global(window)的屬性,每個window中都包含原生型別的建構函式,每個框架都有自己的建構函式。不過它們並不相等。top.Object和top.frames[0].Object並不相等。所以跨框架傳遞物件時使用instanceOf是有問題的。

視窗位置

window物件代表視窗相對於螢幕左邊和上邊的位置對於不同的瀏覽器有:screenLeft和screenTop或screenX和screenY。保險起見可以使用下面的辦法來獲取:

var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;

要注意的是,瀏覽器對這兩個屬性的返回規則也不大一樣,有的就算在某個子框架裡的window物件上呼叫也只會返回頂級window物件的位置,有的則會返回子框架的精確位置。
頂級的window物件還有兩個方法:moveTo()和moveBy()用來將視窗移到或按偏移量移到某位置。

window.moveTo(200,300);
window.moveBy(0,100);

不同瀏覽器對這個的實現也不大一樣。。。。有時還會被禁用掉。。。

視窗大小

有4個屬性來表示視窗的大小innerWidth、innerHeight、outerWidth、outerHeight。不同的瀏覽器對這個的實現並不相同。對於outer的幾個屬性,有的瀏覽器表示瀏覽器視窗大小,有的表示頁面檢視區域大小。不過inner屬性大家基本都表示頁面檢視區域的大小。
還有document.documentElement.clientWidth或document.documentElement.clientHeight。
document.body.clientWidth或document.body. clientHeight獲得的也是頁面檢視區大小。
最保險的獲取視窗大小的辦法:

var pageWidth = window.innerWidth,     
    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;     
        } 
    } 

對於移動瀏覽器有兩個概念,可見視口和佈局視口。可見視口代表螢幕上可見頁面區域的大小, 隨著頁面的縮放這些值會改變。通過window.innerWidth獲取。佈局視口是渲染後頁面的實際大小。不會隨著縮放改變。document.documentElement. client- Width存著這些。移動IE有差別。。。。。。
resizeTo和resizeBy可以調整視窗大小,一個是調整到,一個基於當前。

導航和開啟視窗

window.open()方法這個方法接收4個引數,要載入的URL、視窗目標、一個特性字串以及一個表示新頁面是否取代瀏覽器歷史記錄中當前載入頁的布林值。最後一個引數只在不開啟新視窗的情況下使用。

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);
wroxWin.close(); 
alert(wroxWin.opener == window);   //true 

視窗目標除了視窗名或框架名還可以是:_self _parent _top _blank
新建立的window物件會有一個指標指向開啟它的原始視窗,但是視窗並不記錄它開啟的視窗們。
有時彈出視窗會被遮蔽,這樣window.open()會彈出null或報錯。
檢測視窗是否被遮蔽的完全辦法:

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!"); 
} 

間歇呼叫和超時呼叫

超時呼叫

var timeoutId = setTimeout(function() {      
    alert("Hello world!");  
}, 1000); 
clearTimeout(timeoutId); 

JS是單執行緒的,所以上面的程式碼只保證會在1秒後將要執行的程式碼新增到任務佇列,如果這時任務佇列是空的,那ok。
這個函式會返回一個數值ID,這個ID是即將執行的那段程式碼的唯一標識。可以通過他來取消尚未執行的超時呼叫。
間歇呼叫

var num = 0; 
var max = 10; 
var intervalId = null;  
function incrementNumber() {     
    num++;  
    //到達最大值停止   
    if (num == max) {         
        clearInterval(intervalId);         
        alert("Done");     
    } 
}  
intervalId = setInterval(incrementNumber, 500); 

間歇呼叫有一個問題,就是後一個間歇呼叫有可能在前一個結束後沒到規定時間就啟動,而且如果沒有正確的停下來,間歇呼叫將會一直執行下去。所以使用超時呼叫來模擬間歇呼叫是一個很好的辦法。

var num = 0; 
var max = 10;  
function incrementNumber() {     
    num++;       
    if (num < max) {         
        setTimeout(incrementNumber, 500);     
    } else {         
        alert("Done");   
    } 
}  
setTimeout(incrementNumber, 500); 

系統對話方塊

alert()、confirm()、prompt()。他們是同步的,會阻止程式碼執行
confirm()
這個有兩個按鈕,確認和取消,使用者可以根據自己的需要選擇,這個函式也會返回對應的true或false

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,會返回使用者填寫的字串,否則返回null。

var result = prompt("What is your name? ", ""); 
if (result !== null) {     
    alert("Welcome, " + result); 
} 

window.print()和window.find()顯示瀏覽器的查詢和列印對話方塊。他們是非同步的,和從瀏覽器選單開啟一樣。

location物件

location物件代表了當前視窗所在位置,可以通過他來獲取位置,也可以用他來設定位置。這個物件既是window的屬性又是document的屬性,是同一個引用。

獲取

  • hash:”#contents”。URL中hash#
  • host:”www.wrox.com:80”。伺服器名和埠號
  • hostname:”www.wrox.com”。伺服器名
  • href:”http:/www.wrox.com”。完整URL
  • pathname:”/WileyCDA/”。URL中的目錄或檔名
  • port:”8080”
  • protocol:”http:”
  • search:”?q=javascript”。查詢字串

設定

立即開啟一個新的URL並在瀏覽器的歷史記錄中生成一條記錄

//跳到http://www.baidu.com
location.assign("http://www.baidu.com");
window.location = "http://www.baidu.com"; 
location.href = "http://www.baidu.com"; 

// 初始URL http://www.wrox.com/WileyCDA/  
location.hash = "#section1";  //"http://www.wrox.com/WileyCDA/#section1" 
location.search = "?q=javascript";  //"http://www.wrox.com/WileyCDA/?q=javascript" 
location.hostname = "www.yahoo.com";  //"http://www.yahoo.com/WileyCDA/" 
location.pathname = "mydir";  //"http://www.yahoo.com/mydir/" 
location.port = 8080;  //"http://www.yahoo.com:8080/WileyCDA/" 

開啟新的URL但不生成歷史記錄,也就不能後退

location.replace("http://www.wrox.com/"); 

重新載入當前頁面

location.reload();        //自動選擇最有效的載入方式
location.reload(true);    //強制從伺服器載入

navigator物件

這裡面主要包含著一些瀏覽器和作業系統的資訊。
appCodeName
appMinorVersion
appName
appVersion
buildID
cookieEnabled
cpuClass
javaEnabled()
language
mimeTypes
onLine
opsProfile
oscpu
platform
plugins
preference()
product
productSub
registerContentHandler()
registerProtocolHandler()
securityPolicy
systemLanguage
taintEnabled()
userAgent
userLanguage
userProfile
vendor
vendorSub

檢查外掛

IE和非IE的差別太大,建立兩套檢測方法。

//非IE,直接訪問plugins陣列查名字就行,名字可以是一部分不一定準確
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; 
}
//IE得知道確切的名字,程式碼嘗試例項化一個這樣的物件,成功了就代表有這個外掛
function hasIEPlugin(name){     
    try {         
        new ActiveXObject(name);         
        return true;     
    } catch (ex){         
        return false;     
    } 
} 
function hasQuickTime(){     
    var result = hasPlugin("QuickTime");     
    if (!result){         
        result = hasIEPlugin("QuickTime.QuickTime");     
    }     
    return result; 
}
alert(hasQuickTime()); 

註冊處理程式

registerContentHandler()接收3個引數,要處理的MIME型別,可以處理該MIME型別頁面的URL以及應用程式的名稱。

navigator.registerContentHandler("application/rss+xml",     "http://www.somereader.com?feed=%s", "Some Reader"); 

registerProtocolHandler()接收3個引數,要處理的協議,可以處理該協議的URL以及應用程式的名稱。

navigator.registerProtocolHandler("mailto",     "http://www.somemailclient.com?cmd=%s", "Some Mail Client"); 

screen物件

基本就是可以獲取各種東西的大小
availHeight — — — — availLeft — — availTop — — availWidth — — — — bufferDepth — colorDepth — — — —deviceXDPI deviceYDPI fontSmoothingEnabled height — — — — left — logicalXDPI DPI — logicalYDPI DPI — pixelDepth

history物件

history是window物件的屬性,每個頁面都有自己的history物件與自己的window物件關聯。出於安全考慮,不能獲得使用者瀏覽過得URL,通過go方法可以在不知道URL的情況下跳轉。

history.go(-1); 
history.go(2); 
history.go("wrox.com"); //跳轉到最近的包含這個字串的頁面
history.back(); 
history.forward(); 

history還有一個length屬性,這個可以用來判斷歷史列表中有幾個頁面。對於剛開啟的頁面歷史記錄中的就是1。