Greasy Fork

Greasy Fork is available in English.

YouTube广告拦截器

优化代码,增强可维护性,无API依赖的极简高效广告拦截方案

目前为 2025-04-01 提交的版本。查看 最新版本

// ==UserScript==
// @name         YouTube广告拦截器
// @namespace    safe-adblock
// @version      4.3
// @match        *://*.youtube.com/*
// @grant        none
// @run-at       document-start
// @description  优化代码,增强可维护性,无API依赖的极简高效广告拦截方案
// ==/UserScript==

(function () {
    'use strict';

    // 广告相关的CSS选择器
    const AD_SELECTORS = [
        'ytd-ad-slot-renderer',
        'div.ytd-promoted-sparkles-web-renderer',
        '[data-ad-metadata]',
        'div#player-ads.ytd-watch:not(#movie_player)',
        'ytd-rich-section-renderer:has(ytd-ad-)',
        'div[class*="-ad-"]:not([data-legitimate])',
        'div.ytp-ad-module'
    ];

    /**
     * 创建状态指示图标
     */
    const createStatusIcon = () => {
        const icon = document.createElement('div');
        icon.innerHTML = `
            <svg style="width:24px;height:24px" viewBox="0 0 24 24">
                <path fill="red" d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z"/>
            </svg>
        `;
        
        icon.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 9999;
            cursor: pointer;
            background: rgba(255,255,255,0.9);
            border-radius: 50%;
            padding: 6px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            transition: transform 0.3s;
        `;

        // 添加点击效果
        icon.addEventListener('click', () => {
            icon.style.transform = 'scale(0.9)';
            setTimeout(() => icon.style.transform = '', 100);
        });

        document.body.appendChild(icon);
    };

    // 原有代码保持不变...
    // [保留之前的 injectStyles、playerProtector、adCleaner 等模块]
    // 只需要在初始化函数中添加 createStatusIcon() 调用

    // 初始化所有模块
    const init = () => {
        injectStyles();
        playerProtector.init();
        adCleaner.init();
        createStatusIcon(); // 新增图标创建
    };

    // 确保DOM加载完毕后执行初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();