您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Bypasses YouTube content warning on possibly unsafe content.
// ==UserScript== // @name YTCWBypass // @namespace http://tampermonkey.net/ // @version 3.0 // @description Bypasses YouTube content warning on possibly unsafe content. // @author Dormy // @match *://www.youtube.com/* // @icon https://www.google.com/s2/favicons?domain=youtube.com // @license MIT // @grant GM_getValue // @grant GM_setValue // @grant unsafeWindow // ==/UserScript== (async function() { 'use strict'; const SKIPPER_STATE_KEY = 'yt-bypass-enabled-state'; const TOGGLE_BUTTON_ID = 'yt-bypass-toggle-button'; let isBypassEnabled = true; function performMultiProngedClick(element) { try { element.focus(); element.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })); } catch (e) { /* Silently fail */ } try { element.click(); } catch (e) { /* Silently fail */ } try { const eventInit = { bubbles: true, cancelable: true, view: unsafeWindow }; element.dispatchEvent(new MouseEvent('mousedown', eventInit)); element.dispatchEvent(new MouseEvent('mouseup', eventInit)); element.dispatchEvent(new MouseEvent('click', eventInit)); } catch (e) { /* Silently fail */ } } /** * Finds and clicks the warning button if it's visible. * @returns {boolean} - True if the button was found and clicked, otherwise false. */ function findAndClickWarningButton() { const buttonIdentifiers = ["I understand and wish to proceed", "Continue"]; for (const text of buttonIdentifiers) { const xpath = `(//button | //*[@role="button"] | //yt-button-shape | //yt-button-renderer)[contains(., "${text}") or @aria-label="${text}"]`; const result = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); const container = result.singleNodeValue; if (container && container.offsetParent !== null) { const elementToClick = container.querySelector('button') || container; performMultiProngedClick(elementToClick); return true; // Success } } return false; // Not found } /** * Starts a polling process that checks for the warning button every 500ms for 15 seconds. */ function attemptBypassWithPolling() { if (!isBypassEnabled) return; const intervalId = setInterval(() => { if (findAndClickWarningButton()) { clearInterval(intervalId); // Stop polling on success } }, 500); // Check every half-second setTimeout(() => { clearInterval(intervalId); // Stop polling after 15 seconds }, 15000); } function updateButtonAppearance() { const button = document.getElementById(TOGGLE_BUTTON_ID); if (!button) return; const textElement = button.querySelector('.ytcwb-text'); if (textElement) { textElement.style.color = isBypassEnabled ? '#2ecc71' : '#e74c3c'; } } async function toggleBypassState() { isBypassEnabled = !isBypassEnabled; await GM_setValue(SKIPPER_STATE_KEY, isBypassEnabled); updateButtonAppearance(); // --- NEW: Trigger the bypass action immediately when toggled on --- if (isBypassEnabled) { attemptBypassWithPolling(); } } function injectHeaderButton() { if (document.getElementById(TOGGLE_BUTTON_ID)) return; const buttonsContainer = document.querySelector('ytd-masthead #end #buttons'); if (!buttonsContainer) return; const buttonWrapper = document.createElement('div'); buttonWrapper.id = TOGGLE_BUTTON_ID; buttonWrapper.style.marginRight = '15px'; const buttonEl = document.createElement('button'); Object.assign(buttonEl.style, { width: '36px', height: '36px', borderRadius: '50%', border: 'none', padding: '0', backgroundColor: '#212121', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }); buttonEl.onmouseover = () => buttonEl.style.backgroundColor = '#3d3d3d'; buttonEl.onmouseout = () => buttonEl.style.backgroundColor = '#212121'; const textElement = document.createElement('div'); textElement.textContent = 'YTCW'; textElement.className = 'ytcwb-text'; Object.assign(textElement.style, { fontFamily: 'Roboto, Arial, sans-serif', fontSize: '11px', fontWeight: 'bold', lineHeight: 'normal', pointerEvents: 'none' }); buttonEl.appendChild(textElement); buttonWrapper.appendChild(buttonEl); buttonEl.setAttribute('aria-label', 'Toggle YTCWBypass'); buttonEl.addEventListener('click', toggleBypassState); buttonsContainer.insertBefore(buttonWrapper, buttonsContainer.firstChild); updateButtonAppearance(); } async function initialize() { isBypassEnabled = await GM_getValue(SKIPPER_STATE_KEY, true); // --- NEW: Start the initial bypass attempt on page load --- attemptBypassWithPolling(); // The observer is now ONLY for injecting the button when the header changes const uiObserver = new MutationObserver(() => injectHeaderButton()); uiObserver.observe(document.body, { childList: true, subtree: true }); } initialize(); })();