JavaScript window 對象詳解

1. 概述

window對象 指當前的瀏覽器窗口,它也是當前頁面的頂層對象,即最高一層的對象,全部其餘對象都是它的下屬。
一個變量若是未聲明,那麼默認就是頂層對象的屬性。javascript

// a是一個沒有聲明就直接賦值的變量,它自動成爲頂層對象的屬性。
a = 1;
console.log(window.a) // 1

window 有本身的實體含義,其實不適合看成最高一層的頂層對象,這是一個語言的設計失誤。
最先,設計這門語言的時候,原始設想是語言內置的對象越少越好,這樣能夠提升瀏覽器的性能。所以,語言設計者 Brendan Eich 就把 window 對象看成頂層對象,全部未聲明就賦值的變量都自動變成 window 對象的屬性。這種設計使得編譯階段沒法檢測出未聲明變量,但到了今天已經沒有辦法糾正了。html

2. window 對象的屬性

2.1 window.name
window.name屬性是一個字符串,表示當前瀏覽器窗口的名字。
窗口不必定須要名字,這個屬性主要配合超連接和表單的target屬性使用。java

window.name = 'Hello World!';
console.log(window.name) // "Hello World!"

該屬性只能保存字符串,若是寫入的值不是字符串,會自動轉成字符串。
只要瀏覽器窗口不關閉,這個屬性是不會消失的。
舉例來講,訪問a.com時,該頁面的腳本設置了window.name,接下來在同一個窗口裏面載入了b.com,新頁面的腳本能夠讀到上一個網頁設置的 window.name。頁面刷新也是這種狀況。一旦瀏覽器窗口關閉後,該屬性保存的值就會消失,由於這時窗口已經不存在了。數組

2.2 window.closed,window.opener瀏覽器

2.2.1 window.closed 屬性返回一個布爾值,表示窗口是否關閉;安全

window.closed // false

上面代碼檢查當前窗口是否關閉。這種檢查意義不大,由於只要能運行代碼,當前窗口確定沒有關閉。
這個屬性通常用來檢查,使用腳本打開的新窗口是否關閉。服務器

var popup = window.open();
if ((popup !== null) && !popup.closed) {
	// 窗口仍然打開着
}

2.2.2 window.opener 屬性表示打開當前窗口的父窗口;
若是當前窗口沒有父窗口(即直接在地址欄輸入打開),則返回null。cookie

// 表達式會打開一個新窗口,而後返回 true
window.open().opener === window // true

若是兩個窗口之間不須要通訊,建議將子窗口的 opener 屬性顯式設爲 null,這樣能夠減小一些安全隱患。session

// 子窗口的 opener 屬性設爲 null,兩個窗口之間就沒辦法再聯繫了
var newWin = window.open('example.html', 'newWindow', 'height=400,width=400');
newWin.opener = null;

經過 opener 屬性,能夠得到父窗口的全局屬性和方法,但只限於兩個窗口同源的狀況,且其中一個窗口由另外一個打開。
< a > 元素添加 rel=「noopener」 屬性,能夠防止新打開的窗口獲取父窗口,減輕被惡意網站修改父窗口 URL 的風險。框架

<a href="https://an.evil.site" target="_blank" rel="noopener"> 惡意網站 </a>

2.3 window.self,window.window
window.self和window.window屬性都指向窗口自己,這兩個屬性只讀

console.log(window.self === window) // true
console.log(window.window === window) // true

2.4 window.frames,window.length
window.frames 屬性返回一個相似數組的對象,成員爲頁面內全部框架窗口,包括 frame 元素和 iframe 元素。
window.frames[0]表示頁面中第一個框架窗口。

若是 iframe 元素設置了 id 或 name 屬性,那麼就能夠用屬性值,引用這個 iframe 窗口。
< iframe name=「myIFrame」> 能夠用 frames[‘myIFrame’] 或者 frames.myIFrame 來引用。

