摘要:需求背景在最近的項(xiàng)目中,使用了和定時(shí)器實(shí)現(xiàn)了隨機(jī)走動(dòng)物體的功能,走動(dòng)的物體還會(huì)有的動(dòng)畫。上述代碼中,維護(hù)了兩個(gè)數(shù)組,分別代表頁面進(jìn)入可見狀態(tài)時(shí)需要執(zhí)行的回調(diào)列表和進(jìn)入不可見狀態(tài)時(shí)需要執(zhí)行的回調(diào)列表。
需求背景
在最近的項(xiàng)目中,使用了transition和定時(shí)器實(shí)現(xiàn)了隨機(jī)走動(dòng)物體的功能,走動(dòng)的物體還會(huì)有animation的動(dòng)畫。我發(fā)現(xiàn)在手機(jī)中,按home鍵或者切換應(yīng)用,使頁面不在屏幕中,也就是頁面不可見,過一段時(shí)間切回來,會(huì)出現(xiàn)物體移動(dòng)但是沒有播放animaiton的動(dòng)畫的情況。
我就想到了visibilitychange。
結(jié)合react使用,添加類似onShow/onHide生命周期 額外生命周期瀏覽器document有個(gè)visibilitychange的事件,由于存在兼容性問題,所以代碼里也做了兼容處理。該事件會(huì)在document.visibilityState發(fā)生變化時(shí)觸發(fā),visibilityState有兩個(gè)狀態(tài)值——visible和hidden,表示頁面是否在屏幕當(dāng)中。
let changeState; let visibilityChange; if (typeof document.hidden !== "undefined") { visibilityChange = "visibilitychange"; changeState = "visibilityState"; } else if (typeof document.mozHidden !== "undefined") { visibilityChange = "mozvisibilitychange"; changeState = "mozVisibilityState"; } else if (typeof document.msHidden !== "undefined") { visibilityChange = "msvisibilitychange"; changeState = "msVisibilityState"; } else if (typeof document.webkitHidden !== "undefined") { visibilityChange = "webkitvisibilitychange"; changeState = "webkitVisibilityState"; }
知道了當(dāng)前瀏覽器的狀態(tài)屬性和事件名稱后,就可以添加時(shí)間監(jiān)聽了。
const visibleCallbackList = []; const hiddenCallbackList = []; document.addEventListener( visibilityChange, () => { if (document[changeState] === "visible") { for (let i = 0; i < visibleCallbackList.length; i++) { if (typeof visibleCallbackList[i] === "function") { visibleCallbackList[i](); } } } else if (document[changeState] === "hidden") { for (let i = 0; i < hiddenCallbackList.length; i++) { if (typeof hiddenCallbackList[i] === "function") { hiddenCallbackList[i](); } } } }, false );
上述代碼中,維護(hù)了兩個(gè)數(shù)組,分別代表頁面進(jìn)入可見狀態(tài)時(shí)需要執(zhí)行的回調(diào)列表和進(jìn)入不可見狀態(tài)時(shí)需要執(zhí)行的回調(diào)列表。這兩個(gè)列表在下面會(huì)講到。
因?yàn)槲覀兪鞘褂胷eact開發(fā),所以想在組件級(jí)別做到該組件是否能使用該功能,所以想到讓組件具有類似小程序的onShow和onHide的生命周期,在這個(gè)生命周期中執(zhí)行組件內(nèi)部的邏輯。
export const h5OnShow = callback => { visibleCallbackList.push(callback); }; export const h5OnHide = callback => { hiddenCallbackList.push(callback); }; /** * * @param {Object} * {Function} h5OnShowCallback h5需要注銷的顯示回調(diào) * {Function} h5OnHideCallback h5需要注銷的隱藏回調(diào) */ export const h5ExtraLifecycleWillUnmount = ({ h5OnShowCallback, h5OnHideCallback }) => { if (h5OnShowCallback) { visibleCallbackList.splice(visibleCallbackList.indexOf(h5OnShowCallback), 1); } if (h5OnHideCallback) { hiddenCallbackList.splice(hiddenCallbackList.indexOf(h5OnHideCallback), 1); } };
如上述代碼中,h5OnShow方法中將傳入的callback push至visibleCallbackList數(shù)組,h5OnHide方法將callback push到hiddenCallbackList。
h5ExtraLifecycleWillUnmount是在組件即將要卸載的時(shí)候調(diào)用,將回調(diào)列表里的方法刪除。
componentDidMount() { h5OnShow(this.pageShow); h5OnHide(this.pageHide); } componentWillUnmount() { h5ExtraLifecycleWillUnmount({ h5OnShowCallback: this.pageShow, h5OnHideCallback: this.pageHide }); } pageShow = () => { // 開啟隨機(jī)走動(dòng)定時(shí)器 } pageHide = () => { // 關(guān)閉隨機(jī)走動(dòng)定時(shí)器 }
在組件里,注冊onSHow和onHide,在頁面顯示時(shí)開啟定時(shí)器,在頁面隱藏時(shí)關(guān)閉定時(shí)器并把transition設(shè)置為none,這樣在頁面不可見時(shí)不會(huì)做無用的邏輯處理,這也是符合用戶的預(yù)期,因?yàn)轫撁骐[藏時(shí)并不關(guān)心在這期間做了生命動(dòng)畫變更。
可優(yōu)化點(diǎn):
1.visibleCallbackList和hiddenCallbackList使用WeakSet更好,保證了不會(huì)出現(xiàn)內(nèi)存泄漏。
2.如果組件實(shí)例化多次,pageShow和pageHide使用箭頭函數(shù)并不友好,可使用修飾器模式改變原型上的方法的this指向。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105640.html
一、簡介 要知道用戶何時(shí)離開,有常用的方法是監(jiān)聽下面三個(gè)事件?! agehide beforeunload unload 可上述三種方法有一個(gè)bug就是,這些事件在手機(jī)上可能不會(huì)觸發(fā),頁面就直接關(guān)閉了。因?yàn)槭謾C(jī)系統(tǒng)可以將一個(gè)進(jìn)程直接轉(zhuǎn)入后臺(tái),然后殺死。 用戶點(diǎn)擊了一條系統(tǒng)通知,切換到另一個(gè) App?! ∮脩暨M(jìn)入任務(wù)切換窗口,切換到另一個(gè) App?! ∮脩酎c(diǎn)擊了 Home 按鈕,切換...
摘要:原文譯文的頁面可視性譯者在早期,瀏覽器并沒有提供選項(xiàng)卡,但是現(xiàn)在基本所有瀏覽器都提供了這個(gè)功能。在這個(gè)中,將基于頁面的可視性狀態(tài)彈出文檔的標(biāo)題。對(duì)于常見的手風(fēng)情效果,當(dāng)頁面不可見時(shí),可以限制其移動(dòng)。 原文:HTML5 Page Visibility API 譯文:HTML 5的頁面可視性API 譯者:dwqs showImg(https://segmentfault.com/im...
摘要:問題描述這個(gè)倒計(jì)時(shí)按鈕,如果頁面在移動(dòng)端切到后臺(tái)和切回來,倒計(jì)時(shí)停止運(yùn)行。相關(guān)代碼為了兼容,切換到后臺(tái)繼續(xù)運(yùn)行 問題描述 showImg(https://segmentfault.com/img/bVbiVSh);這個(gè)倒計(jì)時(shí)按鈕,如果頁面在移動(dòng)端切到后臺(tái)和切回來,倒計(jì)時(shí)停止運(yùn)行。但是在pc端沒有這個(gè)問題。倒計(jì)時(shí)代碼如下 let downCount = () => { ...
閱讀 2811·2021-11-22 14:44
閱讀 556·2021-11-22 12:00
閱讀 3693·2019-08-30 15:54
閱讀 1587·2019-08-29 17:15
閱讀 1908·2019-08-29 13:50
閱讀 1123·2019-08-29 13:17
閱讀 3523·2019-08-29 13:05
閱讀 1190·2019-08-29 11:31