How to Use the Fullscreen API in JavaScript (and Keep the Screen Awake with the Wake Lock API) — Opportunihub
Course Remote

How to Use the Fullscreen API in JavaScript (and Keep the Screen Awake with the Wake Lock API)

Alex Oliinyk · Remote

At a glance

Type
Course
Organisation
Alex Oliinyk
Location
Remote
Work mode
Remote
Deadline
Rolling / not stated
Posted
29 Sep 2026

About this course

<p>Sooner or later, most front-end developers hit the same request: <em>"Can this take up the whole screen?"</em></p> <p>A slide deck, a video player, kiosk dashboard, game, drawing canvas, or timer on a classroom projector all feel half-finished while the browser's tabs and address bar are still hanging around the edges.</p> <p>The good news is that the browser has a built-in answer: the <strong>Fullscreen API</strong>. The less good news is that it comes with a handful of quirks that will bite you the first time you ship it: user gestures, Safari prefixes, iPhones that simply refuse, and a screen that goes to sleep two minutes into your beautiful fullscreen experience.</p> <p>In this tutorial, you'll learn how to:</p> <ul> <li><p>Put any element (or the whole page) into fullscreen and back out again</p> </li> <li><p>Keep your UI in sync when the user presses <code>Esc</code></p> </li> <li><p>Style fullscreen content with the <code>:fullscreen</code> pseudo-class</p> </li> <li><p>Handle the cross-browser gotchas, including the one platform that still doesn't support it</p> </li> <li><p>Stop the screen from dimming with the <strong>Screen Wake Lock API</strong></p> </li> <li><p>Combine all of it into one small, reusable pattern</p> </li> </ul> <p>Everything here is vanilla JavaScript with no libraries or build step. You should be comfortable with DOM events and <code>async/await</code>. If you need a refresher on the latter, freeCodeCamp has a solid <a href="https://www.freecodecamp.org/news/javascript-async-await/">async/await tutorial</a> that covers everything we'll rely on.</p> <h2 id="heading-table-of-contents">Table of Contents</h2> <ul> <li><p><a href="#heading-how-the-fullscreen-api-works">How the Fullscreen API Works</a></p> </li> <li><p><a href="#heading-entering-and-exiting-fullscreen">Entering and Exiting Fullscreen</a></p> </li> <li><p><a href="#heading-the-user-gesture-rule">The User Gesture Rule</a></p> </li> <li><p><a href="#heading-keeping-your-ui-in-sync-with-fullscreenchange">Keeping Your UI in Sync with fullscreenchange</a></p> </li> <li><p><a href="#heading-styling-fullscreen-content">Styling Fullscreen Content</a></p> </li> <li><p><a href="#heading-cross-browser-gotchas">Cross-Browser Gotchas</a></p> </li> <li><p><a href="#heading-keeping-the-screen-awake-with-the-wake-lock-api">Keeping the Screen Awake with the Wake Lock API</a></p> </li> <li><p><a href="#heading-putting-it-all-together">Putting It All Together</a></p> </li> <li><p><a href="#heading-a-quick-gotcha-checklist">A Quick Gotcha Checklist</a></p> </li> <li><p><a href="#heading-conclusion">Conclusion</a></p> </li> </ul> <h2 id="heading-how-the-fullscreen-api-works">How the Fullscreen API Works</h2> <p>The Fullscreen API is small. It gives you three things you'll use every day:</p> <ul> <li><p><code>element.requestFullscreen()</code>: asks the browser to display that element (and its descendants) using the entire screen. It returns a Promise.</p> </li> <li><p><code>document.exitFullscreen()</code>: leaves fullscreen. Also returns a Promise.</p> </li> <li><p><code>document.fullscreenElement</code>: the element currently in fullscreen, or <code>null</code> if there isn't one. This is your single source of truth for "are we fullscreen right now?"</p> </li> </ul> <p>Plus two events on <code>document</code>: <code>fullscreenchange</code> (fires when fullscreen is entered <em>or</em> exited) and <code>fullscreenerror</code> (fires if a request fails).</p> <p>One thing that surprises people: you can make <em>any</em> element fullscreen, not just the page. If you fullscreen a <code>&lt;div&gt;</code>, only that <code>&lt;div&gt;</code> fills the screen. Everything else in the document is hidden behind it.</p> <p>To fullscreen the whole page, you call the method on <code>document.documentElement</code> (the <code>&lt;html&gt;</code> element).</p> <p>The full reference lives on <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API">MDN's Fullscreen API page</a>, but you won't need much beyond what's above.</p> <h2 id="heading-entering-and-exiting-fullscreen">Entering and Exiting Fullscreen</h2> <p>Let's start with the simplest useful thing: a button that toggles the page in and out of fullscreen.</p> <pre><code class="language-html">&lt;button id="fs-toggle"&gt;Fullscreen&lt;/button&gt; </code></pre> <pre><code class="language-javascript">const toggleBtn = document.getElementById('fs-toggle'); async function toggleFullscreen() { if (!document.fullscreenElement) { // Nothing is fullscreen yet – enter it. await document.documentElement.requestFullscreen(); } else { // Something is fullscreen – leave it. await document.exitFullscreen(); } } toggleBtn.addEventListener('click', toggleFullscreen); </code></pre> <p>That's genuinely it for the happy path. Because both methods return Promises, you can <code>await</code> them and know that the transition is finished before running any follow-up code.</p> <p>Both calls can reject, though. For example, if the document isn't allowed to go fullscreen (we'll get to why below), or if you call <code>exitFullscreen()</code> when nothing is fullscreen. So in real code, wrap them in <code>try/catch</code> rather than letting an unhandled rejection land in the console:</p> <pre><code class="language-javascript">async function toggleFullscreen() { try { if (!document.fullscreenElement) { await document.documentElement.requestFullscreen(); } else { await document.exitFullscreen(); } } catch (err) { console.warn(`Fullscreen failed: ${err.name} – ${err.message}`); } } </code></pre> <h2 id="heading-the-user-gesture-rule">The User Gesture Rule</h2> <p>Here's the first gotcha, and it's the one that generates the most confused questions on Stack Overflow: <strong>you can't enter fullscreen automatically</strong>. Not on page load, after a timer, or in response to a network event.</p> <p><code>requestFullscreen()</code> only works while the page has what the spec calls <em>transient activation</em>: a short window right after the user genuinely interacts with the page (like with a click, tap, or key press). Outside that window the Promise rejects, and in most browsers you'll see a message like <em>"API can only be initiated by a user gesture."</em></p> <p>This is deliberate. Without it, any page could hijack your whole screen the moment it loaded, which is exactly the kind of thing phishing pages would love to do.</p> <p>In practice, this means two things for your code:</p> <ol> <li><p>Always trigger fullscreen from an event handler tied to user input: <code>click</code>, <code>keydown</code>, <code>pointerup</code>, and so on.</p> </li> <li><p>Don't put an <code>await</code> for something slow <em>before</em> the <code>requestFullscreen()</code> call. If you <code>await fetch(...)</code> first, the activation window may have expired by the time you ask for fullscreen.</p> </li> </ol> <img src="https://cdn.hashnode.com/uploads/covers/6a60e4e5f99e7bbad25386f1/f635bd25-b6ac-44f4-9de2-e06a8fe5fe19.png" alt="Diagram of the user gesture rule: calling requestFullscreen() directly inside a click handler succeeds, while awaiting a slow fetch first lets the activation window expire and the call is rejected." style="display: block;" width="600" height="400" loading="lazy"> <p>Call <code>requestFullscreen()</code> first and do the slow work after, or the activation window closes before you ask.</p> <p>A common and very natural pattern is to let a keyboard shortcut do the same job as the button:</p> <pre><code class="language-javascript">document.addEventListener('keydown', (e) =&gt; { // Ignore shortcuts while the user is typing in a field. if (e.target.matches('input, textarea, [contenteditable]')) return; if (e.key === 'f' || e.key === 'F') { e.preventDefault(); toggleFullscreen(); } }); </code></pre> <p>Two small things I got wrong the first time around are worth passing on.</p> <p>First, make the fullscreen surface itself keyboard-reachable: give it <code>tabindex="0"</code> and treat <code>Enter</code> and <code>Space</code> on it exactly like a click, otherwise keyboard users have a button nobody told them about.</p> <p>Second, think about whether your shortcut key collides with what the page actually does. I have a "hacker typer" page where any key spits out fake terminal output, including <code>F</code>. For the first few days, users typing furiously would drop out of fullscreen mid-"hack" every time they hit that letter. The fix was a one-liner: on that page <code>F</code> only ever <em>enters</em> fullscreen, and leaving is <code>Esc</code>'s job alone.</p> <p>Which brings up <code>Esc</code>: you don't handle it yourself. Every browser exits fullscreen on <code>Esc</code>, and you can't prevent that. It's a safety escape hatch. What you <em>can</em> do is react to it, which is the next section.</p> <h2 id="heading-keeping-your-ui-in-sync-with-fullscreenchange">Keeping Your UI in Sync with <code>fullscreenchange</code></h2> <p>Because the user can leave fullscreen in ways your code doesn't control (like by pressing <code>Esc</code>, using the browser's own exit button, or switching apps on mobile), you should never track fullscreen state in your own variable. It will drift out of sync.</p> <p>Instead, treat <code>document.fullscreenElement</code> as the truth and update your UI whenever <code>fullscreenchange</code> fires:</p> <pre><code class="language-javascript">function syncFullscreenUI() { const isFullscreen = Boolean(document.fullscreenElement); toggleBtn.textContent = isFullscreen ? 'Exit fullscreen' : 'Fullscreen'; toggleBtn.setAttribute('aria-pressed', String(isFullscreen)); document.body.classList.toggle('is-fullscreen', isFullscreen); } document.addEventListener('fullscreenchange', syncFullscreenUI); document.addEventListener('fullscreenerror', () =&gt; { console.warn('Could not enter fullscreen.'); }); </code></pre> <p>This single listener covers every path in and out of fullscreen, including the ones you didn't initiate. It's also the right place to pause an animation, resume a game loop, or (as you'll see later) release a wake lock.</p> <h2 id="heading-styling-fullscreen-content">Styling Fullscreen Content</h2> <p>CSS gives you two hooks for fullscreen state.</p> <p>The <code>:fullscreen</code> pseudo-class matches the element that's currently fullscreen. Browsers apply a default stylesheet that stretches the element to the full viewport, but you'll usually want to control things like background and overflow yourself:</p> <pre><code class="language-css">:fullscreen { background: #000; overflow: hidden; cursor: none; /* hide the pointer on an idle fullscreen surface */ } </code></pre> <p>That <code>cursor: none</code> line looks cosmetic until you put a pure black page on an OLED display: every pixel is off, and the mouse pointer is quite literally the only thing lit on the panel. Hiding it once the page is fullscreen is the difference between "the screen is off" and "the screen has a tiny white arrow in the middle of it."</p> <p>The <code>::backdrop</code> pseudo-element is the layer painted <em>behind</em> the fullscreen element. It only matters when your fullscreen element doesn't cover the whole screen (for example, an element with a fixed aspect ratio), and it's how you control the letterboxing colour:</p> <pre><code class="language-css">:fullscreen::backdrop { background: #000; } </code></pre> <p>One practical tip: if you're fullscreening the whole page, set your background colour on <code>html</code>, not <code>body</code>. In fullscreen, <code>html</code> is the element being displayed, and on some browsers a <code>body</code>-only background leaves a thin strip of the wrong colour at the edges during the transition.</p> <h2 id="heading-cross-browser-gotchas">Cross-Browser Gotchas</h2> <p>The Fullscreen API has been standard in Chrome, Edge and Firefox for years. Safari is where the work is.</p> <h3 id="heading-older-safari-needs-the-webkit-prefix">Older Safari Needs the <code>webkit</code> Prefix</h3> <p>Safari only shipped the unprefixed API in version 16.4 (spring 2023) on macOS and iPadOS. Before that it used <code>webkitRequestFullscreen()</code>, <code>webkitExitFullscreen()</code>, <code>webkitFullscreenElement</code>, and a <code>webkitfullscreenchange</code> event. Unless you can ignore three-year-old Safari installs, a tiny compatibility layer is worth having:</p> <pre><code class="language-javascript">const fs = { get element() { return document.fullscreenElement ?? document.webkitFullscreenElement ?? null; }, get enabled() { return Boolean(document.fullscreenEnabled ?? document.webkitFullscreenEnabled); }, request(el = document.documentElement) { if (el.requestFullscreen) return el.requestFullscreen(); if (el.webkitRequestFullscreen) return Promise.resolve(el.webkitRequestFullscreen()); return Promise.reject(new Error('Fullscreen not supported')); }, exit() { if (document.exitFullscreen) return document.exitFullscreen(); if (document.webkitExitFullscreen) return Promise.resolve(document.webkitExitFullscreen()); return Promise.reject(new Error('Fullscreen not supported')); }, }; // Listen to both event names so old Safari stays in sync too. ['fullscreenchange', 'webkitfullscreenchange'].forEach((evt) =&gt; document.addEventListener(evt, syncFullscreenUI) ); </code></pre> <p>Now <code>fs.request()</code> and <code>fs.exit()</code> both return a Promise in every browser, and the rest of your code doesn't care which one it's running in. (You'll see <code>screenfull.js</code> recommended for this. It's a fine library, but it's been declared feature-complete and frozen, and the fifteen lines above are all it was ever doing for you.)</p> <h3 id="heading-iphone-safari-doesnt-support-element-fullscreen-at-all">iPhone Safari Doesn't Support Element Fullscreen at All</h3> <p>This is the gotcha that catches everyone. As of the time of writing, <strong>Safari on iPhone doesn't support the Fullscreen API for arbitrary elements</strong> – only for <code>&lt;video&gt;</code>. It works on iPad and on the Mac, but on the phone <code>document.fullscreenEnabled</code> is <code>false</code> and <code>requestFullscreen</code> doesn't exist on a <code>&lt;div&gt;</code>. Chrome and Firefox on iOS inherit the same limitation because they're required to use Safari's engine.</p> <p>You have two realistic options:</p> <ol> <li><p><strong>A "pseudo-fullscreen" fallback:</strong> Position your element with <code>position: fixed; inset: 0</code> and hide your own chrome. You won't get rid of Safari's address bar, but it collapses on scroll, and for most tools this is good enough.</p> </li> <li><p><strong>Suggest "Add to Home Screen":</strong> A web app launched from the home screen with <code>"display": "standalone"</code> in its manifest runs without any browser UI. This is the only way to get truly edge-to-edge content on an iPhone today.</p> </li> </ol> <p>Whichever you choose, don't rely on feature detection alone. <code>document.fullscreenEnabled</code> tells you whether the API <em>exists</em>, but the request can still be rejected at runtime (inside an iframe without the <code>allowfullscreen</code> attribute, on a page a browser policy has locked down, or simply because a browser you haven't tested has its own opinion).</p> <p>The pattern that has held up for me is to try the real API and treat a rejection as the trigger for the CSS fallback:</p> <pre><code class="language-javascript">function enterFullscreen(el) { if (fs.enabled) { return fs.request(el).catch(() =&gt; { // The API exists but refused – degrade to a fixed overlay. document.body.classList.add('pseudo-fullscreen'); }); } document.body.classList.add('pseudo-fullscreen'); return Promise.resolve(); } </code></pre> <p>On phones, I go one step further and don't call the API at all, even on Android where it technically works. Between the address bar reappearing on scroll and the system's swipe gestures, a fixed overlay behaves more predictably than real fullscreen on a small touch screen. It's also the same code path that iPhone Safari forces you into anyway. One less branch to test.</p> <p>You can check the current support table on <a href="https://caniuse.com/fullscreen">Can I use</a> before deciding how much of this you need.</p> <h2 id="heading-keeping-the-screen-awake-with-the-wake-lock-api">Keeping the Screen Awake with the Wake Lock API</h2> <p>You've built a beautiful fullscreen experience. The user leans back to watch it… and ninety seconds later the screen dims and locks, because the operating system saw no input and assumed nobody was there.</p> <p>For a video element, the browser handles this for you. For anything else (like a countdown, slideshow, canvas animation, recipe, or sheet-music page), you need the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API">Screen Wake Lock API</a>. It landed in every major browser in 2024 (Chrome 84+, Safari 16.4+, Firefox 126+) and became part of <a href="https://web.dev/blog/screen-wake-lock-supported-in-all-browsers">Baseline</a> in 2025, so you can use it today without a polyfill.</p> <p>The API is a single call, and it's Promise-based:</p> <pre><code class="language-javascript">let wakeLock = null; async function requestWakeLock() { if (!('wakeLock' in navigator)) return; // unsupported – fail silently try { wakeLock = await navigator.wakeLock.request('screen'); wakeLock.addEventListener('release', () =&gt; { // The OS or browser released it (tab hidden, battery saver, etc.) wakeLock = null; }); } catch (err) { // Rejected – most often because the device is in a power-saving mode. console.warn(`Wake lock failed: ${err.name} – ${err.message}`); } } async function releaseWakeLock() { if (wakeLock) { await wakeLock.release(); wakeLock = null; } } </code></pre> <p>Three rules to know:</p> <ol> <li><p><strong>It requires a secure context.</strong> The API is only exposed over HTTPS (and <code>localhost</code>).</p> </li> <li><p><strong>The browser releases the lock automatically when the page is hidden</strong>. If the user switches tabs, minimises the window, or locks the phone, when the page becomes visible again, the lock does <em>not</em> come back on its own. You have to re-request it:</p> </li> </ol> <pre><code class="language-javascript">document.addEventListener('visibilitychange', () =&gt; { if (document.visibilityState === 'visible' &amp;&amp; shouldStayAwake()) { requestWakeLock(); } }); </code></pre> <ol> <li><strong>Be a good citizen.</strong> A wake lock drains batteries. Only hold it while it's actually useful, like while something is playing, running, or being displayed. Release it the moment that stops.</li> </ol> <p>The nice part is that the Fullscreen API already gives you a perfect signal for "something is being displayed": <code>fullscreenchange</code>. When the user enters fullscreen, then request the lock. When they leave fullscreen, release it.</p> <p>Fullscreen isn't the only good signal, though, and it helps to think of the wake lock as attached to <em>an activity</em> rather than to a display mode. On a countdown timer, I request the lock when the countdown starts and release it when it reaches zero or is paused (whether or not the page is fullscreen), because nobody wants a timer that goes dark at the 90-second mark. On a rain-sounds player, the lock follows the audio: it's acquired on play and released on pause or when the sleep timer fades the sound out.</p> <p>The mechanics are identical: only the "should the screen stay awake right now?" question changes.</p> <h2 id="heading-putting-it-all-together">Putting It All Together</h2> <p>Here's the whole pattern in one place: a fullscreen toggle with a keyboard shortcut, a wake lock that follows fullscreen state, UI that stays in sync no matter how the user leaves, and a fallback for browsers that can't do it.</p> <pre><code class="language-javascript">const toggleBtn = document.getElementById('fs-toggle'); let wakeLock = null; /* ---------- Fullscreen compatibility layer ---------- */ const fs = { get element() { return document.fullscreenElement ?? document.webkitFullscreenElement ?? null; }, get enabled() { return Boolean(document.fullscreenEnabled ?? document.webkitFullscreenEnabled); }, request(el = document.documentElement) { if (el.requestFullscreen) return el.requestFullscreen(); if (el.webkitRequestFullscreen) return Promise.resolve(el.webkitRequestFullscreen()); return Promise.reject(new Error('Fullscreen not supported')); }, exit() { if (document.exitFullscreen) return document.exitFullscreen(); if (document.webkitExitFullscreen) return Promise.resolve(document.webkitExitFullscreen()); return Promise.reject(new Error('Fullscreen not supported')); }, }; /* ---------- Wake lock ---------- */ async function requestWakeLock() { if (!('wakeLock' in navigator) || wakeLock) return; try { wakeLock = await navigator.wakeLock.request('screen'); wakeLock.addEventListener('release', () =&gt; { wakeLock = null; }); } catch (err) { console.warn(`Wake lock failed: ${err.name}`); } } async function releaseWakeLock() { if (!wakeLock) return; await wakeLock.release(); wakeLock = null; } /* ---------- Toggle ---------- */ async function toggleFullscreen() { const pseudo = document.body.classList.contains('pseudo-fullscreen'); try { if (pseudo) { document.body.classList.remove('pseudo-fullscreen'); onFullscreenChange(); } else if (!fs.element) { await fs.request(); } else { await fs.exit(); } } catch (err) { // The API refused (iframe policy, unsupported platform, etc.) – degrade gracefully. document.body.classList.add('pseudo-fullscreen'); onFullscreenChange(); } } /* ---------- Keep everything in sync ---------- */ function onFullscreenChange() { const active = Boolean(fs.element) || document.body.classList.contains('pseudo-fullscreen'); toggleBtn.textContent = active ? 'Exit fullscreen' : 'Fullscreen'; toggleBtn.setAttribute('aria-pressed', String(active)); document.body.classList.toggle('is-fullscreen', active); // The screen should stay awake exactly as long as we're fullscreen. if (active) requestWakeLock(); else releaseWakeLock(); } ['fullscreenchange', 'webkitfullscreenchange'].forEach((evt) =&gt; document.addEventListener(evt, onFullscreenChange) ); // Re-acquire the lock if the tab was hidden and came back while fullscreen. document.addEventListener('visibilitychange', () =&gt; { if (document.visibilityState === 'visible' &amp;&amp; fs.element) requestWakeLock(); }); /* ---------- Wiring ---------- */ toggleBtn.addEventListener('click', toggleFullscreen); document.addEventListener('keydown', (e) =&gt; { if (e.target.matches('input, textarea, [contenteditable]')) return; if (e.key === 'f' || e.key === 'F') { e.preventDefault(); toggleFullscreen(); } }); // Unsupported platforms (iPhone Safari) simply take the catch branch above // on the first click and land in pseudo-fullscreen – no user-agent sniffing needed. // One more mobile quirk: rotating the device changes the viewport *after* // the event fires, so re-measure your canvas or layout a beat later. const resizeStage = () =&gt; { /* re-measure whatever fills the screen */ }; window.addEventListener('orientationchange', () =&gt; setTimeout(resizeStage, 100)); </code></pre> <p>And the matching CSS:</p> <pre><code class="language-css">html { background: #000; } :fullscreen { overflow: hidden; cursor: none; } :fullscreen::backdrop { background: #000; } /* Fallback for browsers without element fullscreen */ body.pseudo-fullscreen .app { position: fixed; inset: 0; } body.pseudo-fullscreen .chrome { display: none; } </code></pre> <p>Roughly sixty lines, and it's the same core I run in production: I log every fullscreen entry as an analytics event, because on a screen-tool site that transition <em>is</em> the conversion, and this exact code is what fires it.</p> <p>It powers, for instance, the <a href="https://blankscreen.io/black-screen">black screen page on blankscreen.io</a> – a page whose entire job is to turn a display pure black, go fullscreen on a click or an <code>F</code> key, hide the pointer, stay awake for as long as it's on screen, and get out of the way cleanly on <code>Esc</code>. If you open it on an iPhone, you'll see the pseudo-fullscreen fallback from above doing its thing instead.</p> <img src="https://cdn.hashnode.com/uploads/covers/6a60e4e5f99e7bbad25386f1/dea1eb4a-7862-46f8-a746-86550515820a.png" alt="A pure black web page showing a 'Click for fullscreen' prompt with hints to press F to enter and Esc to exit fullscreen" style="display: block;" width="600" height="400" loading="lazy"> <p>The same pattern in the wild: one click or the F key, the whole display goes black, and the screen stays awake for as long as it's showing. Esc brings the browser back.</p> <p>Once you have this pattern, adding it to a timer, a slideshow, or a canvas experiment is a matter of dropping in the element you want to fill the screen.</p> <h2 id="heading-a-quick-gotcha-checklist">A Quick Gotcha Checklist</h2> <p>Before you ship, run through this list. Every item is something I've been bitten by at least once:</p> <ul> <li><p><strong>User gesture required:</strong> No fullscreen on load, on timer or after an <code>await</code> that takes a while.</p> </li> <li><p><strong>Don't track state yourself:</strong> Read <code>document.fullscreenElement</code> and listen for <code>fullscreenchange</code>.</p> </li> <li><p><strong>You can't block</strong><code>Esc</code><strong>:</strong> Design for the user leaving at any moment.</p> </li> <li><p><strong>Old Safari wants</strong> <code>webkit</code> <strong>prefixes</strong> for the methods <em>and</em> the event name.</p> </li> <li><p><strong>iPhone Safari has no element fullscreen:</strong> Feature-detect with <code>document.fullscreenEnabled</code>, and treat a runtime rejection as a fallback trigger, not just a console warning.</p> </li> <li><p><strong>Check your shortcut against the page's own keys:</strong> If the app consumes letters, let the shortcut only <em>enter</em> fullscreen and leave exiting to <code>Esc</code>.</p> </li> <li><p><strong>Make the fullscreen surface keyboard-reachable</strong> (<code>tabindex="0"</code>, <code>Enter</code>/<code>Space</code>).</p> </li> <li><p><strong>Wake locks need HTTPS:</strong> Can be rejected in battery-saver mode, and they're dropped when the page is hidden. Re-request on <code>visibilitychange</code>.</p> </li> <li><p><strong>Release the wake lock</strong> as soon as the reason for it is gone.</p> </li> <li><p><strong>Put the background on</strong> <code>html</code>, not just <code>body</code>, when fullscreening the page.</p> </li> </ul> <h2 id="heading-conclusion">Conclusion</h2> <p>The Fullscreen API is one of those browser features that looks like a one-liner and turns out to have a personality.</p> <p>The core (<code>requestFullscreen()</code>, <code>exitFullscreen()</code>, <code>fullscreenElement</code>, and the <code>fullscreenchange</code> event) really is simple. The craft is in respecting the user-gesture rule, keeping your UI honest about the real state, handling Safari's history, and remembering that "fullscreen" is only half of the job if the screen goes dark two minutes later. The Wake Lock API closes that gap, and pairing the two through <code>fullscreenchange</code> keeps both of them tidy.</p> <p>Take the sixty-line pattern above, drop your own element into it, and you have a production-ready fullscreen experience for anything from a presentation to a game.</p> <p>Happy coding!</p>

How to apply

  1. 1 Read the full details above and confirm you meet the eligibility criteria.
  2. 2 Prepare your documents — an updated CV, and any cover letter, proposal or certificates required.
  3. 3 Click Apply on official site to complete your application on Alex Oliinyk’s official page.
  4. 4 Submit as early as possible — many close once filled.
Apply on official site

Sourced from freecodecamp. Always verify details on the official website. Opportunihub never charges you to apply.

Frequently asked questions

How do I apply for How to Use the Fullscreen API in JavaScript (and Keep the Screen Awake with the Wake Lock API)?

Review the full details and eligibility on this page, prepare your documents, then use the “Apply on official site” button to complete your application on Alex Oliinyk’s official page.

Is this opportunity remote or location-based?

This opportunity is remote-friendly and open to applicants who can work from anywhere.

Is How to Use the Fullscreen API in JavaScript (and Keep the Screen Awake with the Wake Lock API) free to apply for?

Opportunihub lists this Course for free. Legitimate Courses do not ask for payment to apply — never pay a fee to submit an application.