frames屬性其實是window對象的別名。

frames === window // true

所以,frames[0] 也能夠用 window[0] 表示。
從語義上看 frames 更清晰,並且考慮到 window 仍是全局對象,所以推薦表示多窗口時,老是使用 frames[0] 的寫法。
window.length屬性返回當前網頁包含的框架總數。若是當前網頁不包含 frame 和 iframe 元素,那麼 window.length 就返回 0。

// window.frames.length 與 window.length 應該是相等的
window.frames.length === window.length // true

2.5 window.frameElement
window.frameElement 屬性主要用於當前窗口嵌在另外一個網頁的狀況(嵌入< object >、< iframe >或< embed >元素),返回當前窗口所在的那個元素節點。若是當前窗口是頂層窗口,或者所嵌入的那個網頁不是同源的,該屬性返回null。

// HTML 代碼以下
// <iframe src="about.html"></iframe>

// 下面的腳本在 about.html 裏面
var frameEl = window.frameElement;
if (frameEl) {
  frameEl.src = 'other.html';
}

上面代碼中,frameEl變量就是 < iframe > 元素。

2.6 window.top,window.parent
window.top 屬性指向最頂層窗口,主要用於在框架窗口(frame)裏面獲取頂層窗口;
window.parent 屬性指向父窗口。若是當前窗口沒有父窗口,window.parent指向自身;
對於不包含框架的網頁,這兩個屬性等同於window對象

if (window.parent !== window.top) {
  // 代表當前窗口嵌入不止一層
}

2.7 window.status
window.status屬性用於讀寫瀏覽器狀態欄的文本。
注意: 如今不少瀏覽器都不容許改寫狀態欄文本,因此使用這個方法不必定有效。

2.8 window.devicePixelRatio
window.devicePixelRatio屬性返回一個數值,表示一個 CSS 像素的大小與一個物理像素的大小之間的比率。
它表示一個 CSS 像素由多少個物理像素組成。它能夠用於判斷用戶的顯示環境,若是這個比率較大,就表示用戶正在使用高清屏幕,所以能夠顯示較大像素的圖片。

3. 位置大小屬性

3.1 window.screenX,window.screenY(只讀)
window.screenX和window.screenY屬性,返回瀏覽器窗口左上角相對於當前屏幕左上角的水平距離和垂直距離(單位像素)。

3.2 window.innerHeight,window.innerWidth(只讀)
window.innerHeight和window.innerWidth屬性,返回網頁在當前窗口中可見部分的高度和寬度,即「視口」(viewport)的大小(單位像素)。

用戶放大網頁的時候(好比將網頁從100%的大小放大爲200%),這兩個屬性會變小。由於這時網頁的像素大小不變(好比寬度仍是960像素),只是每一個像素佔據的屏幕空間變大了,由於可見部分(視口)就變小了。

注意,這兩個屬性值包括滾動條的高度和寬度。

3.3 window.outerHeight,window.outerWidth(只讀)
window.outerHeight 和 window.outerWidth 屬性返回瀏覽器窗口的高度和寬度,包括瀏覽器菜單和邊框(單位像素)。

3.4 window.scrollX,window.scrollY(只讀)
window.scrollX屬性返回頁面的水平滾動距離,window.scrollY屬性返回頁面的垂直滾動距離,單位都爲像素。

注意: 這兩個屬性的返回值不是整數,而是雙精度浮點數。若是頁面沒有滾動,它們的值就是0。
舉例來講,若是用戶向下拉動了垂直滾動條75像素,那麼window.scrollY就是75左右。用戶水平向右拉動水平滾動條200像素,window.scrollX就是200左右。

// 若是頁面向下滾動的距離小於75像素,那麼頁面向下滾動75像素
if (window.scrollY < 75) {
  window.scroll(0, 75);
}

3.5 window.pageXOffset,window.pageYOffset
window.pageXOffset屬性和window.pageYOffset屬性,是window.scrollX和window.scrollY別名。

