您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Disable scrolling when YouTube is in fullscreen mode and hide scrollbar. Also hide certain fullscreen UI elements.
// ==UserScript== // @name YouTube Fullscreen Scroll Disabler // @namespace https://youtube.com // @version 1.0.2 // @description Disable scrolling when YouTube is in fullscreen mode and hide scrollbar. Also hide certain fullscreen UI elements. // @author Lolen10 // @match *://www.youtube.com/* // @icon https://www.google.com/s2/favicons?domain=youtube.com // @grant none // @license GNU GPLv3 // ==/UserScript== (function() { 'use strict'; // Store references to hidden elements and their previous display values let hiddenElements = []; // Store previous overflow values so we can restore them let previousOverflow = { html: '', body: '' }; let styleElementId = 'ytfs-scrollblocker-style'; let listenersAdded = false; // Event listeners for fullscreen change document.addEventListener('fullscreenchange', toggleScrollAndContent, false); document.addEventListener('webkitfullscreenchange', toggleScrollAndContent, false); // Older WebKit document.addEventListener('mozfullscreenchange', toggleScrollAndContent, false); // Firefox // Also handle when the user presses F (YouTube's fullscreen toggle) or when the player switches programmatically. // We'll run the toggle function once on script load to handle pages that already are fullscreen (rare). setTimeout(toggleScrollAndContent, 500); function toggleScrollAndContent() { if (isFullScreen()) { enterFullscreenMode(); } else { exitFullscreenMode(); } } function isFullScreen() { return !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement); } // ---------- Fullscreen enter/exit ---------- function enterFullscreenMode() { // Disable scroll input disableScroll(); // Hide content below the #single-column-container (existing behavior) removeContentBelowContainer(); // Hide ytp fullscreen grid main content(s) hideBySelectorAll('.ytp-fullscreen-grid-main-content'); // Hide expand button(s) hideBySelectorAll('.ytp-fullscreen-grid-expand-button.ytp-button'); } function exitFullscreenMode() { // Re-enable scrolling enableScroll(); // Restore previously hidden elements restoreHiddenElements(); } // ---------- Hiding / restoring helpers ---------- function hideBySelectorAll(selector) { const nodes = document.querySelectorAll(selector); nodes.forEach(node => { // Avoid hiding same node twice if (!hiddenElements.some(entry => entry.el === node)) { hiddenElements.push({ el: node, prevDisplay: node.style.display || '' }); node.style.display = 'none'; } }); } // Remove all content below #single-column-container (keeps previous behavior but stores prev display) function removeContentBelowContainer() { const container = document.getElementById('single-column-container'); if (container) { let nextSibling = container.nextElementSibling; while (nextSibling) { if (!hiddenElements.some(entry => entry.el === nextSibling)) { hiddenElements.push({ el: nextSibling, prevDisplay: nextSibling.style.display || '' }); nextSibling.style.display = 'none'; } nextSibling = nextSibling.nextElementSibling; } } } function restoreHiddenElements() { hiddenElements.forEach(entry => { try { entry.el.style.display = entry.prevDisplay; } catch (err) { // element might have been removed from DOM — ignore } }); hiddenElements = []; } // ---------- Scroll blocking ---------- function preventScroll(e) { // Only prevent if in fullscreen (defensive) if (!isFullScreen()) return; e.preventDefault(); e.stopPropagation(); return false; } function preventKeyScroll(e) { if (!isFullScreen()) return; // Keys that can scroll the page const blockedKeys = [ 'PageUp', 'PageDown', 'Home', 'End', ' ' ]; if (blockedKeys.includes(e.key)) { // Allow if user is focused in an input/textarea/contenteditable const target = e.target; const tag = target && target.tagName ? target.tagName.toLowerCase() : ''; const isEditable = target && (target.isContentEditable || tag === 'input' || tag === 'textarea' || target.getAttribute('role') === 'textbox'); if (!isEditable) { e.preventDefault(); e.stopPropagation(); return false; } } } function disableScroll() { if (listenersAdded) return; // don't add twice // Save previous overflow values previousOverflow.html = document.documentElement.style.overflow || ''; previousOverflow.body = document.body.style.overflow || ''; // Force hide overflow to block scrollbar-based scrolling as a robust fallback try { document.documentElement.style.overflow = 'hidden'; document.body.style.overflow = 'hidden'; } catch (err) { // ignore if not allowed } // Insert style to hide scrollbars (visual) if (!document.getElementById(styleElementId)) { const style = document.createElement('style'); style.id = styleElementId; style.type = 'text/css'; style.appendChild(document.createTextNode( 'html, body { overscroll-behavior: none !important; height: 100% !important; } ' + '::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; }' )); (document.head || document.documentElement).appendChild(style); } // Add wheel & touchmove listeners (passive: false to allow preventDefault) window.addEventListener('wheel', preventScroll, { passive: false, capture: true }); window.addEventListener('touchmove', preventScroll, { passive: false, capture: true }); // Keydown to block space/arrow/page keys window.addEventListener('keydown', preventKeyScroll, { passive: false, capture: true }); listenersAdded = true; } function enableScroll() { if (!listenersAdded) { // still attempt to clean up style/overflow even if listeners weren't marked as added cleanupOverflowAndStyle(); return; } window.removeEventListener('wheel', preventScroll, { capture: true }); window.removeEventListener('touchmove', preventScroll, { capture: true }); window.removeEventListener('keydown', preventKeyScroll, { capture: true }); cleanupOverflowAndStyle(); listenersAdded = false; } function cleanupOverflowAndStyle() { // Restore previous overflow values try { document.documentElement.style.overflow = previousOverflow.html || ''; document.body.style.overflow = previousOverflow.body || ''; } catch (err) { // ignore } // Remove style element that hid scrollbars const style = document.getElementById(styleElementId); if (style && style.parentNode) { style.parentNode.removeChild(style); } } // Keep things tidy if the user navigates or the page rebuilds heavy parts of the DOM: // If the fullscreen element is removed unexpectedly, make sure we restore. const observer = new MutationObserver(() => { if (!isFullScreen() && (hiddenElements.length > 0 || listenersAdded)) { // Force restore if DOM changed and we are no longer fullscreen exitFullscreenMode(); } }); observer.observe(document.documentElement, { childList: true, subtree: true }); // Clean up on unload window.addEventListener('beforeunload', () => { try { observer.disconnect(); } catch (e) {} enableScroll(); }); })();