// ==UserScript== // @name YouTube广告拦截器 // @namespace safe-adblock // @version 4.2 // @match *://*.youtube.com/* // @grant none // @run-at document-start // @description 优化代码,增强可维护性,无API依赖的极简高效广告拦截方案 // @downloadURL none // ==/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 injectStyles = () => { const styleContent = ` /* 广告隐藏规则 */ ${AD_SELECTORS.join(', ')} { transform: scale(0) !important; height: 0 !important; width: 0 !important; opacity: 0 !important; pointer-events: none !important; position: absolute !important; z-index: -1 !important; } /* 播放器核心保护规则 */ #movie_player, .html5-video-player { position: static !important; width: 100% !important; height: 0 !important; padding-bottom: 56.25% !important; /* 16:9比例 */ min-height: auto !important; overflow: visible !important; } /* 视频自适应容器 */ .html5-video-container { position: absolute !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; } /* 修复全屏显示 */ .ytp-fullscreen #movie_player { padding-bottom: 0 !important; height: 100vh !important; } /* 防止推荐栏重叠 */ ytd-watch-flexy[theater] #secondary.ytd-watch-flexy { margin-top: 60px !important; z-index: 500 !important; } `; const styleElement = document.createElement('style'); styleElement.textContent = styleContent; document.head.appendChild(styleElement); }; /** * 播放器保护模块 */ const playerProtector = { observer: null, init() { this.observePlayerSize(); this.patchFullscreenAPI(); }, /** * 使用 ResizeObserver 监听播放器大小变化 */ observePlayerSize() { this.observer = new ResizeObserver(entries => { entries.forEach(entry => { const video = entry.target.querySelector('video'); if (video) { this.adjustVideoSize(video); } }); }); const checkAndObservePlayer = () => { const player = document.getElementById('movie_player'); if (player && !player.hasAttribute('data-observed')) { player.setAttribute('data-observed', 'true'); this.observer.observe(player); const video = player.querySelector('video'); if (video) { this.adjustVideoSize(video); } } }; // 初次检查和定时检查 checkAndObservePlayer(); setInterval(checkAndObservePlayer, 3000); }, /** * 调整视频与容器尺寸 * @param {HTMLVideoElement} video */ adjustVideoSize(video) { const container = video.closest('.html5-video-container'); if (container) { container.style.cssText = ` width: 100% !important; height: 100% !important; overflow: hidden !important; `; } video.style.cssText = ` width: 100% !important; height: 100% !important; object-fit: contain !important; `; }, /** * 修改全屏API使播放器在全屏时正常显示 */ patchFullscreenAPI() { const originalRequestFullscreen = Element.prototype.requestFullscreen; Element.prototype.requestFullscreen = function() { const player = document.getElementById('movie_player'); if (player && player.contains(this)) { player.style.paddingBottom = '0'; player.style.height = '100vh'; } return originalRequestFullscreen.apply(this, arguments); }; } }; /** * 广告清理模块,使用 MutationObserver 动态移除广告元素 */ const adCleaner = { observer: null, init() { this.observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { this.cleanAds(node); } }); }); }); this.observer.observe(document, { childList: true, subtree: true }); }, /** * 清理指定节点下的广告元素 * @param {HTMLElement} root */ cleanAds(root) { AD_SELECTORS.forEach(selector => { const ads = root.querySelectorAll(selector); ads.forEach(ad => { // 移除子节点并隐藏元素 ad.replaceChildren(); ad.style.cssText = 'display: none !important'; }); }); } }; // 初始化所有模块 const init = () => { injectStyles(); playerProtector.init(); adCleaner.init(); }; // 确保DOM加载完毕后执行初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();