4. 組件屬性

組件屬性返回瀏覽器的組件對象。

window.locationbar // 地址欄對象
window.menubar  // 菜單欄對象
window.scrollbars // 窗口的滾動條對象
window.toolbar // 工具欄對象
window.statusbar // 狀態欄對象
window.personalbar // 用戶安裝的我的工具欄對象

這些對象的 visible 屬性是一個布爾值,表示這些組件是否可見。這些屬性只讀。

window.locationbar.visible
window.menubar.visible
window.scrollbars.visible
window.toolbar.visible
window.statusbar.visible
window.personalbar.visible

5. 全局對象屬性

全局對象屬性指向一些瀏覽器原生的全局對象。

window.document  // 指向document對象。注意,這個屬性有同源限制。只有來自同源的腳本才能讀取這個屬性。
window.location  // 指向Location對象,用於獲取當前窗口的 URL 信息。它等同於document.location屬性。
window.navigator  // 指向Navigator對象,用於獲取環境信息。
window.history  // 指向History對象,表示瀏覽器的瀏覽歷史。
window.localStorage  // 指向本地儲存的localStorage數據。
window.sessionStorage  // 指向本地儲存的sessionStorage數據。
window.console  // 指向console對象,用於操做控制檯。
window.screen  // 指向Screen對象,表示屏幕信息。
window.isSecureContext  // 屬性返回一個布爾值,表示當前窗口是否處在加密環境。若是是 HTTPS 協議,就是true,不然就是false。

6. window 對象的方法

6.1 window.alert() , window.prompt() , window.confirm()
這三個方法都具備堵塞效應,一旦彈出對話框,整個頁面就是暫停執行,等待用戶作出反應。

window.alert() 方法彈出的對話框,只有一個「肯定」按鈕,每每用來通知用戶某些信息。
用戶只有點擊「肯定」按鈕,對話框纔會消失。對話框彈出期間,瀏覽器窗口處於凍結狀態,若是不點「肯定」按鈕,用戶什麼也幹不了。
window.alert()方法的參數只能是字符串,無法使用 CSS 樣式,可是能夠用\n指定換行。

window.alert('Hello World');
alert('本條提示\n分紅兩行');

window.prompt() 方法彈出的對話框,提示文字的下方,還有一個輸入框,要求用戶輸入信息,並有「肯定」和「取消」兩個按鈕。
window.prompt()方法的第二個參數是可選的,可是最好老是提供第二個參數,做爲輸入框的默認值。
它每每用來獲取用戶輸入的數據。

// 代碼會跳出一個對話框,文字提示爲「您的年齡?」,要求用戶在對話框中輸入本身的年齡(默認顯示25)。用戶填入的值,會做爲返回值存入變量result。
var result = prompt('您的年齡?', 25)
console.log(result)

window.prompt()的返回值有兩種狀況,多是字符串(有多是空字符串),也有多是null。
具體分紅三種狀況:

  1. 用戶輸入信息,並點擊「肯定」,則用戶輸入的信息就是返回值。
  2. 用戶沒有輸入信息,直接點擊「肯定」,則輸入框的默認值就是返回值。
  3. 用戶點擊了「取消」(或者按了 ESC 按鈕),則返回值是null。

window.confirm() 方法彈出的對話框,除了提示信息以外,只有「肯定」和「取消」兩個按鈕,每每用來徵詢用戶是否贊成。
confirm方法返回一個布爾值,若是用戶點擊「肯定」,返回true;若是用戶點擊「取消」,則返回false。

var okay = confirm('Please confirm this message.');
if (okay) {
  // 用戶按下「肯定」
} else {
  // 用戶按下「取消」
}

confirm的一個用途是,用戶離開當前頁面時,彈出一個對話框,問用戶是否真的要離開。

window.onunload = function () {
  return window.confirm('你肯定要離開當面頁面嗎?');
}

