我正在使用HTML、CSS和JavaScript編寫一個(gè)瀏覽器遊戲,使用Perl編寫。健康和耐力保存在伺服器上,我使用JavaScript在目前頁面載入時(shí)向使用者顯示這些統(tǒng)計(jì)資料的即時(shí)更新計(jì)數(shù)。這個(gè)功能運(yùn)作良好,但是如果使用者切換標(biāo)籤或切換到其他應(yīng)用程式並將瀏覽器留在背景運(yùn)行,當(dāng)您返回時(shí)看到的計(jì)數(shù)值無法正確跟上。所以當(dāng)您切換回瀏覽器時(shí),您的計(jì)數(shù)器可能顯示50/100的耐力,而實(shí)際上您的耐力是100/100。因此,當(dāng)您在遊戲中執(zhí)行某個(gè)操作(載入新頁面)時(shí),伺服器會(huì)將計(jì)數(shù)器更新為真實(shí)的數(shù)值,因?yàn)镴avaScript只是計(jì)時(shí)以向使用者在瀏覽器中顯示「即時(shí)」捲動(dòng)視圖。
有沒有辦法確保即使頁面/標(biāo)籤不活動(dòng)或不在前臺(tái),JavaScript計(jì)數(shù)器仍然可以正常運(yùn)作?除了完全重寫我的遊戲以在瀏覽器中向用戶顯示連續(xù)的即時(shí)伺服器推送內(nèi)容之外?
假設(shè)您正在玩遊戲。您會(huì)看到您的健康和耐力正在恢復(fù)。您切換到另一個(gè)程式一分鐘,然後返回瀏覽器中的遊戲。您會(huì)注意到您離開期間健康和耐力沒有更新。但是當(dāng)您在遊戲中執(zhí)行某個(gè)操作時(shí),該值將更新為應(yīng)有的數(shù)值,因?yàn)樗谒欧魃线M(jìn)行了內(nèi)部追蹤。這就是我想要解決的問題。希望這樣說得清楚!
除了在網(wǎng)路上搜尋並最終找到這個(gè)網(wǎng)站上沒有一個(gè)真正「好」的答案之外,我還沒有嘗試過任何方法來解決這個(gè)問題,所以我決定提問。
連續(xù)的伺服器推送也不起作用。主事件循環(huán)中的任何東西,如計(jì)時(shí)器或在失去焦點(diǎn)時(shí)發(fā)生的事件,都會(huì)被瀏覽器減慢以節(jié)省資源。一些行動(dòng)瀏覽器會(huì)完全停止它。
問題的答案是改變應(yīng)用程式如何追蹤這些統(tǒng)計(jì)數(shù)據(jù)。
現(xiàn)在有些人會(huì)說要使用WebWorkers在單獨(dú)的執(zhí)行緒中運(yùn)行計(jì)時(shí)器,但這並不能解決所有問題。您仍然會(huì)遇到不同版本的問題,例如如果有人從睡眠中恢復(fù)您的網(wǎng)頁或類似情況。沒有後臺(tái)任務(wù)能夠存活下來。
您提到您還在伺服器上追蹤這些統(tǒng)計(jì)資料。這很方便,因此您應(yīng)該做的最明顯的事情是使用視窗焦點(diǎn)事件檢測標(biāo)籤何時(shí)重新獲得焦點(diǎn)。然後,您將呼叫伺服器以取得最新的統(tǒng)計(jì)資料並根據(jù)該新資料重設(shè)計(jì)時(shí)器。為了在請(qǐng)求正在進(jìn)行時(shí)防止顯示陳舊的數(shù)據(jù),您可以選擇在此期間顯示載入旋轉(zhuǎn)器或其他內(nèi)容。
修復(fù)此問題的另一種常見方法是在每次計(jì)時(shí)器增加時(shí)保留一個(gè)變量,該變量表示資料上次返回的時(shí)間戳。當(dāng)您失去焦點(diǎn)時(shí),您可以使用blur
事件偵測到,並將該最後時(shí)間戳記儲(chǔ)存在某個(gè)地方。然後當(dāng)它們重新獲得焦點(diǎn)時(shí),您可以處理focus
事件,並計(jì)算當(dāng)前時(shí)間與離開焦點(diǎn)(失去焦點(diǎn))之前記錄的最後時(shí)間之間的差異。您可以從此期間重新計(jì)算出應(yīng)該是什麼值。
但是如果您的伺服器具有此信息,只需在重新獲得焦點(diǎn)時(shí)向伺服器詢問會(huì)更不容易出錯(cuò)和簡單。