Greasy Fork

Greasy Fork is available in English.

YouTube Restore Scrollable Fullscreen

Restores scrollable fullscreen mode to show title, comments, likes, and related videos. Disables new UI's bottom recommendations.

< 脚本 YouTube Restore Scrollable Fullscreen 的反馈

评价:好评 - 脚本运行良好

§
发布于:2025-10-26

Firefox Port:

Here's a modified version for Greasemonkey extension for Firefox browser:

// ==UserScript==
// @name         YouTube Restore Scrollable Fullscreen
// @namespace    burak-tools
// @version      1.8
// @description  Restores scrollable fullscreen mode to show title, comments, likes, and related videos. Disables new UI's bottom recommendations.
// @author       Waldoocs (https://x.com/Waldoocs) [https://github.com/Waldoocs](https://github.com/Waldoocs)
// @match        https://www.youtube.com/*
// @run-at       document-idle
// @grant        GM_addStyle
// @grant        GM.addStyle
// @license      MIT
// @downloadURL  https://update.greasyfork.icu/scripts/547663/YouTube%20Restore%20Scrollable%20Fullscreen.user.js
// @updateURL    https://update.greasyfork.icu/scripts/547663/YouTube%20Restore%20Scrollable%20Fullscreen.meta.js
// @compatible   firefox
// @compatible   chrome
// ==/UserScript==

(function() {
    'use strict';

    // Cross-browser GM_addStyle
    const addStyle = (css) => {
        if (typeof GM_addStyle !== 'undefined') {
            GM_addStyle(css);
        } else if (typeof GM !== 'undefined' && GM.addStyle) {
            GM.addStyle(css);
        } else {
            const style = document.createElement('style');
            style.type = 'text/css';
            style.textContent = css;
            document.head.appendChild(style);
        }
    };

    addStyle(`
        ytd-app[fullscreen] {
            overflow: auto !important;
        }
        ytd-app[scrolling] {
            position: absolute !important;
            top: 0 !important;
            left: 0 !important;
            right: calc((var(--ytd-app-fullerscreen-scrollbar-width) + 1px)*-1) !important;
            bottom: 0 !important;
            overflow-x: auto !important;
        }
        ytd-watch-flexy[fullscreen] #single-column-container.ytd-watch-flexy,
        ytd-watch-flexy[fullscreen] #columns.ytd-watch-flexy {
            display: flex !important;
        }

        /* Hide the fullscreen grid with recommended videos */
        .ytp-fullscreen-grid,
        .ytp-fullscreen-grid-main-content,
        .ytp-fullscreen-grid-stills-container,
        .ytp-modern-videowall-still,
        .ytp-fullscreen-grid-expand-button,
        .ytp-fullscreen-grid-hover-overlay {
            display: none !important;
            opacity: 0 !important;
            visibility: hidden !important;
            pointer-events: none !important;
            height: 0 !important;
            max-height: 0 !important;
            overflow: hidden !important;
        }

        /* Completely disable grid scrolling CSS variables */
        .html5-video-player.ytp-grid-scrollable,
        .html5-video-player {
            --ytp-grid-scroll-percentage: 0 !important;
            --ytp-grid-peek-height: 0px !important;
        }

        /* Hide any fullscreen education panels and overlays */
        .ytp-fullerscreen-edu-panel,
        .ytp-cards-teaser,
        .ytp-cards-teaser-box,
        div[class*="fullerscreen"] {
            display: none !important;
            opacity: 0 !important;
            visibility: hidden !important;
        }
    `);

    // JavaScript to detect and disable new UI scroll behavior
    function disableNewUIScroll() {
        const player = document.querySelector('.html5-video-player');

        if (player) {
            // Remove the grid scrollable class
            if (player.classList.contains('ytp-grid-scrollable')) {
                player.classList.remove('ytp-grid-scrollable');
            }

            // Force CSS variables to 0
            player.style.setProperty('--ytp-grid-scroll-percentage', '0', 'important');
            player.style.setProperty('--ytp-grid-peek-height', '0px', 'important');
        }

        // Remove fullscreen grid elements
        const gridElements = document.querySelectorAll('.ytp-fullscreen-grid, .ytp-fullscreen-grid-main-content, .ytp-fullscreen-grid-stills-container, .ytp-modern-videowall-still');
        gridElements.forEach(el => {
            el.style.display = 'none';
            el.style.visibility = 'hidden';
            try {
                el.remove();
            } catch (e) {
                console.debug('Element already removed');
            }
        });

        // Remove fullscreen education panels
        const panels = document.querySelectorAll('.ytp-fullerscreen-edu-panel, .ytp-cards-teaser, div[class*="fullerscreen"]');
        panels.forEach(panel => {
            panel.style.display = 'none';
            panel.style.visibility = 'hidden';
            try {
                panel.remove();
            } catch (e) {
                console.debug('Panel already removed');
            }
        });
    }

    // Initialize the script
    function init() {
        // Run immediately
        disableNewUIScroll();

        // Watch for DOM changes
        const observer = new MutationObserver((mutations) => {
            // Only run if there are relevant mutations
            const shouldRun = mutations.some(mutation => {
                // Check if the mutation is relevant
                return (mutation.type === 'childList' && mutation.addedNodes.length > 0) ||
                       (mutation.type === 'attributes' && 
                        (mutation.attributeName === 'class' || 
                         mutation.attributeName === 'style'));
            });

            if (shouldRun) {
                disableNewUIScroll();
            }
        });

        // Start observing the entire document
        observer.observe(document.documentElement, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['class', 'style']
        });

        // Run periodically as backup
        const backupInterval = setInterval(disableNewUIScroll, 300);

        // Clean up on script unload
        window.addEventListener('unload', () => {
            clearInterval(backupInterval);
            observer.disconnect();
        });

        // Intercept scroll events
        const handleScroll = () => disableNewUIScroll();
        document.addEventListener('scroll', handleScroll, true);
        document.addEventListener('wheel', handleScroll, true);
    }

    // Start the script when the DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();
Waldoocs作者
§
发布于:2025-10-26

It already works for firefox.

发布留言

登录以发布留言。