6.2 window.open(), window.close(), window.stop()

window.open() 方法用於新建另外一個瀏覽器窗口,相似於瀏覽器菜單的新建窗口選項。它會返回新窗口的引用,若是沒法新建窗口,則返回null。

// 瀏覽器彈出一個新建窗口,網址是當前域名下的somefile.html
var popup = window.open('somefile.html');

open方法一共能夠接受三個參數:

window.open(url, windowName, [windowFeatures])

url:字符串,表示新窗口的網址。若是省略,默認網址就是about:blank。
windowName:字符串,表示新窗口的名字。
			若是該名字的窗口已經存在,則佔用該窗口,再也不新建窗口。
			若是省略,就默認使用_blank,表示新建一個沒有名字的窗口。
			另外還有幾個預設值,_self表示當前窗口,_top表示頂層窗口,_parent表示上一層窗口。
windowFeatures:字符串,內容爲逗號分隔的鍵值對(以下所列),表示新窗口的參數,好比有沒有提示欄、工具條等等。
				若是省略,則默認打開一個完整的新窗口。
				若是新建的是一個已經存在的窗口,則該參數不起做用,瀏覽器沿用之前窗口的參數。
				
				第三個參數能夠設定以下屬性:
					left:新窗口距離屏幕最左邊的距離(單位像素)。注意,新窗口必須是可見的,不能設置在屏幕之外的位置。
					top:新窗口距離屏幕最頂部的距離(單位像素)。
					height:新窗口內容區域的高度(單位像素),不得小於100。
					width:新窗口內容區域的寬度(單位像素),不得小於100。
					outerHeight:整個瀏覽器窗口的高度(單位像素),不得小於100。
					outerWidth:整個瀏覽器窗口的寬度(單位像素),不得小於100。
					menubar:是否顯示菜單欄。
					toolbar:是否顯示工具欄。
					location:是否顯示地址欄。
					personalbar:是否顯示用戶本身安裝的工具欄。
					status:是否顯示狀態欄。
					dependent:是否依賴父窗口。若是依賴,那麼父窗口最小化,該窗口也最小化;父窗口關閉,該窗口也關閉。
					minimizable:是否有最小化按鈕,前提是dialog=yes。
					noopener:新窗口將與父窗口切斷聯繫,即新窗口的window.opener屬性返回null,
							  父窗口的window.open()方法也返回null。
					resizable:新窗口是否能夠調節大小。
					scrollbars:是否容許新窗口出現滾動條。
					dialog:新窗口標題欄是否出現最大化、最小化、恢復原始大小的控件。
					titlebar:新窗口是否顯示標題欄。
					alwaysRaised:是否顯示在全部窗口的頂部。
					alwaysLowered:是否顯示在父窗口的底下。
					close:新窗口是否顯示關閉按鈕。

					對於那些能夠打開和關閉的屬性,設爲yes或1或不設任何值就表示打開;
					好比status=yes、status=一、status都會獲得一樣的結果。
					若是想設爲關閉,不用寫no,而是直接省略這個屬性便可。
					若是在第三個參數中設置了一部分屬性,其餘沒有被設置的yes/no屬性都會被設成no;
					只有titlebar和關閉按鈕除外(它們的值默認爲yes)。
// 打開的新窗口高度和寬度都爲200像素,沒有地址欄,但有狀態欄和滾動條,容許用戶調整大小。
var popup = window.open(
  'somepage.html',
  'DefinitionsWindows',
  'height=200,width=200,location=no,status=yes,resizable=yes,scrollbars=yes'
);

open() 方法的第二個參數雖然能夠指定已經存在的窗口,可是不等於能夠任意控制其餘窗口。爲了防止被不相干的窗口控制,瀏覽器只有在兩個窗口同源,或者目標窗口被當前網頁打開的狀況下,才容許open方法指向該窗口。

window.open方法返回新窗口的引用。

