Page?Visibility?API?教程示例
一、簡(jiǎn)介
有時(shí)候,開發(fā)者需要知道,用戶正在離開頁面。常用的方法是監(jiān)聽下面三個(gè)事件。
pagehide
beforeunload
unload
但是,這些事件在手機(jī)上可能不會(huì)觸發(fā),頁面就直接關(guān)閉了。因?yàn)槭謾C(jī)系統(tǒng)可以將一個(gè)進(jìn)程直接轉(zhuǎn)入后臺(tái),然后殺死。
- 用戶點(diǎn)擊了一條系統(tǒng)通知,切換到另一個(gè) App。
- 用戶進(jìn)入任務(wù)切換窗口,切換到另一個(gè) App。
- 用戶點(diǎn)擊了 Home 按鈕,切換回主屏幕。
- 操作系統(tǒng)自動(dòng)切換到另一個(gè) App(比如,收到一個(gè)電話)。
上面這些情況,都會(huì)導(dǎo)致手機(jī)將瀏覽器進(jìn)程切換到后臺(tái),然后為了節(jié)省資源,可能就會(huì)殺死瀏覽器進(jìn)程。
以前,頁面被系統(tǒng)切換,以及系統(tǒng)清除瀏覽器進(jìn)程,是無法監(jiān)聽到的。開發(fā)者想要指定,任何一種頁面卸載情況下都會(huì)執(zhí)行的代碼,也是無法做到的。為了解決這個(gè)問題,就誕生了 Page Visibility API。不管手機(jī)或桌面電腦,所有情況下,這個(gè) API 都會(huì)監(jiān)聽到頁面的可見性發(fā)生變化。
這個(gè)新的 API 的意義在于,通過監(jiān)聽網(wǎng)頁的可見性,可以預(yù)判網(wǎng)頁的卸載,還可以用來節(jié)省資源,減緩電能的消耗。比如,一旦用戶不看網(wǎng)頁,下面這些網(wǎng)頁行為都是可以暫停的。
- 對(duì)服務(wù)器的輪詢
- 網(wǎng)頁動(dòng)畫
- 正在播放的音頻或視頻
二、document.visibilityState
這個(gè) API 主要在document
對(duì)象上,新增了一個(gè)document.visibilityState
屬性。該屬性返回一個(gè)字符串,表示頁面當(dāng)前的可見性狀態(tài),共有三個(gè)可能的值。
hidden
:頁面徹底不可見。
visible
:頁面至少一部分可見。
prerender
:頁面即將或正在渲染,處于不可見狀態(tài)。
其中,hidden
狀態(tài)和visible
狀態(tài)是所有瀏覽器都必須支持的。prerender
狀態(tài)只在支持"預(yù)渲染"的瀏覽器上才會(huì)出現(xiàn),比如 Chrome 瀏覽器就有預(yù)渲染功能,可以在用戶不可見的狀態(tài)下,預(yù)先把頁面渲染出來,等到用戶要瀏覽的時(shí)候,直接展示渲染好的網(wǎng)頁。
只要頁面可見,哪怕只露出一個(gè)角,document.visibilityState
屬性就返回visible
。只有以下四種情況,才會(huì)返回hidden
。
- 瀏覽器最小化。
- 瀏覽器沒有最小化,但是當(dāng)前頁面切換成了背景頁。
- 瀏覽器將要卸載(unload)頁面。
- 操作系統(tǒng)觸發(fā)鎖屏屏幕。
可以看到,上面四種場(chǎng)景涵蓋了頁面可能被卸載的所有情況。也就是說,頁面卸載之前,document.visibilityState
屬性一定會(huì)變成hidden
。
事實(shí)上,這也是設(shè)計(jì)這個(gè) API 的主要目的。
另外,早期版本的 API,這個(gè)屬性還有第四個(gè)值unloaded
,表示頁面即將卸載,現(xiàn)在已經(jīng)被廢棄了。
注意,document.visibilityState
屬性只針對(duì)頂層窗口,內(nèi)嵌的<iframe>
頁面的document.visibilityState
屬性由頂層窗口決定。
使用 CSS 屬性隱藏<iframe>
頁面(比如display: none;
),并不會(huì)影響內(nèi)嵌頁面的可見性。
三、document.hidden
由于歷史原因,這個(gè) API 還定義了document.hidden
屬性。該屬性只讀,返回一個(gè)布爾值,表示當(dāng)前頁面是否可見。
當(dāng)document.visibilityState
屬性返回visible
時(shí),document.hidden
屬性返回false
;其他情況下,都返回true
。
該屬性只是出于歷史原因而保留的,只要有可能,都應(yīng)該使用document.visibilityState
屬性,而不是使用這個(gè)屬性。
四、visibilitychange 事件
只要document.visibilityState
屬性發(fā)生變化,就會(huì)觸發(fā)visibilitychange
事件。
因此,可以通過監(jiān)聽這個(gè)事件(通過document.addEventListener()
方法或document.onvisibilitychange
屬性),跟蹤頁面可見性的變化。
document.addEventListener('visibilitychange', function () { // 用戶離開了當(dāng)前頁面 if (document.visibilityState === 'hidden') { document.title = '頁面不可見'; } // 用戶打開或回到頁面 if (document.visibilityState === 'visible') { document.title = '頁面可見'; } });
上面代碼是 Page Visibility API 的最基本用法,可以監(jiān)聽可見性變化。
下面是另一個(gè)例子,一旦頁面不可見,就暫停視頻播放。
var vidElem = document.getElementById('video-demo'); document.addEventListener('visibilitychange', startStopVideo); function startStopVideo() { if (document.visibilityState === 'hidden') { vidElem.pause(); } else if (document.visibilityState === 'visible') { vidElem.play(); } }
五、頁面卸載
下面專門討論一下,如何正確監(jiān)聽頁面卸載。
頁面卸載可以分成三種情況。
- 頁面可見時(shí),用戶關(guān)閉 Tab 頁或?yàn)g覽器窗口。
- 頁面可見時(shí),用戶在當(dāng)前窗口前往另一個(gè)頁面。
- 頁面不可見時(shí),用戶或系統(tǒng)關(guān)閉瀏覽器窗口。
這三種情況,都會(huì)觸發(fā)visibilitychange
事件。前兩種情況,該事件在用戶離開頁面時(shí)觸發(fā);最后一種情況,該事件在頁面從可見狀態(tài)變?yōu)椴豢梢姞顟B(tài)時(shí)觸發(fā)。
由此可見,visibilitychange
事件比pagehide
、beforeunload
、unload
事件更可靠,所有情況下都會(huì)觸發(fā)(從visible
變?yōu)?code>hidden)。因此,可以只監(jiān)聽這個(gè)事件,運(yùn)行頁面卸載時(shí)需要運(yùn)行的代碼,不用監(jiān)聽后面那三個(gè)事件。
甚至可以這樣說,unload
事件在任何情況下都不必監(jiān)聽,beforeunload
事件只有一種適用場(chǎng)景,就是用戶修改了表單,沒有提交就離開當(dāng)前頁面。另一方面,指定了這兩個(gè)事件的監(jiān)聽函數(shù),瀏覽器就不會(huì)緩存當(dāng)前頁面。
參考鏈接
- Page Visibility Level 2, W3C
- Page Visibility API, David Walsh
- Using the pageVisbility API, Joe Marini
- Don't lose user and app state, use Page Visibility, Ilya Grigorik
以上就是Page Visibility API 教程示例的詳細(xì)內(nèi)容,更多關(guān)于Page Visibility API 教程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
ant-design的upload組件中實(shí)現(xiàn)粘貼上傳實(shí)例詳解
這篇文章主要為大家介紹了ant-design的upload組件中實(shí)現(xiàn)粘貼上傳實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05web?worker在項(xiàng)目中的使用學(xué)習(xí)為項(xiàng)目增加亮點(diǎn)
這篇文章主要為大家介紹了web?worker使用學(xué)習(xí)來為你的項(xiàng)目增加亮點(diǎn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Moment的feature導(dǎo)致線上bug解決分析
這篇文章主要為大家介紹了Moment的feature導(dǎo)致線上bug解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09JS前端模擬Excel條件格式實(shí)現(xiàn)數(shù)據(jù)條效果
這篇文章主要為大家介紹了JS前端模擬Excel條件格式實(shí)現(xiàn)數(shù)據(jù)條效果,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02JavaScript中七種流行的開源機(jī)器學(xué)習(xí)框架
今天小編就為大家分享一篇關(guān)于JavaScript中五種流行的開源機(jī)器學(xué)習(xí)框架,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10微信小程序報(bào)錯(cuò):this.setData is not a function的解決辦法
這篇文章主要介紹了微信小程序報(bào)錯(cuò):this.setData is not a function的解決辦法的相關(guān)資料,希望通過本文能幫助到大家解決這樣類似的問題,需要的朋友可以參考下2017-09-09