《javascript高級程序設計》讀書筆記(六)

第8章 BOM——瀏覽器對象模型

  1. window對象——BOM的核心

BOM的核心對象是window,它表示瀏覽器的一個實例。
因爲window對象同時扮演着ECMAScript中Global對象的角色,所以全部全局做用域中聲明的變量、函數都會變成window對象的屬性和方法。javascript

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

拋開全局變量會成爲window對象的屬性不談,定義全局變量與在window對象上直接定義屬性仍是有一點差異:全局變量不能經過delete操做符刪除,而直接在window對象上定義的屬性能夠。java

窗口位置:編程

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

窗口大小:
跨瀏覽器肯定一個窗口的大小不是一件簡單的事。各個瀏覽器對窗口大小有不一樣的定義,即便相同的屬性,在各個瀏覽器中表現的也不一樣。
雖然最終沒法肯定瀏覽器窗口自己的大小,但卻能夠取得頁面視口的大小。瀏覽器

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.open()方法既能夠導航到一個特定的URL,也能夠打開一個新的瀏覽器窗口。
這個方法能夠接收4個參數:要加載的URL、窗口目標、一個特性字符串以及一個表示新頁面是否取代瀏覽器歷史記錄中當前加載頁面的布爾值。緩存

window.open("http://www.baidu.com/", "topFrame");
//等同於<a href="http://www.baidu.com" target="topFrame"></a>

第三個參數是一個都喊分割的設置字符串,表示在新窗口中都顯示那些特性。
image.png安全

window.open("http://www.wrox.com/","wroxWindow","height=400,window=400,top=10,left=10,resizable=yes");
//這行代碼會打開一個新的能夠調整大小的窗口,窗口初始大小爲400*400像素,而且距屏幕上沿和左邊各10像素。

對於瀏覽器的主窗口,若是沒有獲得用戶的容許是不能關閉它的,可是彈出窗口也就是經過window.open()打開的彈出窗口,能夠調用top.close()在不經用戶容許的狀況下關閉本身。服務器

可是有個問題:大多數瀏覽器都內置有彈出窗口屏蔽程序。用戶能夠將絕大多數不想看到的彈出窗口屏蔽掉。
在彈出窗口被屏蔽時,能夠考慮兩種可能性。
若是是瀏覽器內置的屏蔽程序阻止的彈出窗口,那麼window.open()極可能會返回null;若是是瀏覽器擴展或其餘程序阻止的彈出窗口,window.open()會拋出錯誤。
所以想要準確地檢測出彈出窗口是否被屏蔽,必須在檢測返回值的同時,將對window.open()的調用封裝在一個try-catch塊中網絡

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

間歇調用和超時調用
JavaScript是單線程語言,但它容許經過設置超時值和間隙時間值來調用代碼在特定的時刻執行。
超時調用須要使用window對象的setTimeout()方法,它接受兩個參數:要執行的代碼和以毫秒錶示的時間—即在執行代碼前須要等待多少毫秒。框架

setTimeout(function(){
 alert(「Hello world!」);
}, 1000);

第一個參數一般是一個函數,第二個參數是一個表示等待多長時間的毫秒數,但通過該時間後指定的代碼不必定會執行。
setTimeout()的第二個參數告訴JavaScript再過多長時間把當前任務添加到隊列中,若是隊列是空的,那麼添加的代碼會當即執行;若是隊列不是空的,那麼它就要等前面的代碼執行完了之後再執行。
要取消還沒有執行的超時調用計劃,能夠調用clearTimeout()方法。函數

//設置超時調用
var timeoutId = setTimeout(function(){
 alert(「Hello world!」);
}, 1000);
//注意:把它取消
clearTimeout(timeoutId);     //在設置超時調用以後立刻又調用了clearTimeout(),結果就跟什麼也沒發生同樣。

只要是在指定的時間還沒有過去以前調用clearTimeout(),就能夠徹底取消超時調用。
間歇調用須要使用window對象的setInterval()方法,它會按照執行的時間間隔重複執行代碼,直至間歇調用被取消或者頁面被卸載。

setInterval(function(){
 alert(「Hello world!」);
}, 10000);

取消間歇調用的重要性要遠遠高於取消超時調用,由於在不加干涉的狀況下,間歇調用將會一直執行到頁面卸載。

var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber(){
 num++;
 //若是執行次數達到了max設定的值,則取消後續還沒有執行的調用
 if(num == max){
  clearInterval(intervalId);
  alert(「Done」);
 }
}
intervalId = setInterval(incrementNumber, 500);