var windowB = window.open('windowB.html', 'WindowB');
windowB.window.name // "WindowB"

注意: 若是新窗口和父窗口不是同源的(即不在同一個域),它們彼此不能獲取對方窗口對象的內部屬性。

// 打開一個新窗口,而後在該窗口彈出一個對話框,再將網址導向example.com
var w = window.open();
console.log('已經打開新窗口');
w.location = 'http://example.com';

因爲open這個方法很容易被濫用,許多瀏覽器默認都不容許腳本自動新建窗口。
只容許在用戶點擊連接或按鈕時,腳本作出反應,彈出新窗口。所以,有必要檢查一下打開新窗口是否成功。

var popup = window.open();
if (popup === null) {
  // 新建窗口失敗
}

window.close() 方法用於關閉當前窗口,通常只用來關閉window.open方法新建的窗口。
該方法只對頂層窗口有效,iframe框架之中的窗口使用該方法無效。

window.close()

window.stop() 方法徹底等同於單擊瀏覽器的中止按鈕,會中止加載圖像、視頻等正在或等待加載的對象。

window.stop()

6.3 window.moveTo(), window.resizeBy()
注意: 爲了防止有人濫用這兩個方法,隨意移動用戶的窗口,目前只有一種狀況,瀏覽器容許用腳本移動窗口:該窗口是用window.open方法新建的,而且它所在的 Tab 頁是當前窗口裏面惟一的。除此之外的狀況,使用上面兩個方法都是無效的。

window.moveTo() 方法用於移動瀏覽器窗口到指定位置。
它接受兩個參數,分別是窗口左上角距離屏幕左上角的水平距離和垂直距離,單位爲像素。

// 將窗口移動到屏幕(100, 200)的位置
window.moveTo(100, 200)

window.moveBy() 方法將窗口移動到一個相對位置。
它接受兩個參數,分佈是窗口左上角向右移動的水平距離和向下移動的垂直距離,單位爲像素。

// 將窗口向右移動25像素、向下移動50像素
window.moveBy(25, 50)

6.4 window.scrollTo(),window.scroll(),window.scrollBy()

window.scrollTo() 方法用於將文檔滾動到指定位置。
接受兩個參數,表示滾動後位於窗口左上角的頁面座標。

window.scrollTo(x-coord, y-coord)

也能夠接受一個配置對象做爲參數。

window.scrollTo(options)
配置對象options有三個屬性:
  top:滾動後頁面左上角的垂直座標,即y座標。
  left:滾動後頁面左上角的水平座標,即x座標。
  behavior:字符串,表示滾動的方式,有三個可能值(smooth、instant、auto),默認值爲auto。

window.scrollTo({
  top: 1000,
  behavior: 'smooth'
});

window.scroll() 方法是 window.scrollTo() 方法的別名。

window.scrollBy() 方法用於將網頁滾動指定距離(單位像素)。
它接受兩個參數:水平向右滾動的像素,垂直向下滾動的像素。

// 用於將網頁向下滾動一屏
window.scrollBy(0, window.innerHeight)
若是不是要滾動整個文檔,而是要滾動某個元素,可使用下面三個屬性和方法:
Element.scrollTop
Element.scrollLeft
Element.scrollIntoView()

6.5 window.print()
window.print() 方法會跳出打印對話框,與用戶點擊菜單裏面的「打印」命令效果相同。

// 常見的打印按鈕代碼以下
document.getElementById('printLink').onclick = function () {
  window.print();
}
// 非桌面設備(好比手機)可能沒有打印功能,這時能夠這樣判斷
if (typeof window.print === 'function') {
  // 支持打印功能
}

6.6 window.focus(),window.blur()
window.focus() 方法會激活窗口,使其得到焦點,出如今其餘窗口的前面。

// 先檢查popup窗口是否依然存在,確認後激活該窗口
var popup = window.open('popup.html', 'Popup Window');

