通過HTML5 Visibility API檢測頁面活動狀態

edithfang發表於2014-09-17
幾年前,我們瀏覽網頁的時候是沒有選項卡瀏覽模式的,每一個網頁都會是一個瀏覽器視窗,如果我沒有記錯,Win7之前我們都是這樣瀏覽網頁的。作為一個程式設計師,我們經常會同時開啟10-15個網頁,多的時候超過20個也不足為奇。
為什麼要使用這個API?
早期我們沒有辦法確定哪些選項卡是活動狀態的,但是現在透過HTML Visibility API,我們可以檢測訪客是否正在瀏覽我們的介面。

在這個教程中我們會介紹如何使用HTML5 Visibility API,同時我們也為你準備了一個簡單的demo來檢視頁面的狀態。在demo中,我們將會根據頁面的狀態來修改檔案的標題。
檢視頁面的狀態
隨著這個API的出現,我們又迎來了兩個新的document屬性,他們分別是document.visibilityState和document.hidden。
document.visibilityState 有四個可選值:
  • hidden: 頁面在任何螢幕上都沒有被瀏覽。
  • prerender: 頁面在選項卡中,但訪客現在沒有在這個選項卡上。
  • visible: 訪客正在瀏覽。
  • unloaded: 頁面已經被載入過了,現在跳轉在其它介面上了。
document.hidden是一個布林型別的屬性。
現在我們可以根據頁面狀態來控制我們的網站了。
現在我們可以馬上知道我們頁面的availability屬性了。但是首先我們要做的是監聽這個事件,這樣一來我們就可以做出相應的事情。我已經寫好了一個簡單的監聽事件:

        
        
                
                
                        
                        
                                document.addEventListener('visibilitychange', function(event) {
                        

                        
                                 if (!document.hidden) {
                        

                        
                                 // The page is visible.
                        

                        
                                 } else {
                        

                        
                                 // The page is hidden. 
                        

                        
                                 }
                        

                        
                                });
                        

                

        

        
                
                
                        
                        
                                
                                
                                        
                                

                                
                                        
                                

                        

                

        


 這段程式碼非常簡單,只是檢測頁面的狀態。但是你必須清楚這兩個屬性和方法必須有固定的字首。因為這個事件和屬性有部分瀏覽器中是基於字首的。現在我們來看一看上面這些程式碼的跨瀏覽器寫法的前提:
        
                
                
                        
                        
                                
                                
                                        // Get Browser-Specifc Prefix
                                

                                
                                        function getBrowserPrefix() {
                                

                                
                                         
                                

                                
                                         // Check for the unprefixed property.
                                

                                
                                         if ('hidden' in document) {
                                

                                
                                         return null;
                                

                                
                                         }
                                

                                
                                         
                                

                                
                                         // All the possible prefixes.
                                

                                
                                         var browserPrefixes = ['moz', 'ms', 'o', 'webkit'];
                                

                                
                                         
                                

                                
                                         for (var i = 0; i < browserPrefixes.length; i++) {
                                

                                
                                         var prefix = browserPrefixes[i] + 'Hidden';
                                

                                
                                         if (prefix in document) {
                                

                                
                                         return browserPrefixes[i];
                                

                                
                                         }
                                

                                
                                         }
                                

                                
                                         
                                

                                
                                         // The API is not supported in browser.
                                

                                
                                         return null;
                                

                                
                                        }
                                

                                
                                         
                                

                                
                                        // Get Browser Specific Hidden Property
                                

                                
                                        function hiddenProperty(prefix) {
                                

                                
                                         if (prefix) {
                                

                                
                                         return prefix + 'Hidden';
                                

                                
                                         } else {
                                

                                
                                         return 'hidden';
                                

                                
                                         }
                                

                                
                                        }
                                

                                
                                         
                                

                                
                                        // Get Browser Specific Visibility State
                                

                                
                                        function visibilityState(prefix) {
                                

                                
                                         if (prefix) {
                                

                                
                                         return prefix + 'VisibilityState';
                                

                                
                                         } else {
                                

                                
                                         return 'visibilityState';
                                

                                
                                         }
                                

                                
                                        }
                                

                                
                                         
                                

                                
                                        // Get Browser Specific Event
                                

                                
                                        function visibilityEvent(prefix) {
                                

                                
                                         if (prefix) {
                                

                                
                                         return prefix + 'visibilitychange';
                                

                                
                                         } else {
                                

                                
                                         return 'visibilitychange';
                                

                                
                                         }
                                

                                
                                        }
                                

                        

                

                
                        
                        
                                
                                
                                        
                                        
                                                
                                        

                                        
                                                
                                        

                                

                        

                

        
 得到這些字首之後,我們可以請求所有瀏覽器的字首屬性和事件,現在我們要做的是改變之前的程式碼:
        
                
                
                        
                        
                                
                                
                                        // Get Browser Prefix
                                

                                
                                        var prefix = getBrowserPrefix();
                                

                                
                                        var hidden = hiddenProperty(prefix);
                                

                                
                                        var visibilityState = visibilityState(prefix);
                                

                                
                                        var visibilityEvent = visibilityEvent(prefix);
                                

                                
                                         
                                

                                
                                        document.addEventListener(visibilityEvent, function(event) {
                                

                                
                                         if (!document[hidden]) {
                                

                                
                                         // The page is visible.
                                

                                
                                         } else {
                                

                                
                                         // The page is hidden. 
                                

                                
                                         }
                                

                                
                                        });
                                

                        

                

                
                        
                        
                                
                                
                                        
                                        
                                                
                                        

                                        
                                                
                                        

                                

                        

                

        