變量num每半秒鐘遞增一次,當遞增到最大值時就會取消先前設定的間歇調用。
這個模式也可使用超時調用來實現。

var num = 0;
var max = 10;
function incrementNumber(){
 num++;
 //若是執行次數達到了max設定的值,則設置另外一次超時調用
 if(num < max){
  setTimeout(incrementNumber, 500);
 }else{
  alert(「Done」);
 }
}
setTimeout(incrementNumber, 500);

系統對話框
瀏覽器經過alert()、confirm()和prompt()方法能夠調用系統對話框向用戶顯示消息。
它們的外觀由操做系統及(或)瀏覽器設置決定,而不是由CSS決定。
此外,經過這幾句歌方法打開的對話框都是同步和模擬的,也就是說,顯示這些對話框的時候代碼會中止執行,而關掉這些對話框後代碼又會恢復執行。

alert(「Hello world!」);
confirm(「Are you sure?」);
prompt(「What’s your name?」,」her」);

2.location對象
location是最有用的BOM對象之一,它提供了與當前窗口中加載的文檔有關的信息,還提供了一些導航功能。
image.png
雖然經過上面的屬性能夠訪問到location對象的大多數信息,但其中訪問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 = decodeURLComponent(item[0]);
    value = decodeURLComponent(item[1]);
    if(name.length){
        args[name] = value;
    }
 }
 return args;
}

//假設查詢字符串是?q=javascript&num=10
var args = getQueryStringArgs();
alert(args["q"]);   //"javascript"
alert(args["name"]);  //"10"

在改變瀏覽器位置的方法中,最經常使用的設置location.href屬性。

//假設初始URL爲http://www.wrox.com/WileyCDA/

//跳轉到http://www.wrox.com
location.href = "http://www.wrox.com";

//將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 = "http://www.yahoo.com";

//將URL修改成"http://www.yahoo.com/mydir/"
location.pathname = "mydir";

//將URL修改成"http://www.yahoo.com:8080/WileyCDA/"
location.port = "8080";

每次修改location的屬性(hash除外),頁面都會以新URL從新加載。
上述任何一種方式修改URL以後,瀏覽器的歷史記錄中就會生成一條新紀錄,所以用戶經過單擊"後退"按鈕都會導航到前一個頁面。
要禁用這種行爲,能夠經過replace()方法,不會再歷史記錄中生成新紀錄。
reload()方法,做用是從新加載當前顯示的頁面。
若是要強制從服務器從新加載,則須要像下面這樣子爲該方法傳遞參數true。

location.reload();    //從新加載(有可能從緩存中加載)
location.reload(true);   //從新加載(從服務器從新加載)

位於reload()調用以後的代碼可能會也可能不會執行,這要取決於網絡延遲或系統資源等因素。爲此最好將reload()放在代碼最後一行。

3.history對象
history對象保存着用戶上網的歷史記錄,從窗口被打開的那一刻算起。
出於安全方面的考慮,開發人員沒法得知用戶瀏覽過的URL。
使用go()方法能夠在用戶的歷史記錄中任意跳轉,能夠向後也能夠向前。

history.go(-1);//後退一頁
history.go(1);//前進一頁
history.go(2);//前進兩頁
history.go("wrox.com");//跳轉到最近的wrox.com頁面
history.back();//後退一頁
history.forward();//前進一頁

也能夠給go()方法傳遞一個字符串參數,會跳轉到歷史記錄中包含該字符串的第一個位置,可能前進可能後退,看哪一個位置最近,若是歷史記錄中不包含該字符串,則什麼都不作。
肯定用戶是否一開始就打開了你的頁面

if(history.length == 0){
    //這應該是用戶打開窗口後的第一個頁面
}

小結
瀏覽器對象(BOM)以window對象爲依託,表示瀏覽器窗口以及頁面可見區域。
在使用框架時,每一個框架都有本身的window對象以及全部構造函數及其餘函數的副本,每一個框架都保存在frames集合中,能夠經過位置或經過名稱來訪問。
top對象始終指向最外圍的框架,也就是整個瀏覽器窗口。
parent對象表示包含當前框架的框架,而self對象則回指window。
使用location對象能夠經過編程方式來訪問瀏覽器的導航系統。實質性相應的屬性,能夠逐段或總體性地修改瀏覽器的URL。
調用replace()方法能夠導航到一個新URL,同時該URL會替換瀏覽器歷史記錄中當前顯示的頁面。
navigator對象提供了與瀏覽器有關的信息。

今天就先到這兒咯,今天下班晚,就先啃到這兒啦

相關文章
相關標籤/搜索