if ((popup !== null) && !popup.closed) {
  popup.focus();
}

window.blur() 方法將焦點從窗口移除。

當前窗口得到焦點時,會觸發focus事件;當前窗口失去焦點時,會觸發blur事件。

6.7 window.getSelection()
window.getSelection方法返回一個Selection對象,表示用戶如今選中的文本。

var selObj = window.getSelection();
// 使用Selection對象的toString方法能夠獲得選中的文本
var selectedText = selObj.toString();

6.8 window.getComputedStyle(),window.matchMedia()

window.getComputedStyle() 方法接受一個元素節點做爲參數,返回一個包含該元素的最終樣式信息的對象。
window.matchMedia() 方法用來檢查 CSS 的mediaQuery語句。

6.9 window.requestAnimationFrame()

window.requestAnimationFrame() 方法跟 setTimeout 相似,都是推遲某個函數的執行。
不一樣之處在於: setTimeout 必須指定推遲的時間,window.requestAnimationFrame() 則是推遲到瀏覽器下一次重流時執行,執行完纔會進行下一次重繪。重繪一般是 16ms 執行一次,不過瀏覽器會自動調節這個速率,好比網頁切換到後臺 Tab 頁時,requestAnimationFrame()會暫停執行。

若是某個函數會改變網頁的佈局,通常就放在window.requestAnimationFrame()裏面執行,這樣能夠節省系統資源,使得網頁效果更加平滑。由於慢速設備會用較慢的速率重流和重繪,而速度更快的設備會有更快的速率。

window.requestAnimationFrame(callback)

callback是一個回調函數。
callback執行時,它的參數就是系統傳入的一個高精度時間戳(performance.now()的返回值),單位是毫秒,表示距離網頁加載的時間。

window.requestAnimationFrame()的返回值是一個整數,這個整數能夠傳入window.cancelAnimationFrame(),用來取消回調函數的執行。
// 下面是一個window.requestAnimationFrame()執行網頁動畫的例子,持續時間是2秒,會讓元素向右移動。
var element = document.getElementById('animate');
element.style.position = 'absolute';

var start = null;

function step(timestamp) {
  if (!start) start = timestamp;
  var progress = timestamp - start;
  // 元素不斷向左移,最大不超過200像素
  element.style.left = Math.min(progress / 10, 200) + 'px';
  // 若是距離第一次執行不超過 2000 毫秒,
  // 就繼續執行動畫
  if (progress < 2000) {
    window.requestAnimationFrame(step);
  }
}

window.requestAnimationFrame(step);

6.10 window.requestIdleCallback()
window.requestIdleCallback()跟setTimeout相似,也是將某個函數推遲執行,可是它保證將回調函數推遲到系統資源空閒時執行。也就是說,若是某個任務不是很關鍵,就可使用window.requestIdleCallback()將其推遲執行,以保證網頁性能。

它跟window.requestAnimationFrame() 的區別: 後者指定回調函數在下一次瀏覽器重排時執行,問題在於下一次重排時,系統資源未必空閒,不必定能保證在16毫秒以內完成;window.requestIdleCallback()能夠保證回調函數在系統資源空閒時執行。

window.requestIdleCallback(callback[, options])

callback參數是一個回調函數。
該回調函數執行時,系統會傳入一個IdleDeadline對象做爲參數。
IdleDeadline對象有一個didTimeout屬性(布爾值,表示是否爲超時調用)和一個timeRemaining()方法(返回該空閒時段剩餘的毫秒數)。
options參數是一個配置對象,目前只有timeout一個屬性,用來指定回調函數推遲執行的最大毫秒數,該參數可選。

window.requestIdleCallback()方法返回一個整數,該整數能夠傳入window.cancelIdleCallback()取消回調函數。
// requestIdleCallback()用來執行非關鍵任務myNonEssentialWork。該任務先確認本次空閒時段有剩餘時間,而後才真正開始執行任務
requestIdleCallback(myNonEssentialWork);

