您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add a Single-click Unsubscribe button for each channel on the YouTube manage subscriptions page
// ==UserScript== // @name YouTube Instant Unsubscribe Button on Manage Subscriptions Page // @namespace http://tampermonkey.net/ // @version 0.9 // @description Add a Single-click Unsubscribe button for each channel on the YouTube manage subscriptions page // @author chrisnt // @match https://www.youtube.com/feed/channels // @grant none // @license GNU GPLv3 // ==/UserScript== (function() { 'use strict'; /** * Simulate a mouse click event on a given element. * @param {HTMLElement} element - The element to be clicked. */ function simulateClick(element) { const event = new MouseEvent('click', { view: window, bubbles: true, cancelable: true, buttons: 1 }); element.dispatchEvent(event); } /** * Hide certain YouTube elements to prevent popups during the unsubscribe process. */ function hideElements() { const style = document.createElement('style'); style.id = 'hide-yt-elements'; style.innerHTML = ` ytd-popup-container, ytd-popup-container *, ytd-menu-popup-renderer, ytd-menu-popup-renderer * { display: none !important; } `; document.head.appendChild(style); } /** * Show the hidden YouTube elements after the unsubscribe process is complete. */ function showElements() { const style = document.getElementById('hide-yt-elements'); if (style) { document.head.removeChild(style); } } /** * Add custom Unsubscribe buttons to each channel renderer on the page. */ function addUnsubscribeButtons() { const channels = document.querySelectorAll('ytd-channel-renderer'); channels.forEach(channel => { if (!channel.querySelector('.custom-unsubscribe-button')) { const unsubscribeButton = document.createElement('button'); unsubscribeButton.className = 'custom-unsubscribe-button'; unsubscribeButton.innerHTML = ` <span style="display: inline-flex; align-items: center; justify-content: center;"> <svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope yt-icon" style="width: 20px; height: 20px; margin-right: 8px; fill: currentColor;"> <g class="style-scope yt-icon"> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z" class="style-scope yt-icon"></path> </g> </svg>Unsubscribe </span>`; // Style the unsubscribe button unsubscribeButton.style.cssText = ` margin-left: 12px; padding: 0 12px; background-color: #FF0000; color: #FFFFFF; border: none; border-radius: 2px; height: 36px; font-size: 14px; font-weight: 500; cursor: pointer; transition: background-color 0.3s ease; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; line-height: 36px; vertical-align: middle; `; // Change background color on hover unsubscribeButton.addEventListener('mouseover', () => { unsubscribeButton.style.backgroundColor = '#CC0000'; }); unsubscribeButton.addEventListener('mouseout', () => { unsubscribeButton.style.backgroundColor = '#FF0000'; }); // Unsubscribe button click event unsubscribeButton.addEventListener('click', () => { hideElements(); const dropdownButton = channel.querySelector("#notification-preference-button > ytd-subscription-notification-toggle-button-renderer-next > yt-button-shape > button > yt-touch-feedback-shape > div > div.yt-spec-touch-feedback-shape__fill"); if (dropdownButton) { simulateClick(dropdownButton); setTimeout(() => { const unsubscribeButton = document.querySelector("#items > ytd-menu-service-item-renderer:nth-child(4) > tp-yt-paper-item > yt-formatted-string"); if (unsubscribeButton) { simulateClick(unsubscribeButton); setTimeout(() => { const confirmButton = document.querySelector("#confirm-button > yt-button-shape > button > yt-touch-feedback-shape > div > div.yt-spec-touch-feedback-shape__fill"); if (confirmButton) { simulateClick(confirmButton); setTimeout(showElements, 100); } else { showElements(); } }, 100); } else { showElements(); } }, 100); } else { showElements(); } }); const actionButtons = channel.querySelector('#buttons'); if (actionButtons) { actionButtons.appendChild(unsubscribeButton); } } }); } addUnsubscribeButtons(); // Observe for new channel elements and add unsubscribe buttons dynamically const observer = new MutationObserver(addUnsubscribeButtons); const pageManager = document.querySelector('ytd-page-manager'); if (pageManager) { observer.observe(pageManager, { childList: true, subtree: true }); } else { console.error('YouTube page manager not found'); } })();