// ==UserScript== // @name Bilibili Z键开关中文字幕 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 按Z键直接开关B站AI中文字幕。忽略输入框、编辑区和修饰键输入。 // @author ChatGPT // @match https://www.bilibili.com/video/* // @match https://www.bilibili.com/list/* // @match https://www.bilibili.com/watchroom/* // @match https://player.bilibili.com/player.html* // @match https://live.bilibili.com/* // @grant none // @run-at document-start // ==/UserScript== (function () { 'use strict'; // 检测是否正在输入 function pathIndicatesTyping(path) { if (!path) return false; for (const node of path) { if (!node) continue; const tag = node.tagName ? node.tagName.toUpperCase() : ''; if (tag === 'INPUT' || tag === 'TEXTAREA') return true; if (node.isContentEditable) return true; if (tag === 'BILI-COMMENT-TEXTAREA' || tag === 'BILI-COMMENT') return true; if (node.classList && ( node.classList.contains('bili-comment-textarea__inner') || node.classList.contains('reply-box') || node.classList.contains('editor') )) return true; } return false; } // 安全点击函数:兼容隐藏元素 function simulateClick(el) { if (!el) return false; try { el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, composed: true })); if (typeof el.click === 'function') el.click(); return true; } catch (e) { console.warn('[字幕脚本] simulateClick 失败:', e); return false; } } // 开启中文字幕 function enableChineseSubtitle() { const zhBtn = document.querySelector('.bpx-player-ctrl-subtitle-language-item[data-lan="ai-zh"]'); if (!zhBtn) { console.warn('[字幕脚本] 未找到 ai-zh 按钮,无法开启字幕'); return false; } if (zhBtn.classList.contains('bpx-state-active')) { console.log('[字幕脚本] 中文字幕已处于开启状态'); return true; } const ok = simulateClick(zhBtn); console.log('[字幕脚本] 尝试开启中文字幕 ->', ok ? '已发送点击事件' : '失败'); return ok; } // 关闭中文字幕(仅通过 close 按钮) function disableChineseSubtitle() { const closeSwitch = document.querySelector('.bpx-player-ctrl-subtitle-close-switch[data-action="close"]'); if (!closeSwitch) { console.warn('[字幕脚本] 未找到关闭按钮,无法关闭字幕'); return false; } const ok = simulateClick(closeSwitch); console.log('[字幕脚本] 尝试关闭中文字幕 ->', ok ? '已发送点击事件' : '失败'); return ok; } // 切换逻辑(根据 ai-zh 激活状态判断) function toggleChineseSubtitle() { const zhBtn = document.querySelector('.bpx-player-ctrl-subtitle-language-item[data-lan="ai-zh"]'); if (zhBtn && zhBtn.classList.contains('bpx-state-active')) { disableChineseSubtitle(); } else { enableChineseSubtitle(); } } // 键盘事件监听 document.addEventListener('keydown', function (event) { const key = event.key ? event.key.toLowerCase() : ''; if (key !== 'z') return; // 忽略修饰键 if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; // 忽略输入区 const path = (typeof event.composedPath === 'function' && event.composedPath()) || event.path || [event.target]; if (pathIndicatesTyping(path)) return; const active = document.activeElement; if (active) { const tag = active.tagName ? active.tagName.toUpperCase() : ''; if (tag === 'INPUT' || tag === 'TEXTAREA' || active.isContentEditable) return; if (tag === 'BILI-COMMENT-TEXTAREA' || tag === 'BILI-COMMENT') return; } event.preventDefault(); event.stopPropagation(); toggleChineseSubtitle(); }, true); // 控制台调试提示 new MutationObserver(() => { if (document.querySelector('.bpx-player-ctrl-subtitle-language-item[data-lan="ai-zh"]') || document.querySelector('.bpx-player-ctrl-subtitle-close-switch[data-action="close"]')) { console.log('[字幕脚本] 🎯 检测到字幕控件已存在(可隐藏)'); } }).observe(document.body || document.documentElement, { childList: true, subtree: true }); })();