function myNonEssentialWork(deadline) {
  while (deadline.timeRemaining() > 0) {
    doWorkIfNeeded();
  }
}
// processPendingAnalyticsEvents必須在將來2秒以內執行
requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 });

若是因爲超時致使回調函數執行,則 deadline.timeRemaining() 返回 0,deadline.didTimeout 返回true。

若是屢次執行 window.requestIdleCallback(),指定多個回調函數,那麼這些回調函數將排成一個隊列,按照先進先出的順序執行。

7. 事件

window對象能夠接收如下事件

7.1 load 事件和 onload 屬性
load事件發生在文檔在瀏覽器窗口加載完畢時,window.onload屬性能夠指定這個事件的回調函數;

// 在網頁加載完畢後,獲取指定元素並進行處理
window.onload = function() {
  var elements = document.getElementsByClassName('example');
  for (var i = 0; i < elements.length; i++) {
    var elt = elements[i];
    // ...
  }
};

7.2 error 事件和 onerror 屬性
瀏覽器腳本發生錯誤時,會觸發 window 對象的 error 事件,能夠經過 window.onerror 屬性對該事件指定回調函數。

window.onerror = function (message, filename, lineno, colno, error) {
  console.log("出錯了!--> %s", error.stack);
};

window的error事件的回調函數不接受錯誤對象做爲參數,而是一共能夠接受五個參數,它們的含義依次以下:
出錯信息, 出錯腳本的網址, 行號, 列號, 錯誤對象

老式瀏覽器只支持前三個參數。

不是全部的錯誤,都會觸發 JavaScript 的error事件(即讓 JavaScript 報錯)。
通常來講,只有 JavaScript 腳本的錯誤,纔會觸發這個事件,而像資源文件不存在之類的錯誤,都不會觸發。
// 若是整個頁面未捕獲錯誤超過3個,就顯示警告
window.onerror = function(msg, url, line) {
  if (onerror.num++ > onerror.max) {
    alert('ERROR: ' + msg + '\n' + url + ':' + line);
    return true;
  }
}
onerror.max = 3;
onerror.num = 0;

注意: 若是腳本網址與網頁網址不在同一個域(好比使用了 CDN),瀏覽器根本不會提供詳細的出錯信息,只會提示出錯,錯誤類型是「Script error.」,行號爲0,其餘信息都沒有。這是瀏覽器防止向外部腳本泄漏信息。
一個解決方法是在腳本所在的服務器,設置Access-Control-Allow-Origin的 HTTP 頭信息:

Access-Control-Allow-Origin: *
// 在網頁的<script>標籤中設置crossorigin屬性
<script crossorigin="anonymous" src="//example.com/file.js"></script>

上面代碼的 crossorigin="anonymous" 表示,讀取文件不須要身份信息,即不須要 cookie 和 HTTP 認證信息。
若是設爲crossorigin="use-credentials",就表示瀏覽器會上傳 cookie 和 HTTP 認證信息,
同時還須要服務器端打開 HTTP 頭信息Access-Control-Allow-Credentials。

7.3 window 對象的事件監聽屬性

window.onafterprint  // afterprint事件的監聽函數。
window.onbeforeprint  // beforeprint事件的監聽函數。
window.onbeforeunload  // beforeunload事件的監聽函數。
window.onhashchange  // hashchange事件的監聽函數。
window.onlanguagechange  // languagechange的監聽函數。
window.onmessage  // message事件的監聽函數。
window.onmessageerror // MessageError事件的監聽函數。
window.onoffline  // offline事件的監聽函數。
window.ononline  // online事件的監聽函數。
window.onpagehide  // pagehide事件的監聽函數。
window.onpageshow  // pageshow事件的監聽函數。
window.onpopstate  // popstate事件的監聽函數。
window.onstorage  // storage事件的監聽函數。
window.onunhandledrejection  // 未處理的Promise對象的reject事件的監聽函數。
window.onunload  // unload事件的監聽函數。

