1. 程式人生 > >讓你的頁面瞬間全屏

讓你的頁面瞬間全屏

@update 文章下方有更新,提到了更多全屏的知識以及錯誤的矯正。

頁面全屏是一個體驗非常棒的功能,他可以讓你的視覺焦點聚集在你想關注的元素塊上。很多瀏覽器都支援全屏,按下 F11,哦了! 頁面全屏了~ 但是本文要說的並不是這種全屏。當頁面中有個小 DEMO 或者小遊戲要展示的時候,使用者期望,這個 DEMO 或者遊戲可以在全屏下展示,本文就教你如何來展示。

如果你是非 IE 瀏覽器進入的該頁面,你可能已經看到了頁面上發生了一點小變化,多個東西:

沒錯,多了個“進入全屏”的按鈕,這就是本文要介紹的內容!

一、全屏策略

1. 原理

一些瀏覽器提供了元素全屏的介面,這些介面的呼叫特別簡單:

// 進入全屏
element.requestFullScreen(); 
// 退出全屏
document.exitFullscreen(); 

這是 w3c 規範統一的介面,但是瀏覽器總是那麼調皮,內部實現的時候會加上自己廠商的字首,如:

// 小狐
element.mozRequestFullScreen();  
// Chrome
document.webkitCancelFullScreen();

這裡有兩點需要引起注意,W3C 中的退出全屏是 exitFullscreen,而小狐跟 Chrome 使用的是 cancelFullScreen,這裡在作判斷的時候不要弄錯了;再一點就是當我們退出全屏的時候,並不是使用 element 作為退出的物件了,而是使用 document。

2. 相容處理

原理是很簡單,但是針對瀏覽器的相容性寫起來還是挺麻煩的,幸好 Chrome 換用 blink核心 之後沒有繼續加上一個 -blink-,否則開發者心裡會有無數個草泥馬奔騰的!

對於進入全屏:

function launchFullScreen(element) {  
   if (element.requestFullscreen) {
      element.requestFullscreen();
    } else if (element.msRequestFullscreen) {
      element.msRequestFullscreen();
    } 
else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if (element.webkitRequestFullscreen) { element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); } }

對於退出全屏:

function cancelFullScreen() {  
   if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    }
}  

3. 瀏覽器相容性

IE 使用者就甭看了,剛測試,IE11 不相容(需要加字首 ms)。對於瀏覽器的相容情況,請戳這裡。目前 Firefox 相容,不過有點離譜。他會彈出一個讓你全屏的提示,此時確實是全屏的,但當你點選提示中的“允許”時,螢幕又退出了全屏,真是讓人匪夷所思。我測試的版本(27.0.1)有這個問題,當然,這是瀏覽器本身的問題,不用糾結。

Chrome 對於新特性的支援永遠是站在前排,不得不佩服 google 開發工程師的牛掰!

二、3 個 bug

1. window 失去焦點

當全屏一個元素塊的時候,原始狀態該元素塊可能沒有 padding 或者 margin 值,為了讓他顯示的稍微養眼一些,我們可能會給他主動加上 padding 值,然後在退出全屏的時候在拿到設定的值。但此時,一個 bug 出現鳥,當我們點選全屏頁面中的 a 標籤,或者觸發了某個 window.open 之後,瀏覽器會失去焦點,跳到新開的頁面中,而全屏的頁面會退出全屏,搞笑的是我們開始設定的 padding 值他不給我們去掉,這個是令人十分神傷的,不過沒關係,有 bug 咱們就打補丁!

window.onblur = function(){
    cancelFullsreen();
    changeThePadding();
};

有人會想到,我們在點選 a 連結的時候先 changeThePadding(),再讓 a 標籤跳走,這種方式是不合理的,因為除了 a 連結會讓頁面失去焦點之外還有其他的可能(如 window.open)。

@update 因為 bug 3 的存在,這裡不能這樣改,需要利用瀏覽器的全屏探測:

$(document).on('webkitfullscreenchange mozfullscreenchange msfullscreenchange fullscreenchange', function(){
    if (!document.fullscreenElement &&    // alternative standard method
    !document.mozFullScreenElement && 
    !document.webkitFullscreenElement && 
    !document.msFullscreenElement ) {
        // 在這裡處理 bug
changeThePadding();
} });

2. 一個貌似可以重現的 bug

所謂的可以重現就是,把程式碼邏輯抽離出來,寫個 demo 還能看到 bug。反正我試過好幾次,這個 bug 都出現了,懶得寫一個 DEMO 重現他。他出現的位置是:我的滾動條是自己設定的樣式,當全屏之後,滾動條本應該在頁面的最右側,但是我測試的時候他偶爾會離最右側有十幾個畫素,我也不知道為什麼。但是當我開啟 DevTools 的時候,這十幾個畫素又奇妙的被縫合了~

後來一想,管你呢,這肯定是 google 的工程師沒有留意到的位置!既然開打 DevTools 可以修復,那就說明觸發 window.resize 也能解決這個問題,好吧,那就這樣試試吧:

newCancelFullscreen = function(){
    cancelFullscreen();
    window.onresize();
};

果然有效,bug 搞定!

3. 全屏之後,部分瀏覽器會在該頁面失去焦點

這就相當於,全屏之後,觸發了 window.blur();

三、小結

除了上面提到的兩個 bug,還有一個值得注意的是,如果你全屏的那個元素塊很高但卻沒有設定

element { overflow:auto; }

之類的東西,你會發現滾爛你的滑鼠也滾不出那塊區域。

本文介紹瞭如何使用 javascript 將頁面中的某個元素調至全屏,並指出了再使用過程中的兩個 bug,希望引起注意!

四、參考資料

@update 2014/03/01 12:00

1. Trident 核心的 IE 瀏覽器是支援的,可以用 element.msRequestFullscreen(),退出用 msExitFullscreen()

2. 對於全屏的元素可以使用偽元素給他加樣式:

:-webkit-full-screen #myvideo {
  width: 100%;
  height: 100%;
}

3. 瀏覽器提供的兩個方便開發的東西:

fullscreenElement:如果這個屬性為空,則瀏覽器處於非全屏狀態,否則就是處於全屏。

fullscreenEnabled:這個屬性告訴你瀏覽器 document 是否可以全屏。

4. 也可以使用 keydown 來控制全屏,如:

document.addEventListener("keydown", function(e) {
  if (e.keyCode == 13) {
    toggleFullScreen();
  }
}, false);

對於 toggleFullScreen 函式:

function toggleFullScreen() {
  if (!document.fullscreenElement &&    // alternative standard method
      !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) {  // current working methods
    if (document.documentElement.requestFullscreen) {
      document.documentElement.requestFullscreen();
    } else if (document.documentElement.msRequestFullscreen) {
      document.documentElement.msRequestFullscreen();
    } else if (document.documentElement.mozRequestFullScreen) {
      document.documentElement.mozRequestFullScreen();
    } else if (document.documentElement.webkitRequestFullscreen) {
      document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
    }
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    }
  }
}
Toggle FullScreen

5. 全屏事件

看到這句程式碼你可能就懂了:

$(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange',fn);

當全屏狀態改變時會觸發上面的 fullscreenchange 事件,所以 #15 p2227 給我提出的問題就可以得到解決了。

文章可能還存在錯誤的地方,還請多多斧正!