您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Hides all videos except those with Russian characters in the title, and also hides the Shorts shelf. Remembers toggle state.
// ==UserScript== // @name YouTube Russian Language and Shorts Filter // @namespace http://tampermonkey.net/ // @version 6.0 // @description Hides all videos except those with Russian characters in the title, and also hides the Shorts shelf. Remembers toggle state. // @description:ru Скрывает все видео, кроме тех, в названии которых есть русские буквы, а также скрывает полку с шортсами. Запоминает состояние кнопки. // @author torch // @match https://www.youtube.com/* // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @license MIT // ==/UserScript== (function() { 'use strict'; // --- SETTINGS --- // Load the saved state. If nothing is saved, it defaults to 'true' (enabled). let isScriptEnabled = GM_getValue('isRussianFilterEnabled', true); // The regular expression to test for any Russian (Cyrillic) characters. const russianRegex = /[а-яА-ЯёЁ]/; // --- SCRIPT LOGIC --- function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function clickNotInterested(videoElement, titleText) { const menuButton = videoElement.querySelector('button[aria-label="Ещё"], button[aria-label="Action menu"]'); if (!menuButton) return; menuButton.click(); await sleep(200); // Wait for menu to appear const menuItems = document.querySelectorAll('ytd-menu-service-item-renderer, yt-list-item-view-model'); for (const item of menuItems) { const textElement = item.querySelector('yt-formatted-string, .yt-core-attributed-string'); if (textElement && (textElement.textContent.trim() === 'Не интересует' || textElement.textContent.trim() === 'Not interested')) { item.click(); console.log(`[Russian Filter] Clicked "Not interested" for: "${titleText}"`); return; } } // Click body to close the menu if the option wasn't found document.body.click(); } async function processVideo(videoElement) { // Stop if the script is disabled or if this video has already been checked if (videoElement.getAttribute('data-processed-russian-filter') === 'true' || !isScriptEnabled) { return; } videoElement.setAttribute('data-processed-russian-filter', 'true'); const titleLink = videoElement.querySelector('a#video-title, .yt-lockup-metadata-view-model-wiz__title'); if (!titleLink) return; const titleText = (titleLink.getAttribute('title') || titleLink.textContent).trim(); // *** CORE LOGIC CHANGE *** // Test if the title contains any Russian characters using the regular expression. const hasRussianChars = russianRegex.test(titleText); if (hasRussianChars) { // If the title has Russian characters, keep it and highlight it. console.log(`[Russian Filter] KEEPING: "${titleText}"`); videoElement.style.outline = '2px solid limegreen'; return; } // Otherwise, hide the video. console.log(`[Russian Filter] HIDING: "${titleText}"`); videoElement.style.display = 'none'; clickNotInterested(videoElement, titleText); } /** * Finds and hides the YouTube Shorts shelf. */ function hideShortsShelf() { if (!isScriptEnabled) return; const shelves = document.querySelectorAll('ytd-rich-shelf-renderer'); shelves.forEach(shelf => { const titleElement = shelf.querySelector('#title.style-scope.ytd-rich-shelf-renderer'); if (titleElement && titleElement.textContent.trim() === 'Shorts') { if (shelf.style.display !== 'none') { console.log('[Russian Filter] HIDING: Shorts shelf'); shelf.style.display = 'none'; // Mark it as processed to easily find and restore it later shelf.setAttribute('data-processed-shorts-filter', 'true'); } } }); } function processAllVisibleVideos() { if (!isScriptEnabled) return; console.log('[Russian Filter] Processing visible items...'); // Hide Shorts shelf first hideShortsShelf(); // Then process individual videos document.querySelectorAll('ytd-rich-item-renderer:not([data-processed-russian-filter]), ytd-video-renderer:not([data-processed-russian-filter]), ytd-grid-video-renderer:not([data-processed-russian-filter]), ytd-compact-video-renderer:not([data-processed-russian-filter])').forEach(processVideo); } // This observer watches for new videos being loaded on the page (e.g., infinite scroll) const observer = new MutationObserver(() => { if (!isScriptEnabled) return; processAllVisibleVideos(); }); // --- UI ELEMENTS --- function createToggleButton() { const button = document.createElement('button'); button.id = 'russian-filter-toggle'; document.body.appendChild(button); button.addEventListener('click', () => { isScriptEnabled = !isScriptEnabled; // Save the new state to memory so it persists across page loads GM_setValue('isRussianFilterEnabled', isScriptEnabled); updateButtonState(button); if (isScriptEnabled) { // If turning on, process all videos immediately. processAllVisibleVideos(); } else { // If turning off, un-hide all previously hidden videos and shelves. document.querySelectorAll('[data-processed-russian-filter]').forEach(el => { if (el.style.display === 'none') { // Reset the display property to its default value el.style.display = ''; } el.style.outline = 'none'; // Remove the green outline }); // Also un-hide the shorts shelf document.querySelectorAll('[data-processed-shorts-filter]').forEach(el => { el.style.display = ''; }); } }); updateButtonState(button); } function updateButtonState(button) { button.textContent = isScriptEnabled ? 'Filter: ON' : 'Filter: OFF'; button.className = isScriptEnabled ? 'enabled' : 'disabled'; } GM_addStyle(` #russian-filter-toggle { position: fixed; bottom: 20px; left: 20px; z-index: 9999; padding: 10px 15px; border-radius: 8px; border: none; color: white; font-size: 14px; font-weight: bold; cursor: pointer; box-shadow: 0 4px 8px rgba(0,0,0,0.2); transition: background-color 0.3s, transform 0.2s; } #russian-filter-toggle.enabled { background-color: #1a73e8; } #russian-filter-toggle.disabled { background-color: #d93025; } #russian-filter-toggle:hover { transform: scale(1.05); } `); // --- STARTUP --- function startObserver() { const targetNode = document.querySelector('ytd-app'); if (targetNode) { console.log('[Russian Filter] Script started. Observer activated.'); observer.observe(targetNode, { childList: true, subtree: true }); createToggleButton(); if (isScriptEnabled) { // Give the page a moment to load initial content before the first run. setTimeout(processAllVisibleVideos, 1500); } } else { // If the main app element isn't ready, wait and try again. setTimeout(startObserver, 1000); } } startObserver(); })();