8. 多窗口操做

因爲網頁可使用 iframe 元素,嵌入其餘網頁,所以一個網頁之中會造成多個窗口。若是子窗口之中又嵌入別的網頁,就會造成多級窗口。
8.1 窗口的引用
各個窗口之中的腳本,能夠引用其餘窗口,瀏覽器提供了一些特殊變量,用來返回其餘窗口。

  1. top:頂層窗口,即最上層的那個窗口;
  2. parent:父窗口;
  3. self:當前窗口,即自身;
// 判斷當前窗口是否爲頂層窗口
if (window.top === window.self) {
  // 當前窗口是頂層窗口
} else {
  // 當前窗口是子窗口
}

// 判斷,當前窗口是否爲頂層窗口
window.parent.history.back();

與這些變量對應,瀏覽器還提供一些特殊的窗口名,供window.open()方法、< a > 標籤、< form > 標籤等引用。

  1. _top:頂層窗口;
  2. _parent:父窗口;
  3. _blank:新窗口;
// 在頂層窗口打開連接
<a href="somepage.html" target="_top">Link</a>

8.2 iframe 元素
對於 iframe 嵌入的窗口,document.getElementById 方法能夠拿到該窗口的 DOM 節點,而後使用 contentWindow 屬性得到iframe 節點包含的 window 對象。

var frame = document.getElementById('theFrame');
var frameWindow = frame.contentWindow;

// 上面代碼中,frame.contentWindow 能夠拿到子窗口的 window 對象。而後,在知足同源限制的狀況下,能夠讀取子窗口內部的屬性。
// 獲取子窗口的標題
frameWindow.title

< iframe > 元素的 contentDocument 屬性,能夠拿到子窗口的 document 對象。

var frame = document.getElementById('theFrame');
var frameDoc = frame.contentDocument;

// 等同於
var frameDoc = frame.contentWindow.document;

< iframe >元素遵照同源政策,只有當父窗口與子窗口在同一個域時,二者之間才能夠用腳本通訊,不然只有使用window.postMessage 方法。

<iframe> 窗口內部,使用 window.parent 引用父窗口。若是當前頁面沒有父窗口,則 window.parent 屬性返回自身。
所以,能夠經過 window.parent 是否等於 window.self,判斷當前窗口是否爲 iframe 窗口。
if (window.parent !== window.self) {
  // 當前窗口是子窗口
}


<iframe>窗口的window對象,有一個frameElement屬性,返回<iframe>在父窗口中的 DOM 節點。對於非嵌入的窗口,該屬性等於null。
var f1Element = document.getElementById('f1');
var f1Window = f1Element.contentWindow;
f1Window.frameElement === f1Element // true
window.frameElement === null // true

8.3 window.frames 屬性
window.frames 屬性返回一個相似數組的對象,成員是全部子窗口的 window 對象。可使用這個屬性,實現窗口之間的互相引用。
如:frames[0]返回第一個子窗口,frames[1].frames[2]返回第二個子窗口內部的第三個子窗口,parent.frames[1]返回父窗口的第二個子窗口。

注意: window.frames 每一個成員的值,是框架內的窗口(即框架的window對象),而不是iframe標籤在父窗口的 DOM 節點。若是要獲取每一個框架內部的 DOM 樹,須要使用 window.frames[0].document 的寫法。

若是 <iframe> 元素設置了name或id屬性,那麼屬性值會自動成爲全局變量,可經過 window.frames 屬性引用,返回子窗口的 window 對象。

// HTML 代碼爲 <iframe id="myFrame">
window.myFrame // [HTMLIFrameElement]
frames.myframe === myFrame // true

name屬性的值會自動成爲子窗口的名稱,能夠用在window.open方法的第二個參數,或者<a>和<frame>標籤的target屬性
相關文章
相關標籤/搜索