javascript
JavaScript权威指南--window对象
知識要點
window對象及其客戶端javascript所扮演的核心角色:它是客戶端javascript程序的全局對象。本章介紹window對象的屬性和方法,這些屬性定義了不同的API,但是只有一部分實際上和瀏覽器窗口相關。window對象是以窗口命名的。
1.計時器
setTimeout()和setIterval()可以用來注冊在指定的時間之后單次或重復調用的函數。因為它們都是客戶端javascript中的重要全局函數,所以定義為window對象方法,但作為通用函數,其實并不會對窗口做什么事情。
window對象的setTimeout()方法用來實現一個函數在指定的毫秒后運行。setTimeout返回一個值,這個值可以傳給clearTimeout()用于取消這個函數的執行。
/**定時器應用函數* 安排函數f()在未來的調用模式* 在等待了若干時間后調用f()* 如果設置了interval并沒有設置end參數,則f()的調用不會停止* 只有制定了f(),才會從start=0時刻開始* 注意,調用invoke()不會阻塞,會立即返回* */ function invoke(f, start, interval, end) {if (!start) start = 0;//默認設置為0if(arguments.length <=2)//單次調用模式setTimeout(f,start);//start秒后調用felse{ //多次調用模式setTimeout(repeat,start);//若干秒后調用repeat()function repeat(){var h = setInterval(f,interval);//循環調用f()//在end結束后調用,嵌套是end已經定義了if(end) setTimeout(function(){clearInterval(h);},end);}} }談談setTimeout()和setInterval()問題
由于歷史原因,setTimeout()和setInterval()第一個參數可以作為字符串傳入。如果這么做,那這個字符串會在指定的超時時間或間隔之后求值(相當于執行eval()).除了前兩個參數之外,HTML5規范還允許setTimeout()和setInterval()傳入額外的參數,并且在調用函數的時候把這些參數傳遞過去。然而,如果需要支持IE的話,就不要應用此特性了。
如果以0毫秒時間調用setTimeout,那么指定的函數不會立刻執行。相反會把它放到隊里中,等到前面處于等待狀態的事件處理程序完全完成之后,再立刻調用它。
補充:
function parent(){ function child(){ setTimeout(child2(),1000); setTimeout(parent2(),1000); alert("use child1") } function child2(){ alert("use child2") } child(); } parent();//調用parent function parent2(){ alert("I’m your mather") }輸出:直接按順序輸出:2-1-l`m。給第一個參數添加雙引號成為字符串即可。
function parent(){ function child(){ setTimeout("child2()",1000); setTimeout("parent2()",1000); console.log("use child1") } function child2(){ console.log("use child2") } child(); } parent();//調用parent function parent2(){ console.log("I’m your mather") }輸出結果:
這說明setTimeout只能訪問全局對象的屬性和方法,而不能訪問私有作用域內的屬性和方法。其實setTimeout是個window對象的一個方法,f是作為window對象的一個方法調用的,其效果就像一個<script>標簽里面的代碼一樣只能訪問,對于函數里面的變量和方法是無法訪問的。這就是為什么建議使用函數代替字符串的一個原因。另外,傳遞字符串也有可能導致性能損失。
2.瀏覽器的定位和導航
window對象的location屬性引用的是Location對象,它表示該窗口中當前顯示的文檔的URL,并定義了方法使窗口載入新的文檔。
Document對象的location屬性也引用到Location對象:
window.location === document.location; //=>true 總是返回trueDocument對象也有一個URL屬性,是文檔首次載人后保存該文檔的URL靜態字符串。如果定位到文檔中的片段標識符(如#table-of-contens),Location對象會做相應的更新,而document.url屬性卻不會改變。
2.1.解析url
window對象的location屬性引用是Location對象,表示該窗口當前顯示的的文檔的URL。Location對象的href屬性是一個字符串,包含URL的完整文本。Location對象的toString()方法返回href屬性的值,因此會在隱式調用toString()情況下,使用location代替location.href。
var d = location.href; var c = location.toString(); console.log(d === c)這個對象的其它屬性,protocol,host,hostname,port,pathname和search分別表示URL的各個部分。它們稱為"URL分解",同時被Link對象(通過HTML文檔中的a和<area>元素創建)支持,參閱本書的第四部分,Location和Link項獲取詳細信息。
Location對象的hash和seerch比較有趣。如果有的話,hash表示URL中的“片段標識符 #xx”部分,search返回問號之后的URL,這部分通常是某種類型的查詢字符串。一般來說這部分內容是用來參數化URL并在其中嵌入參數的。常用于運行在服務器上的腳本,但在啟動JavaScript的頁面中也可以使用。
下面的例子展示了一個通用函數urlArgs()定義,可以用這個函數將參數從URL的search屬性中提取出來。該例子用到了decodeURIComponent(),后者是在客戶端Javascript定義的全局函數(參加本書第三章部分中的Global獲取詳細內容)。
/***這個函數來解析來自URL的查詢中串中的name=value參數* 它將name=value對象存儲在一個對象的屬性中,并返回該對象,這樣使用它** var args = urlArgs();//從URL中解析參數* var q = args.q ||"";//如果參數定義的話就使用它,否則使用默認值。* var n = args.n?parseInt(args.n):10**/ function urlArgs() {var args = {}; //空對象var query = location.search.substring(1); //?后的值var pairs = query.split("&");for (var i = 0; i < pairs.length; i++) { //對于每個片段var pos = pairs[i].indexOf('=');if (pos == -1) continue; //如果沒有找到的話,跳過var name = pairs[i].substring(0, pos); //提取namevar value = pairs[i].substring(pos + 1); //提取valuevalue = decodeURIComponent(value); //對value進行解碼args[name] = value;}return args; }2.2.載入新的文檔
Location對象的assign()方法可以使窗口載入并顯示你指定的url中的文檔。replace()方法也類似,但它在載入新的文檔之前會從瀏覽歷史把當前文檔刪除。如果腳本無條件的載入一個新的文檔,replace()方法是可能比assgin()方法更好的選擇。否則,后退按鈕會使用瀏覽器帶回原始文檔。而相同的腳本則會再次載入新文檔。如果檢測到用戶瀏覽器不支持某些特性來顯示功能齊全的版本,可以用location.replace()來載入靜態的HTML版本:
//如果瀏覽器不支持XMLHttpRequest對象//則將其重定向到一個不需要Ajax的靜態頁面 if (!XMLHttpRequest) location.replace("staticpage.html");注意,在這個例子中傳入replace()的是一個相對URL。相對URL是相對于當前頁面所在的目錄來解析的,就像將它們用于一個超鏈接中。
除了assign()和replace()方法,Location對象還定義了reload()方法,后者可以讓瀏覽器重新載入當前文檔。
使瀏覽器跳轉到新頁面的一種更傳統的方法是直接賦值給location:
location = "https://segmentfault.com/";也可用相對URL,它會對其進行解析:
location = "page.html";純粹的片段標識符也是url的一種類型,它不會讓瀏覽器載入新文檔,但只會使它滾動到文檔的某個位置。#top標識符是一個特殊例子:如果文檔沒有元素額ID是"top",它會讓瀏覽器跳轉到文檔開始處。
location = "#top";Location對象的URL分解屬性是可寫的,對它們重新賦值會改變URL的位置,并且導致瀏覽器載入一個新的文檔(如果改變的是hash屬性,則在當前文檔中進行跳轉):
location.search = "?page=" + (pagename+1);//載入新的頁面3.瀏覽歷史
window對象的history屬性引用的是該窗口的History對象。History對象是用來把窗口的瀏覽歷史用文檔和文檔狀態列表的形式表示。History對象的length屬性表示瀏覽歷史列表中的元素數量,處于安全考慮,腳本不能訪問已經保存的URL(如果允許那任意腳本都可以窺探瀏覽歷史)。
history對象的back()和forward()方法與瀏覽器的“后退”和“前進”按鈕一樣。第三個方法go()接受一個參數,可以在歷史列表向前(正參數)向后(幅參數)跳過任意個頁面。
history.go(-2); //向后兩個歷史記錄,相當于后退按鈕兩次如果窗口包含多個子窗口(比如iframe見14.8.2節),子窗口的瀏覽歷史會按時間順序穿插在主窗口的歷史中。這意味著在主窗口調用history.back()可能會導致其中一個子窗口往回跳到前一個顯示文檔,但主窗口保留當前狀態不變。
現代的web應用可以不通過載入新的文檔而動態的改變自身內容(15、18章)。這么做可能希望用戶能用“后退”和“前進”按鈕在這些動態創建應用狀態之間跳轉。html5將這些技術標準化(22章2節)。
HTML5之前的歷史管理是個更復雜的難題。應用程序必須要在窗口瀏覽歷史中創建一個新的條目來管理自身的歷史記錄。。。。。。
在實際的工作中,那些需要以前的HTML5歷史管理的項目中,開發者會使用一些現成 解決方法,很多框架都實現了這些功能。例如jQuery的history插件。也有一些單獨的管理歷史記錄的類庫。RSH(Really Simple History)是其中一個比較流行的示例。(22章2節會有關于html5的歷史管理)
4.瀏覽器和屏幕信息
本節介紹window對象的navigator和screen屬性,它們分別引用的是Navigator和Screen對象,這些對象信息允許腳本根據環境定制的行為。
4.1.Navigator對象
window對象的navigator屬性引用的是包含瀏覽器廠商和版本信息的Navigator對象。
這樣命名是為了紀念Netscape之后Navigator瀏覽器。
過去會用其來確定腳本是在哪種瀏覽器運行,現在瀏覽器種類繁多,也有一種更好的功能測試方法(13.4.3節)。但是Navigation還是有價值的,在這種情況下有用:當需要解決存在于某個特定的瀏覽器的特定版本中的特殊的bug時。
可以使用這些屬性進行瀏覽器嗅探:
- appName:web瀏覽器的全稱,IE中,它顯示“Microsoft Internet Exploer”.在firefox中,該屬性就是“Netscape”,在其它瀏覽器中也是(為了兼容現在的瀏覽器嗅探碼)。
- appVersion:此屬性通常以數字開始,并跟隨瀏覽器開發商和版本信息等詳細字符串。字符串的前邊通常是4.0或者5.0,表示它是第4還是第5代兼容的瀏覽器。appVersion沒有標準格式。所有沒有辦法判斷瀏覽器的類型
- userAgent:瀏覽器在它的User-Agent HTTP頭部發送的字符串。這個屬性通常包含所有appVersion信息,并且常常包含其它細節。和appVersion一樣,它也沒有標準格式。由于這個屬性包含絕大部分信息,因此,瀏覽器嗅探代碼通常使用它。
- platform:在其上運行的瀏覽器的操作系統(可能是硬件的字符串)。
Navigator屬性的復雜性正說明了瀏覽器嗅探對于處理客戶端兼容性問題是沒有太大幫助的。appName(都設為Netscape)和appVersion(有起始數字)沒太大意義,所以使用更復雜的userAgent。
下面的例子展示了使用正則表達式(來自jQuery)從navigator.userAgent抽取瀏覽器的版本和名稱方法代碼。
/* 使用naVigator.userAgent來進行瀏覽器嗅探 *///為客戶端嗅探定義browser.name和browser.version,這里使用了jQuery1.41的代碼//name和number都是字符串,對瀏覽器的輸出結果不一樣,檢測的結果如下//'webkit':safari或chrome,版本號是WebKit的版本號//'opera' Opear 版本號就是軟件的把嫩好//"mozilla" Firefox或者基于gecko內核的瀏覽器,版本號是Gecko的版本//msie IE+版本號 var browser = (function() {var s = navigator.userAgent.toLowerCase();var match = /(webkit)[ \/]([\w.]+)/.exec(s) ||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(s) ||/(msie)([\w.]+)/.exec(s) ||!/compatible/.test(s) && /(mozilla)( ? : .* ? rv : ([\w.] + )) ? /.exec(s)||[];return{name:match[1]||"",version:match[2]||"0"}; }());除了瀏覽器廠商和版本信息的屬性之外,Navigator對象還包含一些雜項屬性和方法。以下是一些標準化的屬性以及廣泛應用但未標準的屬性:
- OnLine:navigator.onLine是表示瀏覽器是否連接到網絡。應用:判斷離線的話就保存狀態到本地(20章)
- geolocation:navigator.geolocation對象擁有確定用戶地址位置信息的接口,參加22.1章節細節
- javaEnabled():navigator.javaEnabled是一個非標準的方法,當瀏覽器能運行java小程序時返回true
- cookieEnabled():navigator.cookieEnabled也是一個非標準方法,如果瀏覽器可以永久保存cookie時,返回true,而cookie配置“視具體情況而定”時,可能會返回不正確的值。
4.2.Screen對象。
window對象的screen屬性引用的是Screen對象。它提供有關窗口的大小和可用的顏色數量的信息。屬性width和heigth指定的是以像素為單位的窗口大小,屬性availWidth和availHeiht指是實際可用的顯示大小,它們排除了像桌面任務欄這樣的特性所占用的空間。屬性colorDepth指定的是顯示的BPP(bits-per-pixel)值,典型的值有16,24,32
window.screen屬性和它引用的screen對象都是非標準但廣泛實現的。可以用Screen對象來確定web應用是否運行在一個小的屏幕設備上,如果屏幕有限,可能要選用更小的字體和圖片等。
5.對話框
window對象提供了3個方法向用戶顯示簡單的對話框,alert()向用戶顯示一條信息并等待用戶關閉對話框,confirm()要求用戶單擊確定或取消,返回一個布爾值,prompt()同樣也顯示一條消息,等待用戶輸入字符串,并返回那個字符串。下面的代碼全用了這三種方法:
do {var name = prompt("你的名字");var correct = confirm("你輸入了" + name + "\n" + "oK確認,chancel取消"); } while (!correct)alert("hello " + name);盡管alert(),confirm()和prompt()都容易使用,但是良好的設計還是需要有節制的使用它們。如今,唯一常見的就是使用它們調試,查看變量輸出的結果是什么。
注意,這些對話框中顯示的文本是純文本,而不是HTML格式的文本,只能使用空格,換行符和各種標點符號來格式化這些對話框。
confirm()和prompt()都會產生阻塞,也就是說,在用戶關掉它們所顯示的對話框之前,它們不返回,代碼會停止運行或載入,直到用戶響應為止。在大多數瀏覽器里,alert()也會產生阻塞,并等待用戶關閉對話框,但不總是這樣,完整的的細節請參考第四部分的Window.alert()/Window.confirm()、和window.prompt()方法。
除了window的alert()、confirm()和prompt()方法,還有更復雜的方法showModalDialog(),顯示一個包含HTML格式的模態對話框(顯示出來就不可以點選位于其下面的對話框),可以給它傳入參數,以及從對話框里返回值。第一個參數用以指定提供對話框HTML內容的URL,第二個參數是一個任意值(數組和對象均可),這個值在對話框里的腳本中可以通過window.dailogArguments屬性的值訪問。第三個參數是一個非標準的列表,包含以分號隔開的name=value對,如果提供了這個參數,可以配置對話框的尺寸和其他屬性,用dialogwidth和dialogheight來設置對話框窗口的大小。用resizable=yes來允許用戶改變窗口大小。
這個方法直到窗口關閉之前不會反悔。當窗口關閉后,window.returnValue屬性的值就是此方法的返回值。對話框的HTML內容往往必須包含用來設置returnValue的“確認”按鈕,如果需要則調用window.close(14.8.1節)。
下面的例子是一個適用于showModalDialog()的html文件,代碼頂部注釋包含調用showModalDialog()的樣例。對話框里顯示的大量文本都來自showModalDialog()第二個參數,而不是寫死在html中。
。。。。。。
6.錯誤處理
window對象的onerror屬性是一個事件處理程序,當未捕獲的異常傳播到調用棧上時就會調用它,并把錯誤消息輸出到瀏覽器的javascript控制臺上。如果給這個屬性賦值一個函數,那么只要這個窗口中發生了javascript錯誤,就會調用該函數,即它成為了窗口的錯誤處理程序。
由于歷史原因,window對象的onerror事件處理函數的調用通過三個字符串參數,而不是通過傳遞一個事件對象。(其它客戶端對象的onerror處理程序所需要的錯誤條件是不一樣的,但是它們都是正常的事件處理程序,向這個函數只需傳入一個事件對象。)window.onerror的第一個參數是描述錯誤的一條消息。第二個參數是一個字符串,它存放引發錯誤的javascript代碼所在文檔的 url.第三個參數是引發錯誤的行數。
除了這三個參數外,onerror處理程序的返回值也很重要。如果onerror處理程序返回false,它通知瀏覽器事件處理程序已經處理了錯誤,不需要其他操作。換句話說,瀏覽器不應該顯示它自己的錯誤消息。遺憾的是,由于歷史原因,Firefox里的錯誤程序必須返回true表示它已經處理了錯誤
onerror處理程序是很早期的javascript產物,那時候語言核心不包含try/catch異常處理語句。現在的代碼已經很少使用它。但是在開發階段,你可能需要定義一個錯誤處理程序,當錯誤發生時,來顯式的通知你。
//在一個對話框中彈出錯誤消息,但不超過3次 window.onerror = function(msg, url, line) {if(onerror.num++ < onerror.max){alert("出錯了:\n" + msg + "\n 地址:" + url + "\n行號:" + line);return true; //屏蔽系統事件 } } onerror.max = 3; onerror.num = 0;示例:
<html> <head> <script type="text/javascript"> onerror=handleErr var txt=""function handleErr(msg,url,l) { txt="本頁中存在錯誤。\n\n" txt+="錯誤:" + msg + "\n" txt+="URL: " + url + "\n" txt+="行:" + l + "\n\n" txt+="點擊“確定”繼續。\n\n" alert(txt) return true }function message() { ablert("Welcome guest!") } </script> </head><body> <input type="button" value="查看消息" οnclick="message()" /> </body></html>7.作為window對象屬性的文檔元素
如果在HTML文檔中使用id屬性來為元素命名,并且如果window對象沒有此名字的屬性,window對象會賦予一個屬性,它的名字是id屬性的值,而他們的值指向表示文檔元素的HTMLElement對象。
//文檔中存在id="doc"的HTML元素 window.doc在客戶端javascript中,window對象是以全局對象的形式存在于作用域鏈的最上層,這就意味著在html文檔中使用的id屬性會成為被腳本訪問的全局變量。如果一個文檔包含<button id="okay"></button>元素,可以通過全局變量okay引用此元素。
但是:有一個很重要的警告!如果window對象已經具有此名字的屬性,這就不會發生。比如id是history,location或navigator的元素,就不會以全局變量的形式出現,因為這些id已經被占用了。同樣,如果html文檔包含一個id為“x”的元素,并且還在代碼中聲明并賦值給全局變量x,那么顯式聲明的變量會隱藏隱式的元素變量。如果腳本中的變量聲明出現在命名元素之前,那這個變量的存在就會阻止元素獲取它的window屬性。而如果腳本中的變量聲明出現在命名元素之后,那么變量的顯式賦值就會覆蓋該屬性的隱式值。
15章2節中,你會學到通過document,getElementById()方法,用HTML的id屬性來查找文檔元素。見下面的例子:
var ui = ["input", "prompt", "heading"]; //數組中存放要查找的元素id ui.forEach(function(id) { //用每個id查找對于的元素ui[id] = document.getElementById(id); //將其存放在一個屬性中 });運行完這段代碼之后,ui.input,ui.prompt和ui.heading會引用文檔元素。腳本可以用全局變量input和heading來代替ui.input和ui.heading
但記得14.5節里window對象有個方法的名字是prompt(),所用腳本中不能用全局變量prompt代替ui.prompt。
元素的id作為全局變量的隱式應用是web瀏覽器演化過程中遺留的怪癖。它主要是出于與已有web頁面向后兼容性的考慮。但這里并不推薦這種做法---瀏覽器廠商可以在任何時候為window對象定義新屬性,而這些新屬性都會破壞使用了此屬性名的隱式定義的代碼。反之,用document.getElementById()來顯式查找元素,如果給他一個更簡單的名字,這種用法會更加簡單:
var $ = function(id) {return document.getElementById(id); }; ui.prompt = $("prompt")假設ID并沒有被window對象使用的話,那么任何有id屬性的html元素都會變成全局變量的值。以下HTML元素如果有name屬性的話,也會這樣表現:
<a> <applet> <area> <embed> <form> <frame> <frameset> <img> <object>id元素在文檔中必須是唯一的,兩個元素不能有相同的id。但是這對name屬性無效。如果上面的元素有多于一個相同的name屬性(或者一個元素有name屬性,而另外一個元素有相同值的id屬性),具有該名稱的隱式全局變量會引用一個類數組對象,這個類數組對象的元素是所有命名的元素。
有name或id屬性的<iframe>元素是個特殊的例子。為它們隱式創建的變量不會引用表示元素自身的Element對象,而是引用表示<iframe>元素創建的嵌套的window對象。本文14.8.2節會討論到它。
8.多窗口和窗體
一個web頁面窗口可能在桌面上包含多個標簽頁。每一個標簽 頁都是獨立的“瀏覽上下文”(browsing context),每一個上下文都有獨立的window對象,而且相互之間互不干擾。
但是窗口不總是和其它窗口完全沒有關系。一個窗口或標簽頁中的腳本可以打開新的窗口或標簽頁,當一個腳本這樣做時,這樣多個窗口或窗口與另一個窗口文檔之間就可以互操作。(13.6.2節講解的同源策略約束)。本節1小節會介紹窗口的打開和關閉的更多內容。?
html文檔經常使用<iframe>來嵌套多個文檔。由它所創建的嵌套瀏覽上下文是用它自己的window對象所表示的。廢棄的<frameset>和<frame>元素同樣創建了一個嵌套的瀏覽上下文。每一個<frame>都由一個獨立的window對象表示。對于客戶端javascript來說,窗口、標簽頁、iframe和框架都是獨立的瀏覽上下文。對于javascript來說,它們都是window對象。和相互獨立的標簽頁不同,嵌套的瀏覽上下文之間并不是相互獨立的。在一個窗體中運行javascript程序總是能看見它的祖先和子孫窗體,盡管腳本查看這些窗體中的文檔受到同源策略限制。14.8.2節。
因為window是客戶端javascript的全局對象,每個窗口或窗體都包含獨立的javascript執行上下文。不過在一個窗口中的javascript代碼,如有同源策略的限制,則可以使用另外一個窗口中定義的對象、屬性和方法。與此相關的細節會在14.8.3節詳細討論。由于同源策略的限制導致窗口之間無法直接交互時,html5提供了一個基于事件的消息傳輸API,可以用于間接通信。22章3節會討論。
8.1.打開和關閉窗口
使用window對象的open()方法可以打開一個新的瀏覽器窗口(或標簽頁,這通常和瀏覽器的配置項有關)。window.open()載入指定的url到新的或已存在的窗口中,并返回代表那個窗口的window對象。它有四個可選的參數。
open()第一個參數是要在新窗口中顯示的文檔的url。如果省略(也可以是空字符串),那么會使用頁面的URLabout:blank。
opne()第二個參數是新打開的窗口的名字。如果指定的是一個以及存在的窗口的名字(并且腳本允許跳轉到那個窗口),會直接使用已經存在的窗口。否則,會打開新的窗口,并將這個指定的名字賦值給它。如果省略此參數,會使用指定的名字“_blank”打開新的、未命名的窗口。
需要注意的是,腳本是無法通過簡單的猜測窗口的名字來控制操縱這個窗口中的web應用的,只有設置了“允許導航”(allowed to navigte)(html5規范術語)的頁面才可以這樣。寬泛的講,當且僅當窗口包含的文檔來自相同的源或者是這個腳本打開了那個窗口(或者是遞歸地打開了窗口中打開的窗口),腳本才可以通過名字來指定存在的窗口。還有,如果其中一個窗口是內嵌在另一個窗口的里的窗體,那么它們的腳本直接就可以相互導航。在這種情況下,可以使用保留的名字“_top”(頂級祖先窗口)和“_parent”(直接父級窗口)來獲取彼此瀏覽上下文。
open()的第三個可選參數是一個以逗號分隔的列表,包含大小和各種屬性,用以表明新窗口是如何打開的。如果省略它,新窗口會用一個默認的大小,而且帶有一整組標準的UI組件,即菜單欄/狀態欄、工具欄等。在標簽式瀏覽器中,會創建一個新的標簽。
另外一方面,如果指定這個參數,就可以指定窗口的尺寸,以及它包含的一組屬性。(顯式指定窗口支持更像是創建新窗口,而不是新標簽)例如,允許打開改變大小的瀏覽器窗口,并且包含狀態欄、工具欄,地址欄可以這樣寫:
var w =window.open("smaillwin.html","smallwin","width=400,heigth=500,status=yes,resizeable=yes");第三個參數是非標準的,html5規范也主張瀏覽器應該忽略它。參見第四部分中的window.open()查看在此參數中可以指定什么內容。注意,當指定第三個參數時,所有沒有顯式指定的功能都會忽略。出于各種安全原因,瀏覽器包含對可能指定的功能的限制。例如:通常不允許指定一個太小或者位于屏幕之外才窗口,并且瀏覽器不允許創建一個沒有狀態欄的窗口。
open()的第四個參數只在第二個參數命名的是一個存在的窗口時才有用。它是一個布爾值,聲明了由第一個參數是url是應用替換掉窗口瀏覽歷史的當前條目(true),還是應該在窗口瀏覽歷史中創建一個新的條目false,后者為默認設置。
open()的返回值是代表命名或新創建的窗口的window對象。可以在自己的javascript代碼中使用這個window對象來引用新創建的窗口,就像使用隱式的window對象window來引用運行代碼的窗口一樣。
var w = window.open(); w.alert("to example.com"); w.location = "http://www.example.com"在由window.open()方法創建的窗口中,opener屬性引用的是打開它的腳本的window對象。在其它窗口中,opener為null:
w.opner !== true; //true, 對于任何由w創建的任意窗口 w.open().opener === w; //true,對于任意窗口wwindow.open()是廣告商用來在你瀏覽網頁時采用的“頁面之前彈出”或“頁面之后彈出”窗口的一種方法。由于這種方法的濫用,大部分瀏覽器增加了彈出窗口過濾系統,通常,open()方法只有當用戶單擊按鈕或者鏈接的時候才會調用,javascript代碼嘗試在瀏覽器載入或關閉時開啟彈出一個窗口時,通常會失敗。將上面的代碼粘貼到瀏覽器javascript控制臺進行測試 ,可能會因為同樣的原因而失敗。
關閉窗口
就像方法open()打開一個新窗口一樣,方法close()將關閉一個窗口。如果已經創建了window對象w,可以使用如下的代碼將它關閉。
w.close()運行在那個窗口中的javascript代碼則可以使用下面的代碼關閉。如下
window.close();注意,要顯式地使用標識符window。這樣可以避免混淆window對象的close()方法和Document對象的close()方法,如果正在從事件處理程序調用close()。這很重要
大多瀏覽器只允許自動關閉由自己的javascript代碼創建的窗口。如果要關閉其他窗口,可以用一個對話框提示用戶,要求他對關閉窗口的請求進行確認或取消。在表示窗體而不是頂級窗口或標簽頁上的window對象執行close()方法不會有任何效果,它不能關閉一個窗體(反之可以從它包含的文檔中刪除iframe)。
即使一個窗口關閉了,代表它的window對象仍然存在。已關閉的窗口會有個值為為true的closed屬性。它的Document會是null。它的方法通常再也不會工作。
8.2.窗體之間的關系
我們已經知道,window對象的方法open()返回代表新創建的窗口的window對象,而且這個新窗口具有opener屬性,該屬性可以打開它的原始窗口。這樣,兩個窗口就可以相互引用,彼此都可以讀取對方的屬性或是調用對方的方法。窗體也是這樣的,窗口或窗體中運行的代碼都可以通過下面介紹的屬性引用到自己的窗口或窗體,以及嵌套的子窗體。
任何窗口或窗體中的javascript代碼都可以將自己的窗口和窗體引用為window或self.窗體可以用parent屬性引用包含它的窗口或窗體的window對象。
parent.history.back();如果一個窗口是頂層窗口或標簽,而不是窗體,那么其parent屬性引用的就是這個窗口本身。
parent == self; //只有頂級窗口才會返回true如果一個窗體包含在另一個窗體中,而后者又包含在頂級窗口中,那么該窗體就可以使用parent.parent來引用頂級窗口。top屬性是一個通用的快捷方式,無論一個窗體被嵌套了幾層,它的top屬性引用的都是指向包含它的頂級窗口。如果一個window對象代表的是一個頂級窗口,那么它的top屬性引用的就是窗口本身。對于那些頂級窗口的直接子窗口,top屬性就等價于parent屬性。
parent和top屬性允許腳本引用它的窗體的祖先。有不止一種方法可以引用窗口或窗體的子孫窗體。窗體是通過iframe元素創建的。可以用 獲取其他元素的一個方法獲取一個表示iframe元素的對象。假定文檔里有<iframe id="f1">,那么表示該iframe元素的對象就是:
var iframeElement = document.getElementById("f1");<iframe>元素有contentWindow屬性,引用該窗體的window對象,所以此窗體的window對象就是:
var childFrame = document.getElementById("f1").contentWindow;可以進行反向操作——從表示窗體的window對象來獲取該窗體的<iframe>元素,用window對象的frameElement屬性。表示頂級窗口的window對象的frameElement屬性為null。窗體中的window對象的frameElement屬性不是null:
var elt = document.getElementById("f1"); var win = elt.contentWindow; win.frameElement === elt; //對于幀來說,永遠是true window.frameElement === null; //對于頂級窗口來說,永遠是true。。。。。。
8.3.交互窗口中的javascript
每個窗口和窗體都是它自身的javascript執行上下文,以window作為全局對象。但是如果一個窗口或窗體中的代碼可以應用到其他窗口或窗體(并且同源策略沒有阻止它),那么一個窗口或窗體中的腳本就可以和其它窗口或窗體的腳本進行交互。
設想一個web頁面中有兩個<iframe>元素 ,分別叫A和B,并且這些窗體所包含的文檔來自同一服務器,并且包含交互腳本,窗體A里的腳本定義了一個變量i :
var i = 3;這個變量只是全局對象的一個屬性,也是window對象的一個屬性。窗體A中的代碼可以用標識符i來引用變量,或者用window對象顯式的引用這個變量:
window.i由于窗體B中的腳本可以引用窗體A的window對象,因此它可以引用那個window對象的屬性:
parent.A.i=4;//改變窗體A中的變量i的值。。。。。。
?
轉載于:https://www.cnblogs.com/Chen-XiaoJun/p/6657955.html
總結
以上是生活随笔為你收集整理的JavaScript权威指南--window对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu安装vsftpd
- 下一篇: 安装spring-tool-suite插