Fullscreen API 全屏顯示網頁

第一次看到應用 Fullscreen API 全屏顯示網頁,是 FaceBook 中的照片放大。做爲一個比較新的 API,目前只有 Safari、Chrome 和 FireFox 三種瀏覽器支持該特性。由於還沒有發佈正式版的標準,因此必須使用瀏覽器特定的方法,也就是應用添加前綴(webit/moz)的方法。
這個 API 不只可以使整個頁面全屏顯示,也可使頁面中的某個元素全屏顯示。它的設計初衷是爲了全屏顯示 HTML5 視頻和遊戲,以便更全面的替代 flash 功能。儘管還有不少有待完善的地方,可是做爲一個新的瀏覽器特性,在某些地方仍是可以極大地加強用戶體驗。javascript

1. 標準調用方式

要對某個元素使用全屏特效,標準的流程是:html

  1. 調用這個元素對象的 requestFullscreen() 方法;java

  2. 瀏覽器將元素全屏顯示,改變相關的屬性值,而後觸發 document 的 fullscreenchange 事件;jquery

  3. 退出全屏時有兩種方式,一種是默認的按 ESC 鍵退出,一種是調用 document 的 exitFullscreen() 方法;git

  4. 瀏覽器將元素退出全屏顯示,改變相關屬性值,再次觸發 fullscreenchange 方法。github

瀏覽器在改變全屏狀態時修改的相關屬性,是指修改當前全屏狀態有否、全屏顯示的元素對象,這些屬性都是隻讀的。web

瀏覽器觸發 fullscreenchange 事件,默認不作任何處理,內部的處理函數須要編程人員自行判斷當前全屏狀態後,進行相應處理。
對應的,規範中還添加了一個 :fullscreen 僞類,對當前全屏的元素進行樣式定義。編程

2. 封裝API

Fullscreen 目前只有兩個方法:進入全屏、退出全屏,三個屬性(所有是隻讀的):是否支持全屏、當前全屏狀態、當前全屏元素,以及一個在全屏狀態改變時觸發的事件( Using full-screen mode 中提到還有一個 fullscreenerror,可是我沒有測試出如何才能觸發這個事件 )。與 W3 草案 相比,FireFox 的實現更符合標準,而 webkit 內核瀏覽器中的方法則要自我不少。
全部的方法和屬性中,只有 requestFullscreen() 是 element 對象的方法,其餘所有是 document 對象全部的方法和屬性。api

2.1 進入全屏:element.requestFullscreen()瀏覽器

將 element 全屏顯示。webkit內核瀏覽器和Firefox表現不一樣,前者只要求element是DOM元素便可,後者則要求DOM必須是文檔流中的元素,比較嚴格,不然不能全屏顯示。
出於安全考慮,全屏狀態下默認是不容許用戶輸入的。webkit 內核瀏覽器會阻止除方向鍵、控制鍵以外的鍵盤輸入,FireFox 會在輸入時發出要求用戶退出全屏狀態的提示。前者能夠經過在方法 webkitRequestFullScreen() 中傳入參數 Element.LLOW_KEYBOARD_INPUT 容許用戶輸入,但 Safari 一旦傳入該參數,整個 Fullscreen 功能都會壞掉(這應該是 Safari 的一個bug);後者直接就能夠輸入,除了有個煩人的提示。

webkit 瀏覽器中能夠經過只讀屬性 document.webkitFullScreenKeyboardInputAllowed 查看當前是否容許全屏狀態下的輸入。

/**
 * 標準化 requestFullscreen 方法
 * @param {DOM} elem 要全屏顯示的元素(webkit下只要是DOM便可,Firefox下必須是文檔中的DOM元素)
 */
function requestFullscreen( elem ) {
    if (elem.requestFullscreen) {
        elem.requestFullscreen();
    }
    else if (elem.webkitRequestFullScreen) {
        // 對 Chrome 特殊處理,
        // 參數 Element.ALLOW_KEYBOARD_INPUT 使全屏狀態中能夠鍵盤輸入。
        if ( window.navigator.userAgent.toUpperCase().indexOf( 'CHROME' ) >= 0 ) {
            elem.webkitRequestFullScreen( Element.ALLOW_KEYBOARD_INPUT );
        }
        // Safari 瀏覽器中,若是方法內有參數,則 Fullscreen 功能不可用。
        else {
            elem.webkitRequestFullScreen();
        }
    }
    else if (elem.mozRequestFullScreen) {
        elem.mozRequestFullScreen();
    }
}

2.2 退出全屏:document.exitFullscreen()

從全屏狀態中退出。目前實現的方法都是 cancelFullScreen() ,而不是標準的 exitFullscreen()。

/**
 * 標準化 exitFullscreen 方法
 */
function exitFullscreen() {
    if (document.exitFullscreen) {
        document.exitFullscreen();
    }
    else if (document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen();
    }
    else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    }
}

2.3 瀏覽器是否支持全屏:document.fullscreenEnabled

經過該屬性的boolean值判斷瀏覽器是支持 Fullscreen 功能。
webkit 內核的瀏覽器目前尚未該屬性,所以只能經過能力斷定來判斷是否支持全屏顯示功能。Firefox 已經有了對應的屬性定義。

/* 標準化 fullscreenEnabled 屬性 (只讀) */
document.fullscreenEnabled = ( function() {
        var doc = document.documentElement;
        return ( 'requestFullscreen' in doc ) ||
               ( 'webkitRequestFullScreen' in doc ) ||
               // 對Firefox除了能力判斷,還加上了屬性判斷
               ( 'mozRequestFullScreen' in doc && document.mozFullScreenEnabled ) ||
               false;
    } )();

