2017-04-05 22 views
2

我正在使用elm中的端口來訪問瀏覽器的全屏API。在Chrome中一切正常,但在Firefox中不起作用。我得到的錯誤是:Request for full-screen was denied because Element.mozRequestFullScreen() was not called from inside a short running user-generated event handler. 但是,我認爲我理解了錯誤消息,因爲我希望它能夠工作,因爲我通過單擊按鈕訪問全屏API。中間只有一個榆樹港。有沒有人解決過這個問題?在elm中使用端口的全屏API在Firefox中不起作用

這是我的榆木代碼:

port module Main exposing (..) 

import Html exposing (Html, button, div, text) 
import Html.Events exposing (onClick) 
import Html.Attributes exposing (class) 


main = 
    Html.program { init = init, view = view, update = update, subscriptions = subscriptions } 



-- Model 


type alias Model = 
    { fullscreen : Bool } 


init : (Model, Cmd Msg) 
init = 
    ({ fullscreen = False } 
    , Cmd.none 
    ) 



-- Ports 


port activateFullscreen : String -> Cmd msg 


port deactivateFullscreen : String -> Cmd msg 


subscriptions : Model -> Sub Msg 
subscriptions model = 
    Sub.none 


type Msg 
    = FullscreenMode Bool 



-- Update 


update : Msg -> Model -> (Model, Cmd Msg) 
update msg model = 
    case msg of 
     FullscreenMode on -> 
      let 
       m = 
        { model | fullscreen = on } 
      in 
       if on then 
        (m, activateFullscreen "") 
       else 
        (m, deactivateFullscreen "") 



-- views 


fullScreenButton : Model -> Html Msg 
fullScreenButton model = 
    case model.fullscreen of 
     False -> 
      button [ onClick (FullscreenMode True) ] 
       [ text "fullscreen on" ] 

     True -> 
      button [ onClick (FullscreenMode False) ] 
       [ text "fullscreen off" ] 


view : Model -> Html Msg 
view model = 
    div [ class "app" ] [ fullScreenButton model ] 

和我的html代碼:

<!doctype html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> 
    <title>Fullscreen Test</title> 
    </head> 
    <body> 
    <div id="main"></div> 
    <script src="main.js"></script> 
    <script> 
     (function() { 
     window.onload = function() { 
      var node = document.getElementById('main'); 
      var app = Elm.Main.embed(node); 
      app.ports.activateFullscreen.subscribe(function() { 
      var element = document.querySelector('.app'); 
      if (element.requestFullscreen) { 
       element.requestFullscreen(); 
      } else if (element.webkitRequestFullscreen) { 
       element.webkitRequestFullscreen(); 
      } else if (element.mozRequestFullScreen) { 
       element.mozRequestFullScreen(); 
      } else if (element.msRequestFullscreen) { 
       element.msRequestFullscreen(); 
      } 
      }); 
      app.ports.deactivateFullscreen.subscribe(function() { 
      if (document.exitFullscreen) { 
       document.exitFullscreen(); 
      } else if (document.webkitExitFullscreen) { 
       document.webkitExitFullscreen(); 
      } else if (document.mozCancelFullScreen) { 
       document.mozCancelFullScreen(); 
      } else if (document.msExitFullscreen) { 
       document.msExitFullscreen(); 
      } 
      }); 
     }; 
     }()); 
    </script> 
    </body> 
</html> 
+0

大概火狐這樣做是爲了防止網站隨意劫持您的屏幕。我很想知道Chrome和IE是否做了類似的事情,但對構成「短時間運行的用戶生成的事件處理程序」的內容有不同的看法。正如你所提到的,這最終是由一個按鈕點擊觸發的,但由於中間有一堆Elm生成的代碼,所以會有一定程度的間接性。這可能只是Firefox不認爲它是「短跑」。 –

+1

在http://stackoverflow.com/a/43297759/2688中有一個解決方法,它使用'window.open',這可能會起作用(只需使用直接JavaScript的字符串'onClick'屬性) – bdukes

回答

0

如上bdukes「的評論指出,有一種變通方法這個問題。 我們可以使用我們放在全局窗口對象上的函數,而不是使用端口進行全屏處理。 的按鈕產生的榆樹代碼將是這樣的:

button [ onClick (FullscreenMode True), attribute "onClick" "window.enterFullScreen()" ] 
    [ text "fullscreen on" ] 

我仍然會保持榆樹的onClick有更新的內部狀態。

在JavaScript中,我們可以再定義enterFullScreen功能,並有處理我們的邏輯:

window.enterFullScreen = function() { 
    var element = document.querySelector('.app'); 
    if (element.requestFullscreen) { 
     element.requestFullscreen(); 
    } else if (element.webkitRequestFullscreen) { 
     element.webkitRequestFullscreen(); 
    } else if (element.mozRequestFullScreen) { 
     element.mozRequestFullScreen(); 
    } else if (element.msRequestFullscreen) { 
     element.msRequestFullscreen(); 
    } 
};