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