Greasy Fork

Greasy Fork is available in English.

YouTube视觉隐身广告拦截器

无API依赖的极简高效广告拦截方案

目前为 2025-03-29 提交的版本。查看 最新版本

// ==UserScript==
// @name        YouTube视觉隐身广告拦截器
// @namespace   pure-dom
// @version     3.2.1
// @match       *://*.youtube.com/*
// @grant       none
// @run-at      document-start
// @description 无API依赖的极简高效广告拦截方案
// ==/UserScript==

(function() {
    'use strict';

    // 动态元素特征库(伪装成普通样式表)
    const stealthRules = {
        selectors: [
            'ytd-ad-slot-renderer', 
            'div.ytd-promoted-sparkles-web-renderer',
            'ytm-companion-ad-renderer',
            '[data-ad-metadata]',
            'div#player-ads.ytd-watch',
            'ytd-rich-section-renderer:has(ytd-ad-)',
            'div[class*="-ad-"]:not([data-legitimate])',
            'ytd-action-companion-ad-renderer',
            'div.ytp-ad-module'
        ],
        attributes: [
            'ad-showing',
            'data-ad-status',
            'ad-type',
            'data-request-slot'
        ]
    };

    // 三维隐藏系统(物理隐藏+视觉隐藏+逻辑隐藏)
    const createGhostCSS = () => {
        const style = document.createElement('style');
        style.id = '__yt_legit_style';
        style.textContent = `
            ${stealthRules.selectors.join(',')} {
                transform: scale(0) !important;
                height: 0 !important;
                width: 0 !important;
                opacity: 0 !important;
                overflow: hidden !important;
                contain: strict !important;
                margin: 0 !important;
                padding: 0 !important;
                pointer-events: none !important;
                visibility: hidden !important;
                position: absolute !important;
                z-index: -99999 !important;
            }

            /* 伪造正常布局 */
            ytd-watch-flexy[theater] #player.ytd-watch-flexy {
                top: 0 !important;
                height: 100vh !important;
            }

            /* 消除广告残留空间 */
            ytd-rich-item-renderer:empty {
                display: none !important;
            }
        `;
        document.head.appendChild(style);
    };

    // 智能元素消毒系统
    const elementSanitizer = {
        observer: null,
        mutationConfig: {
            childList: true,
            subtree: true,
            attributeFilter: stealthRules.attributes
        },

        init() {
            this.setupObserver();
            this.initialCleanup();
            this.enableLayoutProtection();
        },

        setupObserver() {
            this.observer = new MutationObserver(mutations => {
                mutations.forEach(mutation => {
                    if (mutation.type === 'attributes') {
                        this.neutralizeElement(mutation.target);
                    } else if (mutation.addedNodes) {
                        mutation.addedNodes.forEach(node => {
                            if (node.nodeType === 1) this.deepClean(node);
                        });
                    }
                });
            });
            this.observer.observe(document.documentElement, this.mutationConfig);
        },

        initialCleanup() {
            this.deepClean(document.documentElement);
            setTimeout(() => this.deepClean(document.body), 1500);
        },

        deepClean(root) {
            stealthRules.selectors.forEach(selector => {
                root.querySelectorAll(selector).forEach(element => {
                    this.neutralizeElement(element);
                });
            });
            this.processAttributes(root);
        },

        neutralizeElement(element) {
            if (!element.dataset.stealthProcessed) {
                element.replaceChildren();
                element.style.cssText = `
                    transform: scale(0);
                    height: 0;
                    width: 0;
                    opacity: 0;
                    pointer-events: none;
                `;
                element.dataset.stealthProcessed = "1";
            }
        },

        processAttributes(root) {
            stealthRules.attributes.forEach(attr => {
                root.querySelectorAll(`[${attr}]`).forEach(element => {
                    element.removeAttribute(attr);
                    element.setAttribute('data-legitimate', 'true');
                });
            });
        },

        enableLayoutProtection() {
            const fixLayout = () => {
                const player = document.querySelector('#movie_player');
                if (player) {
                    player.style.cssText = `
                        position: fixed !important;
                        top: 0 !important;
                        left: 0 !important;
                        width: 100vw !important;
                        height: 100vh !important;
                        z-index: 9999 !important;
                    `;
                }
            };
            new MutationObserver(fixLayout).observe(document, {
                childList: true,
                subtree: true
            });
        }
    };

    // 启动系统
    createGhostCSS();
    elementSanitizer.init();

    // 环境混淆保护
    document.addEventListener('DOMContentLoaded', () => {
        Object.defineProperty(document, 'hidden', {
            get: () => false,
            configurable: false
        });
        window.requestAnimationFrame = new Proxy(window.requestAnimationFrame, {
            apply: (target, thisArg, args) => {
                args[0](performance.now());
                return 0;
            }
        });
    });

})();