概述
瀏覽器里面蛉谜,window對象(注意稚晚,w為小寫)指當(dāng)前的瀏覽器窗口。它也是當(dāng)前頁面的頂層對象悦陋,即最高一層的對象蜈彼,所有其他對象都是它的下屬筑辨。一個變量如果未聲明俺驶,那么默認(rèn)就是頂層對象的屬性。
a = 1;
window.a // 1
上面代碼中棍辕,a是一個沒有聲明就直接賦值的變量暮现,它自動成為頂層對象的屬性。
window有自己的實(shí)體含義楚昭,其實(shí)不適合當(dāng)作最高一層的頂層對象栖袋,這是一個語言的設(shè)計失誤。最早抚太,設(shè)計這門語言的時候塘幅,原始設(shè)想是語言內(nèi)置的對象越少越好,這樣可以提高瀏覽器的性能尿贫。因此电媳,語言設(shè)計者 Brendan Eich 就把window對象當(dāng)作頂層對象,所有未聲明就賦值的變量都自動變成window對象的屬性庆亡。這種設(shè)計使得編譯階段無法檢測出未聲明變量匾乓,但到了今天已經(jīng)沒有辦法糾正了。
window對象屬性
1.window.name
window.name屬性是一個字符串又谋,表示當(dāng)前瀏覽器窗口的名字拼缝。窗口不一定需要名字娱局,這個屬性主要配合超鏈接和表單的target屬性使用。
window.name = 'Hello World!';
console.log(window.name)
// "Hello World!"
該屬性只能保存字符串咧七,如果寫入的值不是字符串衰齐,會自動轉(zhuǎn)成字符串。各個瀏覽器對這個值的儲存容量有所不同继阻,但是一般來說娇斩,可以高達(dá)幾MB。
只要瀏覽器窗口不關(guān)閉穴翩,這個屬性是不會消失的犬第。舉例來說,訪問a.com時芒帕,該頁面的腳本設(shè)置了window.name歉嗓,接下來在同一個窗口里面載入了b.com,新頁面的腳本可以讀到上一個網(wǎng)頁設(shè)置的window.name背蟆。頁面刷新也是這種情況鉴分。一旦瀏覽器窗口關(guān)閉后,該屬性保存的值就會消失带膀,因?yàn)檫@時窗口已經(jīng)不存在了志珍。
2.window.closed,window.opener
window.closed返回一個布爾值垛叨,表示當(dāng)前窗口是否已經(jīng)關(guān)閉伦糯。
上面代碼檢查當(dāng)前窗口是否關(guān)閉。這種檢查意義不大嗽元,因?yàn)橹灰苓\(yùn)行代碼敛纲,當(dāng)前窗口肯定沒有關(guān)閉。這個屬性一般用來檢查剂癌,使用腳本打開的新窗口是否關(guān)閉淤翔。
ar popup = window.open();
if ((popup !== null) && !popup.closed) {
// 窗口仍然打開著
}
window.opener屬性表示打開當(dāng)前窗口的父窗口。如果當(dāng)前窗口沒有父窗口(即直接在地址欄輸入打開)佩谷,則返回null旁壮。
window.open().opener === window // true
上面表達(dá)式會打開一個新窗口,然后返回true谐檀。
如果兩個窗口之間不需要通信抡谐,建議將子窗口的opener屬性顯式設(shè)為null,這樣可以減少一些安全隱患稚补。
var newWin = window.open('example.html', 'newWindow', 'height=400,width=400');
newWin.opener = null;
上面代碼中童叠,子窗口的opener屬性設(shè)為null,兩個窗口之間就沒辦法再聯(lián)系了。
通過opener屬性厦坛,可以獲得父窗口的全局屬性和方法五垮,但只限于兩個窗口同源的情況,且其中一個窗口由另一個打開杜秸。<a>元素添加rel="noopener"屬性放仗,可以防止新打開的窗口獲取父窗口,減輕被惡意網(wǎng)站修改父窗口 URL 的風(fēng)險撬碟。
<a target="_blank" rel="noopener">
惡意網(wǎng)站
</a>
3.window.self诞挨,window.window
window.self和window.window都指向當(dāng)前窗口
window.window === window; //true
window.self = window; //true
4.window.frames,window.length
window.frames返回一個類似數(shù)組的對象呢蛤,成員由當(dāng)前頁面所包含的框架結(jié)構(gòu)構(gòu)成惶傻,包含了frame和iframe。window.frames[0]可以獲取頁面第一個窗口結(jié)構(gòu)其障。
如果iframe設(shè)置了id或者name屬性银室,我們可以通過屬性來獲取窗口。如<iframe name="iframeName" />name可以通過window.iframes['iframeName']來獲取励翼,或者frames.iframeName蜈敢。
某種程度上來講,frames其實(shí)上就是一個window對象汽抚。
frames === window; //true
所以我們frames[0]也可以直接使用window[0]來表示抓狭。但是從語義上來講,frames更加確切一些造烁,而且window是全局對象否过,容易搞混,因此推薦使用frames來表達(dá)膨蛮。
window.length表示當(dāng)前網(wǎng)頁包含的框架數(shù)量叠纹,如果頁面不包含frame或者iframe元素,則返回0
window.frames.length === window.length; //true
從上面代碼也可以看出來frames其實(shí)也就是window
5.window.frameElement
window.frameElement主要應(yīng)用于一個頁面嵌套在另一個頁面的情況敞葛。(<object>、<frame>与涡、<embed>),返回當(dāng)前元素所在的那個頁面節(jié)點(diǎn)惹谐,如果當(dāng)前頁面時頂層,或者所嵌入的不是同源(非同一資源下的頁面)的驼卖,則返回null氨肌。
//在index.html中
<frame src="b.html">
//在b.html中
const frameB = window.frameElement;
if(frameB){
frameB .src = 'v.html';
}
以上frameB指的就是frame。
6.window.top和window.parent
window.top指的是當(dāng)前頁面的最頂層框架酌畜,主要用于frame框架頁面中怎囚。
window.parent指的是當(dāng)前框架的父框架
window.top === window.parent;
以上方法可以用來判斷是否是多層嵌套的頁面。
7.window.status
window.status主要用于讀寫瀏覽器狀態(tài)欄的內(nèi)容。但是現(xiàn)在大部分瀏覽器是不允許修改的恳守,所以基本沒什么用考婴。
8.window.devicePixelRatio
window.devicePixelRatio返回一個數(shù)值,表示css像素大小與顯示器物理像素的一個比例催烘。也就是表示css像素由多少個物理像素構(gòu)成沥阱。
它可以用來表示用戶顯示器的顯示效果,也就是說這個數(shù)值越大,表示用戶用的越是高清顯示器,我們便可以使用高像素的照片或者視頻冕广。
9.位置信息
以下返回window的大小及位置信息
(1)window.screenX和window.screenY
window.screenX和window.screenY返回瀏覽器窗口相對于顯示器左上角的水平距離和垂直距離宋雏。這兩個屬性都是只讀屬性。
(2)window.innerWith和window.innerHeight
window.innerWith和window.innerHeight返回當(dāng)前網(wǎng)頁在在窗口中可見部分的大小涛贯,即視口(viewport)的大小,也是只讀屬性
(3)window.outerWith和window.outerHeight
window.outerWith和window.outerHeight返回當(dāng)前瀏覽器窗口的大小,包括瀏覽器的任務(wù)欄及邊框等易茬。也是只讀屬性。
(4)window.scrollX和window.scrollY
window.scrollX和window.scrollY返回當(dāng)前網(wǎng)頁的水平和垂直感動距離及老,單位都是像素抽莱,且是只讀屬性。
這兩個屬性返回的是雙精度浮點(diǎn)數(shù)骄恶,并不是整數(shù)食铐,如果頁面沒有滾動,則返回0.
(5)window.pageXOffset僧鲁,window.pageYOffset
window.pageXOffset虐呻,window.pageYOffset是window.scrollX和window.scrollY的別名,用法一致寞秃。
window屬性
window.locationbar:地址欄對象
window.menubar:菜單欄對象
window.scrollbars:窗口的滾動條對象
window.toolbar:工具欄對象
window.statusbar:狀態(tài)欄對象
window.personalbar:用戶安裝的個人工具欄對象
這些屬性的visible屬性表示這些屬性是否可見斟叼,都是只讀屬性。
window.locationbar.visible
window.menubar.visible
window.scrollbars.visible
window.toolbar.visible
window.statusbar.visible
window.personalbar.visible
全局對象屬性
- window.document對象春寿,即document對象朗涩。這個屬性有同源限制,只有同源的屬性才能讀取這個屬性
- window.location對象绑改,即location對象谢床,用來獲取網(wǎng)頁URL的相關(guān)信息,等同于document.location厘线。
- window.navigator识腿,指向Navigator對象,用于獲取環(huán)境信息造壮。
- window.history渡讼,指向History對象,用于獲取瀏覽器的瀏覽歷史
- window.localStorage,指向?yàn)g覽器本地存儲localStorage數(shù)據(jù)對象成箫。
- window.sessionStorage展箱,指向本地存儲的sessionStorage數(shù)據(jù)對象。
- window.console伟众,指向sonsole對象析藕,用于操作控制臺。
- window.screen凳厢,獲取當(dāng)前屏幕的信息账胧。
window.isSecureContext
用于判斷當(dāng)前窗口是否屬于加密環(huán)境,返回一個Boolean值先紫。如果是https返回true治泥,http返回false。
window的方法
window.alert()遮精、window.prompt()居夹、window.confirm()都是瀏覽器與用戶互動的全局方法。它們會彈出不同的對話框本冲,要求用戶做出回應(yīng)准脂。注意,這三個方法彈出的對話框檬洞,都是瀏覽器統(tǒng)一規(guī)定的式樣狸膏,無法定制。也可以省去window添怔,直接嗲用方法湾戳。
這三個方法都具有堵塞效應(yīng),一旦彈出對話框广料,整個頁面就是暫停執(zhí)行砾脑,等待用戶做出反應(yīng)。
window.alert('hello')
window.alert()方法彈出的對話框艾杏,只有一個“確定”按鈕韧衣,往往用來通知用戶某些信息。
用戶只有點(diǎn)擊“確定”按鈕糜颠,對話框才會消失汹族。對話框彈出期間,瀏覽器窗口處于凍結(jié)狀態(tài)其兴,如果不點(diǎn)“確定”按鈕,用戶什么也干不了夸政。
window.alert()方法的參數(shù)只能是字符串元旬,沒法使用 CSS 樣式,但是可以用\n指定換行。
var result = prompt('您的年齡匀归?', 25)
window.prompt()方法彈出的對話框坑资,提示文字的下方,還有一個輸入框穆端,要求用戶輸入信息袱贮,并有“確定”和“取消”兩個按鈕。它往往用來獲取用戶輸入的數(shù)據(jù)体啰。
上面代碼會跳出一個對話框攒巍,文字提示為“您的年齡?”荒勇,要求用戶在對話框中輸入自己的年齡(默認(rèn)顯示25)柒莉。用戶填入的值,會作為返回值存入變量result沽翔。
window.prompt()的返回值有兩種情況兢孝,可能是字符串(有可能是空字符串),也有可能是null仅偎。具體分成三種情況跨蟹。
用戶輸入信息,并點(diǎn)擊“確定”橘沥,則用戶輸入的信息就是返回值窗轩。
用戶沒有輸入信息,直接點(diǎn)擊“確定”威恼,則輸入框的默認(rèn)值就是返回值品姓。
用戶點(diǎn)擊了“取消”(或者按了 ESC 按鈕),則返回值是null箫措。
window.prompt()方法的第二個參數(shù)是可選的腹备,但是最好總是提供第二個參數(shù),作為輸入框的默認(rèn)值斤蔓。
var result = confirm('你最近好嗎植酥?');
var okay = confirm('Please confirm this message.');
if (okay) {
// 用戶按下“確定”
} else {
// 用戶按下“取消”
}
window.confirm()方法彈出的對話框,除了提示信息之外弦牡,只有“確定”和“取消”兩個按鈕友驮,往往用來征詢用戶是否同意。
上面代碼彈出一個對話框驾锰,上面只有一行文字“你最近好嗎卸留?”,用戶選擇點(diǎn)擊“確定”或“取消”椭豫。
confirm方法返回一個布爾值耻瑟,如果用戶點(diǎn)擊“確定”旨指,返回true;如果用戶點(diǎn)擊“取消”喳整,則返回false谆构。
confirm的一個用途是,用戶離開當(dāng)前頁面時框都,彈出一個對話框搬素,問用戶是否真的要離開。
window的操作事件
window.open方法用于新建另一個瀏覽器窗口魏保,類似于瀏覽器菜單的新建窗口選項(xiàng)熬尺。它會返回新窗口的引用,如果無法新建窗口囱淋,則返回null猪杭。
window.open();
var popup = window.open('somefile.html');
上面代碼會讓瀏覽器彈出一個新建窗口,網(wǎng)址是當(dāng)前域名下的somefile.html妥衣。
open方法一共可以接受三個參數(shù)皂吮。
- url:字符串,表示新窗口的網(wǎng)址税手。如果省略蜂筹,默認(rèn)網(wǎng)址就是about:blank。
- windowName:字符串芦倒,表示新窗口的名字艺挪。如果該名字的窗口已經(jīng)存在,則占用該窗口兵扬,不再新建窗口麻裳。如果省略,就默認(rèn)使用_blank器钟,表示新建一個沒有名字的窗口津坑。另外還有幾個預(yù)設(shè)值,_self表示當(dāng)前窗口傲霸,_top表示頂層窗口疆瑰,_parent表示上一層窗口。
- windowFeatures:字符串昙啄,內(nèi)容為逗號分隔的鍵值對(詳見下文)穆役,表示新窗口的參數(shù),比如有沒有提示欄梳凛、工具條等等耿币。如果省略,則默認(rèn)打開一個完整 UI 的新窗口韧拒。如果新建的是一個已經(jīng)存在的窗口掰读,則該參數(shù)不起作用秘狞,瀏覽器沿用以前窗口的參數(shù)叭莫。
var popup = window.open(
'somepage.html',
'DefinitionsWindows',
'height=200,width=200,location=no,status=yes,resizable=yes,scrollbars=yes'
);
如上蹈集,是一個比較完整的例子。
第三個參數(shù)可以使用的參數(shù):
- left:新窗口距離屏幕最左邊的距離(單位像素)雇初。注意拢肆,新窗口必須是可見的,不能設(shè)置在屏幕以外的位置靖诗。
- top:新窗口距離屏幕最頂部的距離(單位像素)郭怪。
- height:新窗口內(nèi)容區(qū)域的高度(單位像素),不得小于100刊橘。
- width:新窗口內(nèi)容區(qū)域的寬度(單位像素)鄙才,不得小于100。
- outerHeight:整個瀏覽器窗口的高度(單位像素)促绵,不得小于100攒庵。
- outerWidth:整個瀏覽器窗口的寬度(單位像素),不得小于100败晴。
- menubar:是否顯示菜單欄浓冒。
- toolbar:是否顯示工具欄。
- location:是否顯示地址欄尖坤。
- personalbar:是否顯示用戶自己安裝的工具欄稳懒。
- status:是否顯示狀態(tài)欄。
- dependent:是否依賴父窗口慢味。如果依賴场梆,那么父窗口最小化,該窗口也最小化纯路;父窗口關(guān)閉或油,該窗口也關(guān)閉。
- minimizable:是否有最小化按鈕感昼,前提是dialog=yes装哆。
- noopener:新窗口將與父窗口切斷聯(lián)系,即新窗口的window.opener屬性返回null定嗓,父窗口的window.open()方法也返回null蜕琴。
- resizable:新窗口是否可以調(diào)節(jié)大小。
- scrollbars:是否允許新窗口出現(xiàn)滾動條宵溅。
- dialog:新窗口標(biāo)題欄是否出現(xiàn)最大化凌简、最小化、恢復(fù)原始大小的控件恃逻。
- titlebar:新窗口是否顯示標(biāo)題欄雏搂。
- alwaysRaised:是否顯示在所有窗口的頂部藕施。
- alwaysLowered:是否顯示在父窗口的底下。
- close:新窗口是否顯示關(guān)閉按鈕凸郑。
對于那些可以打開和關(guān)閉的屬性裳食,設(shè)為yes或1或不設(shè)任何值就表示打開,比如status=yes芙沥、status=1诲祸、status都會得到同樣的結(jié)果。如果想設(shè)為關(guān)閉而昨,不用寫no救氯,而是直接省略這個屬性即可。也就是說歌憨,如果在第三個參數(shù)中設(shè)置了一部分屬性着憨,其他沒有被設(shè)置的yes/no屬性都會被設(shè)成no,只有titlebar和關(guān)閉按鈕除外(它們的值默認(rèn)為yes)务嫡。
另外甲抖,open()方法的第二個參數(shù)雖然可以指定已經(jīng)存在的窗口,但是不等于可以任意控制其他窗口植袍。為了防止被不相干的窗口控制惧眠,瀏覽器只有在兩個窗口同源,或者目標(biāo)窗口被當(dāng)前網(wǎng)頁打開的情況下于个,才允許open方法指向該窗口氛魁。
window.open方法返回新窗口的引用。
var windowB = window.open('windowB.html', 'WindowB');
windowB.window.name // "WindowB"
注意厅篓,如果新窗口和父窗口不是同源的(即不在同一個域)秀存,它們彼此不能獲取對方窗口對象的內(nèi)部屬性。
下面是另一個例子羽氮。
var w = window.open();
console.log('已經(jīng)打開新窗口');
w.location = 'http://example.com';
上面代碼先打開一個新窗口或链,然后在該窗口彈出一個對話框,再將網(wǎng)址導(dǎo)向example.com档押。
由于open這個方法很容易被濫用澳盐,許多瀏覽器默認(rèn)都不允許腳本自動新建窗口。只允許在用戶點(diǎn)擊鏈接或按鈕時令宿,腳本做出反應(yīng)叼耙,彈出新窗口。因此粒没,有必要檢查一下打開新窗口是否成功筛婉。
var popup = window.open();
if (popup === null) {
// 新建窗口失敗
}
window.close();
window.close方法用于關(guān)閉當(dāng)前窗口,一般只用來關(guān)閉window.open方法新建的窗口癞松。
popup.close()
該方法只對頂層窗口有效爽撒,iframe框架之中的窗口使用該方法無效入蛆。
window.stop()
window.stop()方法完全等同于單擊瀏覽器的停止按鈕,會停止加載圖像硕勿、視頻等正在或等待加載的對象哨毁。
window.stop()
window.moveTo(),window.moveBy()
window.moveTo()方法用于移動瀏覽器窗口到指定位置首尼。它接受兩個參數(shù)挑庶,分別是窗口左上角距離屏幕左上角的水平距離和垂直距離,單位為像素软能。
window.moveTo(100, 200)
上面代碼將窗口移動到屏幕(100, 200)的位置。
window.moveBy()方法將窗口移動到一個相對位置举畸。它接受兩個參數(shù)查排,分別是窗口左上角向右移動的水平距離和向下移動的垂直距離,單位為像素抄沮。
window.moveBy(25, 50)
上面代碼將窗口向右移動25像素跋核、向下移動50像素。
為了防止有人濫用這兩個方法叛买,隨意移動用戶的窗口砂代,目前只有一種情況,瀏覽器允許用腳本移動窗口:該窗口是用window.open()方法新建的率挣,并且窗口里只有它一個 Tab 頁刻伊。除此以外的情況,使用上面兩個方法都是無效的椒功。
window.resizeTo()捶箱,window.resizeBy()
window.resizeTo()方法用于縮放窗口到指定大小。
它接受兩個參數(shù)动漾,第一個是縮放后的窗口寬度(outerWidth屬性丁屎,包含滾動條、標(biāo)題欄等等)旱眯,第二個是縮放后的窗口高度(outerHeight屬性)晨川。
window.resizeTo(
window.screen.availWidth / 2,
window.screen.availHeight / 2
)
上面代碼將當(dāng)前窗口縮放到,屏幕可用區(qū)域的一半寬度和高度删豺。
window.resizeBy()方法用于縮放窗口共虑。它與window.resizeTo()的區(qū)別是,它按照相對的量縮放吼鳞,window.resizeTo()需要給出縮放后的絕對大小看蚜。
它接受兩個參數(shù),第一個是水平縮放的量赔桌,第二個是垂直縮放的量供炎,單位都是像素渴逻。
window.resizeBy(-200, -200)
上面的代碼將當(dāng)前窗口的寬度和高度,都縮小200像素音诫。
window.scrollTo()惨奕,window.scroll(),window.scrollBy()
window.scrollTo方法用于將文檔滾動到指定位置竭钝。它接受兩個參數(shù)梨撞,表示滾動后位于窗口左上角的頁面坐標(biāo)。
window.scrollTo(x-coord, y-coord)
它也可以接受一個配置對象作為參數(shù)香罐。
window.scrollTo(options)
配置對象options有三個屬性卧波。
- top:滾動后頁面左上角的垂直坐標(biāo),即 y 坐標(biāo)庇茫。
- left:滾動后頁面左上角的水平坐標(biāo)港粱,即 x 坐標(biāo)。
- behavior:字符串旦签,表示滾動的方式查坪,有三個可能值(smooth、instant宁炫、auto)偿曙,默認(rèn)值為auto。
top: 1000,
behavior: 'smooth'
});
window.scroll()方法是window.scrollTo()方法的別名羔巢。
window.scrollBy()方法用于將網(wǎng)頁滾動指定距離(單位像素)望忆。它接受兩個參數(shù):水平向右滾動的像素,垂直向下滾動的像素朵纷。
window.scrollBy(0, window.innerHeight)
上面代碼用于將網(wǎng)頁向下滾動一屏炭臭。
如果不是要滾動整個文檔,而是要滾動某個元素袍辞,可以使用下面三個屬性和方法鞋仍。
Element.scrollTop
Element.scrollLeft
Element.scrollIntoView()
window.print()
window.print方法會跳出打印對話框,與用戶點(diǎn)擊菜單里面的“打印”命令效果相同搅吁。
常見的打印按鈕代碼如下威创。
document.getElementById('printLink').onclick = function () {
window.print();
}
非桌面設(shè)備(比如手機(jī))可能沒有打印功能,這時可以這樣判斷谎懦。
// 支持打印功能
}
window.focus()肚豺,window.blur()
window.focus()方法會激活窗口,使其獲得焦點(diǎn)界拦,出現(xiàn)在其他窗口的前面吸申。
var popup = window.open('popup.html', 'Popup Window');
if ((popup !== null) && !popup.closed) {
popup.focus();
}
上面代碼先檢查popup窗口是否依然存在,確認(rèn)后激活該窗口。
window.blur()方法將焦點(diǎn)從窗口移除截碴。
當(dāng)前窗口獲得焦點(diǎn)時梳侨,會觸發(fā)focus事件;當(dāng)前窗口失去焦點(diǎn)時日丹,會觸發(fā)blur事件走哺。
window.getSelection()
window.getSelection方法返回一個Selection對象,表示用戶現(xiàn)在選中的文本哲虾。
var selObj = window.getSelection();
使用Selection對象的toString方法可以得到選中的文本丙躏。
var selectedText = selObj.toString();
window.getComputedStyle(),window.matchMedia()
window.getComputedStyle()方法接受一個元素節(jié)點(diǎn)作為參數(shù)束凑,返回一個包含該元素的最終樣式信息的對象晒旅。
window.matchMedia()方法用來檢查 CSS 的mediaQuery語句。
window.requestAnimationFrame()
window.requestAnimationFrame()方法跟setTimeout類似湘今,都是推遲某個函數(shù)的執(zhí)行敢朱。不同之處在于,setTimeout必須指定推遲的時間摩瞎,window.requestAnimationFrame()則是推遲到瀏覽器下一次重流時執(zhí)行,執(zhí)行完才會進(jìn)行下一次重繪孝常。重繪通常是 16ms 執(zhí)行一次旗们,不過瀏覽器會自動調(diào)節(jié)這個速率,比如網(wǎng)頁切換到后臺 Tab 頁時构灸,requestAnimationFrame()會暫停執(zhí)行上渴。
如果某個函數(shù)會改變網(wǎng)頁的布局,一般就放在window.requestAnimationFrame()里面執(zhí)行喜颁,這樣可以節(jié)省系統(tǒng)資源稠氮,使得網(wǎng)頁效果更加平滑。因?yàn)槁僭O(shè)備會用較慢的速率重流和重繪半开,而速度更快的設(shè)備會有更快的速率隔披。
該方法接受一個回調(diào)函數(shù)作為參數(shù)。
window.requestAnimationFrame(callback)
上面代碼中寂拆,callback是一個回調(diào)函數(shù)奢米。callback執(zhí)行時,它的參數(shù)就是系統(tǒng)傳入的一個高精度時間戳(performance.now()的返回值)纠永,單位是毫秒鬓长,表示距離網(wǎng)頁加載的時間。
window.requestAnimationFrame()的返回值是一個整數(shù)尝江,這個整數(shù)可以傳入window.cancelAnimationFrame()涉波,用來取消回調(diào)函數(shù)的執(zhí)行。
下面是一個window.requestAnimationFrame()執(zhí)行網(wǎng)頁動畫的例子。
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';
// 如果距離第一次執(zhí)行不超過 2000 毫秒苍日,
// 就繼續(xù)執(zhí)行動畫
if (progress < 2000) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
上面代碼定義了一個網(wǎng)頁動畫,持續(xù)時間是2秒城侧,會讓元素向右移動易遣。
window.requestIdleCallback()
window.requestIdleCallback()跟setTimeout類似,也是將某個函數(shù)推遲執(zhí)行嫌佑,但是它保證將回調(diào)函數(shù)推遲到系統(tǒng)資源空閑時執(zhí)行豆茫。也就是說,如果某個任務(wù)不是很關(guān)鍵屋摇,就可以使用window.requestIdleCallback()將其推遲執(zhí)行揩魂,以保證網(wǎng)頁性能。
它跟window.requestAnimationFrame()的區(qū)別在于炮温,后者指定回調(diào)函數(shù)在下一次瀏覽器重排時執(zhí)行火脉,問題在于下一次重排時,系統(tǒng)資源未必空閑柒啤,不一定能保證在16毫秒之內(nèi)完成倦挂;window.requestIdleCallback()可以保證回調(diào)函數(shù)在系統(tǒng)資源空閑時執(zhí)行。
該方法接受一個回調(diào)函數(shù)和一個配置對象作為參數(shù)担巩。配置對象可以指定一個推遲執(zhí)行的最長時間方援,如果過了這個時間,回調(diào)函數(shù)不管系統(tǒng)資源有無空虛涛癌,都會執(zhí)行犯戏。
window.requestIdleCallback(callback[, options])
callback參數(shù)是一個回調(diào)函數(shù)。該回調(diào)函數(shù)執(zhí)行時拳话,系統(tǒng)會傳入一個IdleDeadline對象作為參數(shù)先匪。IdleDeadline對象有一個didTimeout屬性(布爾值,表示是否為超時調(diào)用)和一個timeRemaining()方法(返回該空閑時段剩余的毫秒數(shù))弃衍。
options參數(shù)是一個配置對象呀非,目前只有timeout一個屬性,用來指定回調(diào)函數(shù)推遲執(zhí)行的最大毫秒數(shù)笨鸡。該參數(shù)可選姜钳。
window.requestIdleCallback()方法返回一個整數(shù)。該整數(shù)可以傳入window.cancelIdleCallback()取消回調(diào)函數(shù)形耗。
下面是一個例子哥桥。
requestIdleCallback(myNonEssentialWork);
function myNonEssentialWork(deadline) {
while (deadline.timeRemaining() > 0) {
doWorkIfNeeded();
}
}
上面代碼中,requestIdleCallback()用來執(zhí)行非關(guān)鍵任務(wù)myNonEssentialWork激涤。該任務(wù)先確認(rèn)本次空閑時段有剩余時間拟糕,然后才真正開始執(zhí)行任務(wù)判呕。
下面是指定timeout的例子。
requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 });
上面代碼指定送滞,processPendingAnalyticsEvents必須在未來2秒之內(nèi)執(zhí)行侠草。
如果由于超時導(dǎo)致回調(diào)函數(shù)執(zhí)行,則deadline.timeRemaining()返回0犁嗅,deadline.didTimeout返回true边涕。
如果多次執(zhí)行window.requestIdleCallback(),指定多個回調(diào)函數(shù)褂微,那么這些回調(diào)函數(shù)將排成一個隊(duì)列功蜓,按照先進(jìn)先出的順序執(zhí)行。
load 事件和 onload 屬性
load事件發(fā)生在文檔在瀏覽器窗口加載完畢時宠蚂。window.onload屬性可以指定這個事件的回調(diào)函數(shù)式撼。
window.onload = function() {
var elements = document.getElementsByClassName('example');
for (var i = 0; i < elements.length; i++) {
var elt = elements[i];
// ...
}
};
error 事件和 onerror 屬性
瀏覽器腳本發(fā)生錯誤時,會觸發(fā)window對象的error事件求厕。我們可以通過window.onerror屬性對該事件指定回調(diào)函數(shù)著隆。
window.onerror = function (message, filename, lineno, colno, error) {
console.log("出錯了!--> %s", error.stack);
};
由于歷史原因呀癣,window的error事件的回調(diào)函數(shù)不接受錯誤對象作為參數(shù)美浦,而是一共可以接受五個參數(shù),它們的含義依次如下项栏。
- 出錯信息
- 出錯腳本的網(wǎng)址
- 行號
- 列號
- 錯誤對象
老式瀏覽器只支持前三個參數(shù)抵代。
并不是所有的錯誤,都會觸發(fā) JavaScript 的error事件(即讓 JavaScript 報錯)忘嫉。一般來說,只有 JavaScript 腳本的錯誤案腺,才會觸發(fā)這個事件庆冕,而像資源文件不存在之類的錯誤,都不會觸發(fā)劈榨。
下面是一個例子访递,如果整個頁面未捕獲錯誤超過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;
需要注意的是拷姿,如果腳本網(wǎng)址與網(wǎng)頁網(wǎng)址不在同一個域(比如使用了 CDN),瀏覽器根本不會提供詳細(xì)的出錯信息旱函,只會提示出錯响巢,錯誤類型是“Script error.”,行號為0棒妨,其他信息都沒有踪古。這是瀏覽器防止向外部腳本泄漏信息。一個解決方法是在腳本所在的服務(wù)器,設(shè)置Access-Control-Allow-Origin的 HTTP 頭信息伏穆。
Access-Control-Allow-Origin: *
然后拘泞,在網(wǎng)頁的<script>標(biāo)簽中設(shè)置crossorigin屬性。
<script crossorigin="anonymous" src="http://example.com/file.js"></script>
上面代碼的crossorigin="anonymous"表示枕扫,讀取文件不需要身份信息陪腌,即不需要 cookie 和 HTTP 認(rèn)證信息。如果設(shè)為crossorigin="use-credentials"烟瞧,就表示瀏覽器會上傳 cookie 和 HTTP 認(rèn)證信息诗鸭,同時還需要服務(wù)器端打開 HTTP 頭信息Access-Control-Allow-Credentials。
window 對象的事件監(jiān)聽屬性
除了具備元素節(jié)點(diǎn)都有的 GlobalEventHandlers 接口燕刻,window對象還具有以下的事件監(jiān)聽函數(shù)屬性只泼。
- window.onafterprint:afterprint事件的監(jiān)聽函數(shù)。
- window.onbeforeprint:beforeprint事件的監(jiān)聽函數(shù)卵洗。
- window.onbeforeunload:beforeunload事件的監(jiān)聽函數(shù)请唱。
- window.onhashchange:hashchange事件的監(jiān)聽函數(shù)。
- window.onlanguagechange: languagechange的監(jiān)聽函數(shù)过蹂。
- window.onmessage:message事件的監(jiān)聽函數(shù)十绑。
- window.onmessageerror:MessageError事件的監(jiān)聽函數(shù)。
- window.onoffline:offline事件的監(jiān)聽函數(shù)酷勺。
- window.ononline:online事件的監(jiān)聽函數(shù)本橙。
- window.onpagehide:pagehide事件的監(jiān)聽函數(shù)。
- window.onpageshow:pageshow事件的監(jiān)聽函數(shù)脆诉。
- window.onpopstate:popstate事件的監(jiān)聽函數(shù)甚亭。
- window.onstorage:storage事件的監(jiān)聽函數(shù)。
- window.onunhandledrejection:未處理的 Promise 對象的reject事件的監(jiān)聽函數(shù)击胜。
- window.onunload:unload事件的監(jiān)聽函數(shù)亏狰。
多窗口操作
由于網(wǎng)頁可以使用iframe元素,嵌入其他網(wǎng)頁偶摔,因此一個網(wǎng)頁之中會形成多個窗口暇唾。如果子窗口之中又嵌入別的網(wǎng)頁,就會形成多級窗口辰斋。
窗口的引用
各個窗口之中的腳本策州,可以引用其他窗口。瀏覽器提供了一些特殊變量宫仗,用來返回其他窗口够挂。
- window.top:頂層窗口,即最上層的那個窗口
- window.parent:父窗口
- window.self:當(dāng)前窗口锰什,即自身
下面代碼可以判斷下硕,當(dāng)前窗口是否為頂層窗口丁逝。
if (window.top === window.self) {
// 當(dāng)前窗口是頂層窗口
} else {
// 當(dāng)前窗口是子窗口
}
下面的代碼讓父窗口的訪問歷史后退一次。
window.parent.history.back();
與這些變量對應(yīng)梭姓,瀏覽器還提供一些特殊的窗口名霜幼,供window.open()方法、<a>標(biāo)簽誉尖、<form>標(biāo)簽等引用罪既。
_top:頂層窗口
_parent:父窗口
_blank:新窗口
下面代碼就表示在頂層窗口打開鏈接。
<a href="somepage.html" target="_top">Link</a>
iframe 元素
對于iframe嵌入的窗口铡恕,document.getElementById方法可以拿到該窗口的 DOM 節(jié)點(diǎn)琢感,然后使用contentWindow屬性獲得iframe節(jié)點(diǎn)包含的window對象。
var frame = document.getElementById('theFrame');
var frameWindow = frame.contentWindow;
上面代碼中探熔,frame.contentWindow可以拿到子窗口的window對象驹针。然后,在滿足同源限制的情況下诀艰,可以讀取子窗口內(nèi)部的屬性柬甥。
// 獲取子窗口的標(biāo)題
frameWindow.title
<iframe>元素的contentDocument屬性,可以拿到子窗口的document對象其垄。
var frame = document.getElementById('theFrame');
var frameDoc = frame.contentDocument;
// 等同于
var frameDoc = frame.contentWindow.document;
<iframe>元素遵守同源政策苛蒲,只有當(dāng)父窗口與子窗口在同一個域時,兩者之間才可以用腳本通信绿满,否則只有使用window.postMessage方法臂外。
<iframe>窗口內(nèi)部,使用window.parent引用父窗口喇颁。如果當(dāng)前頁面沒有父窗口漏健,則window.parent屬性返回自身。因此橘霎,可以通過window.parent是否等于window.self漾肮,判斷當(dāng)前窗口是否為iframe窗口。
if (window.parent !== window.self) {
// 當(dāng)前窗口是子窗口
}
<iframe>窗口的window對象茎毁,有一個frameElement屬性,返回<iframe>在父窗口中的 DOM 節(jié)點(diǎn)忱辅。對于非嵌入的窗口七蜘,該屬性等于null。
var f1Element = document.getElementById('f1');
var f1Window = f1Element.contentWindow;
f1Window.frameElement === f1Element // true
window.frameElement === null // true
window.frames 屬性
window.frames屬性返回一個類似數(shù)組的對象墙懂,成員是所有子窗口的window對象橡卤。可以使用這個屬性损搬,實(shí)現(xiàn)窗口之間的互相引用碧库。比如柜与,frames[0]返回第一個子窗口,frames[1].frames[2]返回第二個子窗口內(nèi)部的第三個子窗口嵌灰,parent.frames[1]返回父窗口的第二個子窗口弄匕。
注意,window.frames每個成員的值沽瞭,是框架內(nèi)的窗口(即框架的window對象)迁匠,而不是iframe標(biāo)簽在父窗口的 DOM 節(jié)點(diǎn)。如果要獲取每個框架內(nèi)部的 DOM 樹驹溃,需要使用window.frames[0].document的寫法城丧。
另外,如果<iframe>元素設(shè)置了name或id屬性豌鹤,那么屬性值會自動成為全局變量亡哄,并且可以通過window.frames屬性引用,返回子窗口的window對象布疙。
// HTML 代碼為 <iframe id="myFrame">
window.myFrame // [HTMLIFrameElement]
frames.myframe === myFrame // true
另外蚊惯,name屬性的值會自動成為子窗口的名稱,可以用在window.open方法的第二個參數(shù)拐辽,或者<a>和<frame>標(biāo)簽的target屬性拣挪。
完結(jié),撒花