我們可以在哪裡使用這個API?
下面我舉了幾個我認為這個API比較適用的地方:
  • 當頁面屬性是hidden的時候,我們可以禁止呼叫RSS API。
  • 當頁面狀態是隱藏的時候,我們可以禁止運動的物體繼續運動。
  • 我們可以在頁面狀態是隱藏的時候在標題上顯示一些通知。
我只是大概舉了幾個例子,有更好主意的可以在評論中告訴大家。下面我們使用這個API寫一些例項。
例子
  • Demo 1: 這個例子在頁面狀態是隱藏的時候改變標題欄內容。檢視 Demo
  • Demo 2: 這個例子演示在頁面狀態是隱藏的時候,計數量停止計數,可見後繼續計數。
這Demo 2中,我們會詳細向你介紹它的實現原理:
HTML程式碼

        
        
                
                
                        
                        
                                <!-- This element will show updated count -->
                        

                        
                                <h1 id="valueContainer">0</h1>
                        

                

        

        
                
                
                        
                        
                                
                                
                                        
                                

                                
                                        
                                

                        

                

        


 
JavaScript程式碼

                
                        
                        
                                
                                
                                        
                                        
                                                <script type="text/javascript">
                                        

                                        
                                                 
                                        

                                        
                                                 // Get Browser Prefix
                                        

                                        
                                                 var prefix = getBrowserPrefix();
                                        

                                        
                                                 var hidden = hiddenProperty(prefix);
                                        

                                        
                                                 var visibilityState = visibilityState(prefix);
                                        

                                        
                                                 var visibilityEvent = visibilityEvent(prefix);
                                        

                                        
                                                 
                                        

                                        
                                                 var timer = null;
                                        

                                        
                                                 
                                        

                                        
                                                 function increaseVal() {
                                        

                                        
                                                 var newVal = parseInt($('#valueContainer').text()) + parseInt(1);
					

					
						 $('#valueContainer').text(newVal);
					

					
						 document.title = newVal + ': Running'; 
					

					
						 
					

					
						 timer = setTimeout(function() {
					

					
						 increaseVal();
					

					
						 }, 1);
					

					
						 }
					

					
						 
					

					
						 // Visibility Change 
					

					
						 document.addEventListener(visibilityEvent, function(event) {
					

					
						 if (document[hidden]) {
					

					
						 clearTimeout(timer);
					

					
						 var val = parseInt($('#valueContainer').text());
					

					
						 document.title = val + ': Pause'; 
					

					
						 } else {
					

					
						 increaseVal(); 
					

					
						 }
					

					
						 });
					

					
						 
					

					
						 increaseVal();
					

					
						 
					

					
						</script>
					

				

			

			
				
				
					
					
						
						
							
						

						
							
						

					

				

			

		


檢視Demo
瀏覽器支援
如果你想讓所有的瀏覽器都支援這個API,我建議你看一下這篇文章。如果想檢測當前瀏覽器是否執行這個API,可以看一看Detect Support for Various HTML5 Features.。到目前為止,我們已經可以很好的在各個瀏覽器中使用這個功能。
結論
我不得不說這是一個非常好的API,而且它只有兩個屬性和一個事件。透過這個API,我們可以簡單地完善我們的網站,透過頁面當前的狀態來做一些改變,這樣非常酷不是麼,就像你只顧著打程式碼冷落了你的女朋友,她馬上就會教訓你一樣。
評論(2)

相關文章