您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Hide YouTube homepage videos by blacklisted words in title or channel name
当前为
// ==UserScript== // @name YouTube Keyword Blocker (Whole‑Word Mode) // @description Hide YouTube homepage videos by blacklisted words in title or channel name // @match https://www.youtube.com/* // @run-at document-end // @version 0.0.1.20250522140812 // @namespace https://greasyfork.org/users/1435046 // ==/UserScript== (function () { 'use strict'; // skip “results” and “@channel” pages if (location.pathname.startsWith('/results') || location.pathname.startsWith('/@')) return; // 1) List words const terms = [ ]; // 2) Convert to RegExp objects with \b boundaries, case‑insensitive const blacklist = terms.map(term => { const esc = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); return new RegExp(`\\b${esc}\\b`, 'i'); }); const ITEM_SELECTOR = 'ytd-rich-item-renderer'; /*, ytd-rich-grid-media, ytd-video-renderer*/ const TITLE_SELECTOR = '#video-title'; const CHANNEL_SELECTOR = 'ytd-channel-name a'; function filterItem(item) { // skip “results” and “@channel” pages on dynamic loads if (location.pathname.startsWith('/results') || location.pathname.startsWith('/@')) return; // skip if we've already seen this node if (item.dataset.keywordBlocked) return; item.dataset.keywordBlocked = '1'; const linkEl = item.querySelector('a#video-title-link'); const title = linkEl ? linkEl.getAttribute('aria-label').trim() : '‹no title›'; console.log('› filterItem saw:', item.tagName, title); const channelEl = item.querySelector(CHANNEL_SELECTOR); const channel = channelEl ? channelEl.textContent.trim() : ''; for (const re of blacklist) { if (re.test(title) || re.test(channel)) { console.log( `Blocking video:\n` + ` title: "${title}"\n` + ` channel: "${channel}"\n` + ` matched: ${re}` ); item.style.display = 'none'; return; } } } function scanPage() { // skip “results” and “@channel” pages on every scan if (location.pathname.startsWith('/results') || location.pathname.startsWith('/@')) return; document.querySelectorAll(ITEM_SELECTOR).forEach(filterItem); } new MutationObserver(mutations => { for (const { addedNodes } of mutations) { for (const node of addedNodes) { if (!(node instanceof HTMLElement)) continue; if (node.matches(ITEM_SELECTOR)) filterItem(node); else node.querySelectorAll && node.querySelectorAll(ITEM_SELECTOR).forEach(filterItem); } } }).observe(document.body, { childList: true, subtree: true }); scanPage(); window.addEventListener('yt-navigate-finish', scanPage); })();