window對象
BOM的核心對象是window,它表示瀏覽器的一個實例。在瀏覽器中,window對象有雙重角色,它既是通過JavaScript訪問瀏覽器窗口的一個接口,又是ECMScript規定的Global對象。
全局作用域
由于window對象同時扮演著ECMAScript中Global對象的角色,因此所有在全局作用域中聲明的變量、函數都會變成window對象的屬性和方法。來看下面的例子:
var age=29; function sayAge(){ alert(this.age); } alert(window.age); //29 sayAge(); //29 window.sayAge(); //29
定義全局變量與在window對象上直接定義屬性還有一點差別就是:全局變量不能通過delete操作符刪除,而直接在window對象上定義的屬性可以,例如:
var age=29; window.color="red"; delete window.age' //在IE<9時拋出錯誤,在其他所有瀏覽器中都返回false delete window.color //在IE<9時拋出錯誤,在其他所有瀏覽器中都返回true alert(window.age) ;//29 alert(window.color); //undefined
原因是使用var語句添加的window屬性有一個名為[[Configurable]]的特性,這個特性的值被設置為false,因此這樣定義的屬性不可通過delete操作符刪除。
另外,還要記住一件事:嘗試訪問未聲明的變更會拋出錯誤,但是通過查詢window對象,可以知道某個可能未聲明的變更是否存在,如:
//這里會拋出錯誤,因為oldValue未定義 var newValue=oldValue; //這里不會拋出錯誤,因為這是一次屬性查詢 //newValue的值是undefined var newValue=window.oldValue;
窗口關系及框架
top對象始終指向最高(最外)層的框架,也就是瀏覽器窗口。與框架有關的最后一個對象是self,它始終指向window;實際上,self和window對象可以互換使用。引入
self對象的目的只是為了與top和parent對象對應起來,因此它不格外包含其它值。
窗口位置
使用下面的代碼可以跨瀏覽器取得窗口左邊和上邊的位置。
var leftPos=(typeof windwow.screenLeft=="number")? window.screenLeft:window.screenX; var topPos=(typeof windwow.screenTop=="number")? window.screenTop:window.screenY;
使用resizeTo()和resizeBy()方法可以調整瀏覽器窗口的大小 。
導航和打開窗口
window。open("http://www.wrox.com","topFrame");
如果有一個名叫"topFrame"的窗口或者框架,就會在該窗口或框架加載這個URL;否則,就會創建一個新窗口并將其命名為"topFrame".
在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;
將opener屬性設置為Null就是告訴瀏覽器新創建的標簽頁不需要與打開它的標簽頁通信,因此可以在獨立的進程中運行。
間隙調用和超時調用
JavaScript是一個單線程序的解釋器,因此一定時間內只能執行一段代碼。為了控制要執行的代碼,就有一個JavaScript任務隊列。這些任務會按照將它們添加到隊列的順序執行。
setTimout()的第二個參數告訴JavaScript再過多長時間把當前任務添加到隊列中。如果隊列是空的,那么添加的代碼會立即執行;如果隊列不是空的,那么它就要等前面的代碼
執行完以后再執行。
要取消尚未執行的超時調用計劃,可以調用clearTimeout()方法并將相應的超時調用ID作為參數傳遞給它,如下所示:
//設置超時調用 var timeoutId=setTimout(function(){ alert("Hello world!"); },1000); //注意:把它取消 clearTimeout(timeoutId);
間隙調用與超時調用類似,只不過它會按照指定的時間間隔重復執行代碼,直至間歇調用被取消或者頁面被卸載。設置間歇調用的方法是setInterval().
//不建議傳遞字符串 setInterval("alert('Hello world!')",10000); //推薦的調用方式 setInterval(function(){ alert("Hello world!"); },10000);
雖然這兩種調用方式都沒有問題,但由于傳字符串可能導致性能損失,因此不建議以字符串作為第一個參數。
也可以用clearInterval()方法并傳入相應的間隙ID來取消。以下是一個常見的使用間歇調用的例子:
var num=0; var max=10; var intervalId=null; function incrementNumber(){ num++; //如果執行次數達到max設定的值,則取消后續尚未執行的調用 if(num==max) { clearTimeout(intervalId); alert("Done"); } } intervalId=setInterval(incrementNumber,500);
這個例子也可以用超時調用來實現,如下:
var num=0; var max=10; function incrementNumber(){ num++; //如果執行次數未達到max設定的值,則設置另一次超時調用 if(num<max) setTimout(incrementNumber,500); else alert("Done"); } setTimout(incrementNumber,500);
一般認為,使用超時調用來模擬間歇調用是一種最佳模式。在開發環境下,很少使用真正的間歇調用,原因是后一個間歇調用可能會在前一個間歇調用結束之前啟動。
而像前面示例中那樣使用超時調用,則完全可以避免這一點。所以,最好不要使用間歇調用。
更簡潔的寫法:
setTimeout(function(){ //processing setTimeout(arguments.callee, interval); }, interval);
文章列表