2.4 :document.fullscreenElement

當前全屏顯示的DOM元素。

/**
 * 標準化 fullscreenElement 屬性 (只讀)
 * 以同名方法替代
 */
function fullscreenElement() {
    return document.fullscreenElement ||
           document.webkitCurrentFullScreenElement ||
           document.mozFullScreenElement ||
           null;
}

2.5 當前全屏狀態:document.fullscreen

該屬性並未在2012/6/3的 w3草案 中出現,但在Using full-screen mode 一文中介紹了該屬性。其值爲 boolean 類型,判斷當前文檔的全屏狀態。

若是最終去掉這個判斷全屏狀態的屬性,咱們仍然能夠經過 document.fullscreenElement 的值是否爲 null 來判斷全屏與否

/**
 * 標準化 fullscreen 屬性 (只讀)
 * 以同名方法替代
 */
function fullscreen() {
    return document.fullscreen ||
           document.webkitIsFullScreen ||
           document.mozFullScreen ||
           false;
}

2.6 全屏狀態改變事件:fullscreenchange

該事件要綁定在 document 上,該事件僅在全屏狀態改變時觸發,默認沒有任何動做。

/* 綁定 document 的 fullscreenchange 事件 */
document.addEventListener(
    'fullscreenchange', // webkitfullscreenchange/mozfullscreenchange
    function( evt ){
        //todo 全屏狀態改變時的時間處理。
        //默認不會有任何處理,須要本身判斷當前屏幕全屏與否,作出相應處理。
    },
    false
);

/* 若是使用 jQuery : */
$( document ).bind(
    'fullscreenchange webkitfullscreenchange mozfullscreenchange',
    function(){
        //todo code
    }
);

3. 全屏樣式設置

標準中,經過 :fullscreen 僞類對全屏的元素進行樣式定義。

默認狀況下,瀏覽器只會簡單地將元素設置爲全屏顯示。若是該元素全屏後,高度比屏幕還高,超出的部分將會被隱藏。爲了將超出部分能夠滾動顯示,最頂層全屏顯示的元素要特別設置:

position : fixed;
top      : 0;
left     : 0;
width    : 100%;
height   : 100%;
overflow : auto;

通常狀況下,要全屏顯示的元素是不能像上面這樣設置的。那麼咱們能夠變通下,設置一個 <div/>,包圍要全屏的元素,而後將這個 <div/> 設置爲全屏,上面的樣式定義就能夠定義在這個 <div/> 上,相應的,:fullscreen 將會做用在這個 <div/> 上。這樣,過長的元素就能夠在這個包圍層內滾動顯示。

4. 特別注意

  • 目前 FireFox 十、Safari 5.1+、Chrome 15+ 支持全屏

  • 可使任意元素全屏顯示,不僅是整個頁面

  • 全屏只能從事件觸發(用戶操做),而不能用代碼直接觸發

  • 全屏狀態下,webkit 內核瀏覽器默認會阻止除方向鍵、控制鍵以外的鍵盤輸入,FireFox 會在輸入時發出退出全屏狀態提示。處理方法在 封裝API 部分有說明。

下面是實際中遇到的須要注意的地方:

  • 全屏狀態切換須要時間。執行 requestFullscreen() 後,並不會當即進入全屏狀態,對應的全屏屬性不會當即更改,而是有一個執行時間。所以,只能在 fullscreenchange 事件觸發後才表明進入了全屏狀態。可是在 fullscreenchange 事件中調用 $(window).width() 並不總能獲得全屏的尺寸,這個現象很奇怪。若是須要屏幕尺寸,能夠經過 window.screen.width 來得到。

  • 涉及修改DOM文檔須注意代碼位置。當用 <div/> 包圍要全屏顯示的元素時,這段 javascript 代碼不該該在要全屏顯示的元素內部,不然這段代碼會被執行兩遍,並且第二遍不會在斷點中被監視到,緣由將在後文詳細描述。

  • ESC 鍵不一樣系統功能不一樣。目前發現點擊 ESC 退出全屏時,mac系統不會再額外觸發鍵盤事件,可是win7系統下出發 fullscreenchange 事件後還會立馬觸發鍵盤事件,所以若是還有不但願被觸發的鍵盤事件,能夠設置一個監視變量,在很短期後再修改監視變量,以錯過這個立馬執行的時間。

5. 未涉及功能

  • iframe 元素的 allowfullscreen 屬性

  • ::backdrop 僞類

  • 具體其餘細節能夠參考 W3 草案

6. 結語

Fullscreen API 畢竟目前只是草案,還沒有造成正式的標準,何況各個瀏覽器的實現狀況也不徹底相同,甚至細節上的實現差異更可能引起預想不到的問題。但做爲漸進加強方式使用的新功能,可以極大的加強用戶體驗。仍要根據規範的完善,不斷改進咱們的代碼。
詳細代碼能夠參考:https://github.com/calefy/calefy.github.com/blob/master/js/Fullscreen.js

參考

  1. W3 草案 2012/6/3版

  2. Using full-screen mode

  3. Enhance Your Website with the FullScreen API

  4. Using the Fullscreen API in web browsers

  5. 代碼參考 jQuery Fullscreen 插件

本文參考

相關文章
相關標籤/搜索