34

Not sure if the following code snip will work embedded on SO, as it didn't work when pasting it, however it does work stand-alone.

The problem, is I want this to be a toggle; not just to enter fullscreen mode, but to exit it if the user is in fullscreen. It goes into fullscreen mode perfectly, and executes the exit fullscreen code (as the alert() box is shown which runs after the exit code but inside the exit code condition only) yet it does nothing.

I have read up on this here, and here which seems that I am doing everything correct, but something is missing. Could you please assist in figuring out how to make this procedural code work.

function fullscreen() {
 var isInFullScreen = (document.fullscreenElement && document.fullscreenElement !== null) ||
  (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
  (document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
  (document.msFullscreenElement && document.msFullscreenElement !== null);

 var docElm = document.documentElement;
 if (!isInFullScreen) {
  if (docElm.requestFullscreen) {
   docElm.requestFullscreen();
  } else if (docElm.mozRequestFullScreen) {
   docElm.mozRequestFullScreen();
  } else if (docElm.webkitRequestFullScreen) {
   docElm.webkitRequestFullScreen();
  } else if (docElm.msRequestFullscreen) {
   docElm.msRequestFullscreen();
  }
 } else {
  if (docElm.exitFullscreen) {
   docElm.exitFullscreen();
  } else if (docElm.webkitExitFullscreen) {
   docElm.webkitExitFullscreen();
  } else if (docElm.mozCancelFullScreen) {
   docElm.mozCancelFullScreen();
  } else if (docElm.msExitFullscreen) {
   docElm.msExitFullscreen();
  }
  alert('exit fullscreen, doesnt work');
 }
}
<a onclick="fullscreen()" href="javascript:void(0);">Toggle FullScreen</a>

I also tried adding parent.exitfs() where the alert code is, according to this questions accepted answer and still has no impact

Community
  • 1
  • 1
Kraang Prime
  • 9,981
  • 10
  • 58
  • 124

6 Answers6

73

Figured it out.

Apparently, to enter full screen, you need to use the Element, however to exit fullscreen, you use document.

Here is the complete javascript function to toggle fullscreen that works !!!

function fullscreen() {
    var isInFullScreen = (document.fullscreenElement && document.fullscreenElement !== null) ||
        (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
        (document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
        (document.msFullscreenElement && document.msFullscreenElement !== null);

    var docElm = document.documentElement;
    if (!isInFullScreen) {
        if (docElm.requestFullscreen) {
            docElm.requestFullscreen();
        } else if (docElm.mozRequestFullScreen) {
            docElm.mozRequestFullScreen();
        } else if (docElm.webkitRequestFullScreen) {
            docElm.webkitRequestFullScreen();
        } else if (docElm.msRequestFullscreen) {
            docElm.msRequestFullscreen();
        }
    } else {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        } else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
        }
    }
}

And a simple case on how to use it :

<button onclick="fullscreen()">Toggle FullScreen</button>

You need to make sure that this is a short method called when the user does an action on the page. From what the documentation says, is this is a feature that requires a higher access mode, and thus you can not (at this time) automatically force fullscreen on things like when the page has loaded, or async events (unless they are events from a users action like Click), etc.

Garbee
  • 10,581
  • 5
  • 38
  • 41
Kraang Prime
  • 9,981
  • 10
  • 58
  • 124
  • 1
    Apparently, I'm getting this error ` document.exitFullscreen is not a function`. Any ideas? – Nigel Feb 07 '18 at 11:06
  • @Nigel in general this means that your browser doesn't support the Fullscreen API. That's why you use all the if blocks. And also check for any typos. – Andreas Linnert May 23 '18 at 14:42
4

Solutions provided here are incredibly long. You can use these few lines to show or cancel fullscreen.

Show full screen:

  /* You can use any HTML element through JS selector functions
   * eg. document.querySelector(".example");
  */
const element = document; 
const requestFullScreen = element.requestFullscreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
requestFullScreen.call(element);

Cancel full screen:

// As correctly mentioned in the accepted answer, exitFullscreen only works on document
const cancellFullScreen = document.exitFullscreen || document.mozCancelFullScreen || document.webkitExitFullscreen || document.msExitFullscreen;
cancellFullScreen.call(document);

Chrome will display an error: Uncaught (in promise) TypeError: Document not active if exitFullscreen is called while not in fullscreen mode.

Kalimah
  • 11,217
  • 11
  • 43
  • 80
1

A more generalized helper (derived from the accepted answer)...

Get Mode

The function can be invoked without arguments to find out if the browser is currently in Fullscreen Mode. It returns true if so and false otherwise.

Set Mode

The function can be invoked with a bool to explicitly set the current mode, where true ensures the browser is in Fullscreen Mode, and false ensures it isn't.

Toggle Mode

The function can be invoked with null as the only argument to implicitly set the mode to the opposite of whatever mode it is currently in.


let fullscreen = function() {

    let enter = function() {
        let body = document.body;
        if (body.requestFullscreen) body.requestFullscreen();
        else if (body.webkitRequestFullscreen) body.webkitRequestFullscreen();
        else if (body.mozRequestFullScreen) body.mozRequestFullScreen();
        else if (body.msRequestFullscreen) body.msRequestFullscreen();
    };

    let exit = function() {
        if (document.exitFullscreen) document.exitFullscreen();
        else if (document.webkitExitFullscreen) document.webkitExitFullscreen();
        else if (document.mozCancelFullScreen) document.mozCancelFullScreen();
        else if (document.msExitFullscreen) document.msExitFullscreen();
    };

    let attemptToGetState = element => element && element !== null;

    return function(action=undefined) {
        if (action === true) enter();
        else if (action === false) exit();
        else {
            let currentlyFullscreen = (
                attemptToGetState(document.fullscreenElement)       ||
                attemptToGetState(document.webkitFullscreenElement) ||
                attemptToGetState(document.mozFullScreenElement)    ||
                attemptToGetState(document.msFullscreenElement)
            );
            if (action === undefined) return !! currentlyFullscreen;
            else currentlyFullscreen ? exit() : enter();
        }
    };

}();
Carl Smith
  • 3,025
  • 24
  • 36
  • `exit` is a reserved word. not sure you can use that as a variable without errors. – Kraang Prime Jul 26 '18 at 05:20
  • 1
    I stand corrected. Just feels strange using a word that is normally reserved. Good closure. The only other issues I noticed is I recall getting an error when trying to enter fullscreen if already in fullscreen, and vice-versa - and the last issue is how are you handling any element being passed as the fullscreen object. Sometimes fullscreen view is not the entire page ( body or html ), but more a section of it ( a div container ). – Kraang Prime Jul 26 '18 at 06:02
  • 1
    On the errors, it assumes you know whether you're in fullscreen mode or not if you're specifying which mode to switch to (you can find out by calling it with no args). You can also call it with a `null` arg to toggle from one mode to the other regardless of the current state. I hadn't thought about needing to take an element as a parameter (not just assuming it should apply to the body). That's a good point. Cheers. – Carl Smith Nov 20 '18 at 02:08
1

Krang's answer was great, Carl's idea to modularize was too. But I couldn't easily understand his code. So here's my version in TypeScript:

function isInFullScreen() {
  const document: any = window.document;
  return (document.fullscreenElement && document.fullscreenElement !== null) ||
        (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
        (document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
        (document.msFullscreenElement && document.msFullscreenElement !== null);
}

function requestFullScreen(elem: any) {
  if (elem.requestFullscreen) {
    elem.requestFullscreen();
  } else if (elem.mozRequestFullScreen) {
    elem.mozRequestFullScreen();
  } else if (elem.webkitRequestFullScreen) {
    elem.webkitRequestFullScreen();
  } else if (elem.msRequestFullscreen) {
    elem.msRequestFullscreen();
  } else {
    console.warn("Did not find a requestFullScreen method on this element", elem);
  }
}

function exitFullScreen() {
  const document: any = window.document;
  if (document.exitFullscreen) {
    document.exitFullscreen();
  } else if (document.webkitExitFullscreen) {
    document.webkitExitFullscreen();
  } else if (document.mozCancelFullScreen) {
    document.mozCancelFullScreen();
  } else if (document.msExitFullscreen) {
    document.msExitFullscreen();
  }
}

function toggleFullScreen(elem: any) {
  // based on https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
  if (isInFullScreen()) {
    exitFullScreen();
  } else {
    requestFullScreen(elem || document.body);
  }
}
ubershmekel
  • 11,864
  • 10
  • 72
  • 89
  • 1
    I like your answer but why typescript ? This is a real example where we see why typescript is useless in this context. What's the point to add type : any ? It is like js in the end :D – Leths May 23 '20 at 08:24
  • You're right. I was working in typescript, so I copy pasted the final result that I tested. I could have added better types instead of those `any` and I could have just provided a `js` solution, but it was more work for me that I didn't need at the time. – ubershmekel May 24 '20 at 21:30
1

As of January 2020, in a slightly different scenario where I wanted to toggle fullscreen mode on a video tag, the accepted solution did not work for me on Safari & iOS Safari. On these platforms, the working APIs are webkitEnterFullScreen and webkitExitFullscreen and both should be called on the HTML Element. Therefore in my case the complete code with platform-specific fallbacks was :

// Request full screen
const requestVideoFullScreen = videoElt.requestFullscreen || videoElt.webkitEnterFullScreen || videoElt.mozRequestFullScreen || videoElt.msRequestFullScreen;
if (requestVideoFullScreen) {
    requestVideoFullScreen.call(videoElt);
}
...
// Exit full screen
if (videoElt.webkitExitFullscreen) {
    videoElt.webkitExitFullscreen();
} else {
    const cancelVideoFullScreen = document.exitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen;
    if (cancelVideoFullScreen) {
        cancelVideoFullScreen.call(document);
    }
}

Moreover, to use the fullscreen-related events I had to listen to the "webkitbeginfullscreen" and "webkitendfullscreen" events on iOS Safari, and "webkitfullscreenchange" on macOS Safari, as mentioned in this other SO answer.

jean-baptiste
  • 674
  • 7
  • 18
  • In the accepted solution, you place your element object where it says `var docElm = document.documentElement;` - for example `document.videoElt` . If you notice the code above calls the exit/enter fullscreen on the object specified on that line. – Kraang Prime Jan 27 '20 at 17:26
  • Sorry, I just realized that my use case is slightly different than your original post, as I just wanted to toggle a video tag in fullscreen mode, not the entire document (and in that case the webkitRequestFullscreen API doesnt work). I just edited my answer to clarify this. – jean-baptiste Jan 28 '20 at 09:13
  • Yes, any element can be set as the fullscreen element, but you need to call the 'exit' fullscreen methods off document base. Sorry it has been ages since I solved this, my block of code should have you covered for that as long as you specify the element. You use of .call() is a nice touch. – Kraang Prime Jan 28 '20 at 13:51
0

replace docElem by document in the following section, and it will work

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