您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a smart fullscreen button and hides navbar.
// ==UserScript== // @name Poki Better Fullscreen // @namespace https://poki.com/ // @version 1.0 // @description Adds a smart fullscreen button and hides navbar. // @match https://poki.com/* // @run-at document-idle // @grant none // @noframes // @license MIT // @author giovane2230 // ==/UserScript== (() => { "use strict"; // ======================== // UTILITY FUNCTIONS // ======================== // Shortcut for requestAnimationFrame const raf = (fn) => requestAnimationFrame(fn); // Add an event listener that triggers only once const once = (el, type, fn) => el.addEventListener(type, fn, { once: true }); // ======================== // SPA URL CHANGE DETECTION // ======================== // Detect URL changes in Single Page Applications (SPA) const initUrlChangeHook = () => { const originalPush = history.pushState; const originalReplace = history.replaceState; const triggerEvent = () => window.dispatchEvent(new Event("poki-urlchange")); history.pushState = function () { originalPush.apply(this, arguments); triggerEvent(); }; history.replaceState = function () { originalReplace.apply(this, arguments); triggerEvent(); }; window.addEventListener("popstate", triggerEvent); }; // ======================== // FULLSCREEN BUTTON // ======================== // Find Poki's "report bug" button for reference const findReportButton = () => { const useEl = document.querySelector( "button use[href='#reportIcon'], button use[xlink\\:href='#reportIcon']" ); return useEl ? useEl.closest("button") : null; }; // Check if a fullscreen button already exists const fullscreenButtonExists = () => !!document.querySelector( "#fullscreen-button, button[aria-label*='ullscreen'], button[aria-label*='inimize']" ); // Create a fullscreen button with native Poki styling const createFullscreenButton = () => { const btn = document.createElement("button"); btn.type = "button"; btn.id = "fullscreen-button"; btn.className = "HPn_GzeLxs8_4nNebuj1 mDTrvHhilj2xlIvo_kXA phlaiC_iad_lookW5__d"; btn.setAttribute("aria-label", "Fullscreen"); btn.title = "Toggle Fullscreen"; // Icon container const iconDiv = document.createElement("div"); iconDiv.className = "tqh57qBcKxMV9EdZQoAb"; iconDiv.innerHTML = ` <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" class="AUcJqk5uLaoXL0jqRGuH"> <use xlink:href="#enterFullscreenIcon" href="#enterFullscreenIcon"></use> </svg> `; btn.append(iconDiv); // Text container const textDiv = document.createElement("div"); textDiv.className = "aAJE6r6D5rwwQuTmZqYG"; const emptySpan = document.createElement("span"); emptySpan.className = "L6WSODmebiIqJJOEi46E Vlw13G6cUIC6W9LiGC_X"; textDiv.append(emptySpan); const label = document.createElement("span"); label.className = "L6WSODmebiIqJJOEi46E tz2DEu5qBC9Yd6hJGjoW"; label.textContent = "Fullscreen"; textDiv.append(label); btn.append(textDiv); // Toggle fullscreen on click btn.addEventListener("click", () => { const elem = document.documentElement; if (!document.fullscreenElement) { // Request fullscreen (elem.requestFullscreen || elem.webkitRequestFullscreen || elem.msRequestFullscreen)?.call(elem); } else { // Exit fullscreen (document.exitFullscreen || document.webkitExitFullscreen || document.msExitFullscreen)?.call(document); } }); return btn; }; // Insert a new node after a reference node const insertAfter = (newNode, referenceNode) => { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); }; // ======================== // GAME MAXIMIZATION // ======================== // Hide navbar and other navigation elements only in fullscreen const hideNavbarInFullscreen = () => { if (!document.fullscreenElement) return; const selectors = [ 'nav#nav.qoMYGbBhf9dsbaBGBphh.DJT17TB5hYo14sdLEAwk', '.J91n1ymJasoch_FZq89b', 'nav', '[role="navigation"]', '.navbar', '.navigation', '.nav', 'header nav', ]; selectors.forEach((selector) => { try { const elements = document.querySelectorAll(selector); elements.forEach((el) => { if (!el.hasAttribute("data-hidden-in-fullscreen")) { el.style.cssText = "display: none !important; visibility: hidden !important;"; el.setAttribute("data-hidden-in-fullscreen", "true"); } }); } catch (e) { // Ignore invalid selectors } }); // Remove Poki-specific nav completely const pokiNav = document.querySelector( 'nav#nav.qoMYGbBhf9dsbaBGBphh.DJT17TB5hYo14sdLEAwk' ); if (pokiNav && !pokiNav.hasAttribute("data-removed-in-fullscreen")) { pokiNav.remove(); pokiNav.setAttribute("data-removed-in-fullscreen", "true"); } }; // Restore navbar when leaving fullscreen const restoreNavbarFromFullscreen = () => { if (document.fullscreenElement) return; const hiddenElements = document.querySelectorAll("[data-hidden-in-fullscreen]"); hiddenElements.forEach((el) => { el.style.cssText = ""; el.removeAttribute("data-hidden-in-fullscreen"); }); }; // ======================== // FULLSCREEN BUTTON MANAGEMENT // ======================== let localObserver = null; // Ensure a fullscreen button exists and is functional const ensureFullscreenButton = () => { if (fullscreenButtonExists()) return; const reportBtn = findReportButton(); if (!reportBtn) return; const btn = createFullscreenButton(); insertAfter(btn, reportBtn); // Observer to keep the button alive if DOM changes if (localObserver) localObserver.disconnect(); localObserver = new MutationObserver(() => { if (!fullscreenButtonExists()) { localObserver.disconnect(); Promise.resolve().then(() => raf(ensureFullscreenButton)); } }); const scope = reportBtn.parentElement || reportBtn; localObserver.observe(scope, { childList: true }); // Remove our button if Poki adds a native fullscreen button const removeIfNativeAppears = () => { if ( fullscreenButtonExists() && btn.isConnected && btn !== document.querySelector("#fullscreen-button") ) { btn.remove(); localObserver?.disconnect(); } }; once(document, "fullscreenchange", removeIfNativeAppears); }; // ======================== // INITIALIZATION // ======================== initUrlChangeHook(); // Ensure button after DOM is ready document.addEventListener("readystatechange", () => raf(ensureFullscreenButton)); // Handle fullscreen changes document.addEventListener( "fullscreenchange", () => { if (document.fullscreenElement) { setTimeout(() => hideNavbarInFullscreen(), 100); } else { setTimeout(() => restoreNavbarFromFullscreen(), 100); } raf(ensureFullscreenButton); }, { passive: true } ); // Handle SPA route changes window.addEventListener( "poki-urlchange", () => { setTimeout(() => raf(ensureFullscreenButton), 100); }, { passive: true } ); // Safety interval to maintain fullscreen button and hide navbar setInterval(() => { if (!fullscreenButtonExists()) ensureFullscreenButton(); if (document.fullscreenElement) hideNavbarInFullscreen(); }, 2000); raf(ensureFullscreenButton); // ======================== // ADDITIONAL STYLES // ======================== const style = document.createElement("style"); style.textContent = ` html:fullscreen, html:-webkit-full-screen, html:-moz-full-screen { overflow:hidden !important; } html:fullscreen body, html:-webkit-full-screen body, html:-moz-full-screen body { margin:0 !important; padding:0 !important; overflow:hidden !important; } #fullscreen-button:hover { opacity:0.8 !important; transform:scale(1.05) !important; transition:all 0.2s ease !important; } #game-player[data-enhanced] { box-sizing: border-box !important; } html:fullscreen nav, html:-webkit-full-screen nav, html:-moz-full-screen nav, html:fullscreen [role="navigation"], html:-webkit-full-screen [role="navigation"], html:-moz-full-screen [role="navigation"], html:fullscreen .navbar, html:-webkit-full-screen .navbar, html:-moz-full-screen .navbar { display:none !important; visibility:hidden !important; } html:fullscreen [class*="qoMYGbBhf9dsbaBGBphh"], html:-webkit-full-screen [class*="qoMYGbBhf9dsbaBGBphh"], html:-moz-full-screen [class*="qoMYGbBhf9dsbaBGBphh"], html:fullscreen [class*="DJT17TB5hYo14sdLEAwk"], html:-webkit-full-screen [class*="DJT17TB5hYo14sdLEAwk"], html:-moz-full-screen [class*="DJT17TB5hYo14sdLEAwk"] { display:none !important; visibility:hidden !important; } `; document.head.appendChild(style); console.log( "betterfullscreen loaded" ); })();