一、簡介
要知道用戶何時離開,有常用的方法是監(jiān)聽下面三個事件。
pagehide
beforeunload
unload
可上述三種方法有一個bug就是,這些事件在手機上可能不會觸發(fā),頁面就直接關(guān)閉了。因為手機系統(tǒng)可以將一個進程直接轉(zhuǎn)入后臺,然后殺死。
用戶點擊了一條系統(tǒng)通知,切換到另一個 App。
用戶進入任務(wù)切換窗口,切換到另一個 App。
用戶點擊了 Home 按鈕,切換回主屏幕。
操作系統(tǒng)自動切換到另一個 App(比如,收到一個電話)。
其實上面說的過程是可以實現(xiàn)監(jiān)聽,但會導(dǎo)致手機將瀏覽器進程切換到后臺,這樣手機會因為節(jié)省資源,極有可能就會殺死瀏覽器進程。
之前那無法監(jiān)聽是因為頁面被系統(tǒng)切換,以及系統(tǒng)清除瀏覽器進程?,F(xiàn)在我們換種解決思路,用Page Visibility API。不管手機或桌面電腦,所有情況下,這個 API 都會監(jiān)聽到頁面的可見性發(fā)生變化。
這個新的 API 的意義在于,通過監(jiān)聽網(wǎng)頁的可見性,可以預(yù)判網(wǎng)頁的卸載,還可以用來節(jié)省資源,減緩電能的消耗。比如,一旦用戶不看網(wǎng)頁,下面這些網(wǎng)頁行為都是可以暫停的。
對服務(wù)器的輪詢
網(wǎng)頁動畫
正在播放的音頻或視頻
二、document.visibilityState
這個 API 主要在document對象上,新增了一個document.visibilityState屬性。該屬性返回一個字符串,表示頁面當前的可見性狀態(tài),共有三個可能的值。
hidden:頁面徹底不可見。
visible:頁面至少一部分可見。
prerender:頁面即將或正在渲染,處于不可見狀態(tài)。
其中,hidden狀態(tài)和visible狀態(tài)是所有瀏覽器都必須支持的。prerender狀態(tài)只在支持"預(yù)渲染"的瀏覽器上才會出現(xiàn),比如 Chrome 瀏覽器就有預(yù)渲染功能,可以在用戶不可見的狀態(tài)下,預(yù)先把頁面渲染出來,等到用戶要瀏覽的時候,直接展示渲染好的網(wǎng)頁。
只要頁面可見,哪怕只露出一個角,document.visibilityState屬性就返回visible。只有以下四種情況,才會返回hidden。
瀏覽器最小化。
瀏覽器沒有最小化,但是當前頁面切換成了背景頁。
瀏覽器將要卸載(unload)頁面。
操作系統(tǒng)觸發(fā)鎖屏屏幕。
這樣聽起來是不是將所有阻礙頁面監(jiān)聽的情況都解決了,但頁面卸載之前,document.visibilityState屬性一定會變成hidden。
事實上,這也是設(shè)計這個 API 的主要目的。
另外,早期版本的 API,這個屬性還有第四個值unloaded,表示頁面即將卸載,這也已經(jīng)扔了。
注意,document.visibilityState屬性只針對頂層窗口,內(nèi)嵌的<iframe>頁面的document.visibilityState屬性由頂層窗口決定。
使用 CSS 屬性隱藏<iframe>頁面(比如display: none;),并不會影響內(nèi)嵌頁面的可見性。
三、document.hidden
由于歷史原因,這個 API 還定義了document.hidden屬性。該屬性只讀,返回一個布爾值,表示當前頁面是否可見。
當document.visibilityState屬性返回visible時,document.hidden屬性返回false;其他情況下,都返回true。
該屬性只是出于歷史原因而保留的,只要有可能,都應(yīng)該使用document.visibilityState屬性,而不是使用這個屬性。
四、visibilitychange 事件
只要document.visibilityState屬性發(fā)生變化,就會觸發(fā)visibilitychange事件。
因此,可以通過監(jiān)聽這個事件(通過document.addEventListener()方法或document.onvisibilitychange屬性),跟蹤頁面可見性的變化。
document.addEventListener('visibilitychange', function () { // 用戶離開了當前頁面 if (document.visibilityState === 'hidden') { document.title = '頁面不可見'; } // 用戶打開或回到頁面 if (document.visibilityState === 'visible') { document.title = '頁面可見'; } });
上面代碼是 Page Visibility API 的最基本用法,可以監(jiān)聽可見性變化。
下面是另一個例子,一旦頁面不可見,就暫停視頻播放。
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)聽沒有問題了,我們就說說如何正確監(jiān)聽頁面卸載。
頁面卸載可以分成三種情況。
頁面可見時,用戶關(guān)閉 Tab 頁或瀏覽器窗口。
頁面可見時,用戶在當前窗口前往另一個頁面。
頁面不可見時,用戶或系統(tǒng)關(guān)閉瀏覽器窗口。
這三種情況,都會觸發(fā)visibilitychange事件。前兩種情況,該事件在用戶離開頁面時觸發(fā);最后一種情況,該事件在頁面從可見狀態(tài)變?yōu)椴豢梢姞顟B(tài)時觸發(fā)。
由此可見,visibilitychange事件比pagehide、beforeunload、unload事件更可靠,所有情況下都會觸發(fā)(從visible變?yōu)閔idden)。因此,可以只監(jiān)聽這個事件,運行頁面卸載時需要運行的代碼,不用監(jiān)聽后面那三個事件。
說完上面我們可以知道,其實unload事件在任何情況下都不必監(jiān)聽,beforeunload事件只有一種適用場景,就是用戶修改了表單,沒有提交就離開當前頁面。另一方面,指定了這兩個事件的監(jiān)聽函數(shù),瀏覽器就不會緩存當前頁面。
參考鏈接
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
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/128191.html
摘要:大學(xué),光學(xué)工程研究生畢業(yè),和程序猿完全不搭邊。那怎么辦,試著學(xué)一學(xué)唄,學(xué)習(xí)才是程序猿的天性。所以我在想程序猿是不是都需要新知識刺激一下,才能保持興奮的頭腦。有句話說的很對程序猿就像好奇的貓,追著毛球的線頭玩,最后一個毛球在腦袋里攪漿糊。 說說我自己的經(jīng)歷。211大學(xué),光學(xué)工程研究生畢業(yè),和程序猿完全不搭邊。 畢業(yè)后進了成都某國字頭研究所,在行業(yè)里摸爬滾打了四年,2018年機緣巧合在家養(yǎng)...
摘要:作品演示站源碼地址本站鳴謝程序員翟永超以及主題大部分的前端博客頁面都是使用的主題。下定決心做這個博客也是因為自己面臨畢業(yè),很多東西確實應(yīng)該嘗試。我想是寫博客的必備技能吧。哈哈結(jié)語本篇主要簡單介紹一下的基本情況,下一篇將對的部署和技術(shù)做總結(jié)。 轉(zhuǎn)載請注明博客出處 http://www.eumji025.com/artic... 前言 ? 一直都準備做一個博客系統(tǒng),直到四月份才真正的...
摘要:你只需要花分鐘,就能擁有一個屬于自己的私人博客了,并且可以對整個項目有一個完成的概念和感覺。指令和相似,表達式和保持一致,易學(xué)易用。 本文適合剛學(xué)習(xí)完 Java 語言基礎(chǔ)的人群,跟著本文可了解和運行 Tale 項目。示例均在 Windows 操作系統(tǒng)下演示 showImg(https://segmentfault.com/img/bVbwsbo?w=1578&h=868); 本文作者:...
摘要:比如把上面畫正方形的例子稍做變化重復(fù)執(zhí)行次畫正方形開始畫正方形結(jié)束右轉(zhuǎn)度執(zhí)行后,可以看到,畫出一個非常規(guī)整漂亮的組合圖案。 turtle圖形庫源于1966年誕生的Logo語言,是入門Python的有趣工具。因其簡單便捷的圖形化方法、和立即反饋式的繪畫效果,成為眾多編程入門者的首選。相對于大多數(shù)入門教材中枯燥的語法學(xué)習(xí),和函數(shù)、方法的演練來說,turtle的趣味性顯得別具一格、極富效...
閱讀 547·2023-03-27 18:33
閱讀 732·2023-03-26 17:27
閱讀 630·2023-03-26 17:14
閱讀 591·2023-03-17 21:13
閱讀 521·2023-03-17 08:28
閱讀 1801·2023-02-27 22:32
閱讀 1292·2023-02-27 22:27
閱讀 2178·2023-01-20 08:28