// ==UserScript== // @name DY直播讲解按钮自动监控(精确版) // @namespace http://tampermonkey.net/ // @version 1.0 // @description 根据DOM结构精确监控讲解按钮 // @author 助手 // @match https://eos.douyin.com/livesite/live/current // @grant none // @run-at document-idle // ==/UserScript== (function() { 'use strict'; console.log('🎯 抖音直播讲解按钮监控脚本加载'); class TalkingButtonMonitor { constructor() { this.config = { checkInterval: 1000, debug: true }; this.isMonitoring = false; this.monitorTimer = null; this.lastState = null; this.waitingTimer = null; this.init(); } log(message) { if (this.config.debug) { console.log(`[直播监控] ${new Date().toLocaleTimeString()} ${message}`); } } // 根据图片中的DOM结构精确查找按钮 findButton() { // 方法1: 按照图片中的DOM层级查找 const selectors = [ // 图片中的精确路径 '.operate-area-LOr1qx .talking-btn-XzVTUV .talking-word-S8p5x6', // 更通用的选择器 '.talking-word-S8p5x6', '[class*="talking-word-"]', '.talking-btn-XzVTUV', '[class*="talking-btn-"]', // 通过文字查找 'div:contains("取消讲解")', 'div:contains("讲解")', 'span:contains("讲解")' ]; for (const selector of selectors) { try { const element = document.querySelector(selector); if (element) { const text = this.getButtonText(element); if (text && (text.includes('讲解') || text.includes('取消'))) { // 找到按钮元素 let button = element; // 如果当前是文字元素,向上查找按钮 if (!button.classList || (!button.classList.contains('talking-btn') && !button.className.includes('talking-btn'))) { button = button.closest('[class*="talking-btn"]') || button.closest('button') || button.closest('div[role="button"]') || button.parentElement; } return { element: button, text: text.trim(), selector: selector }; } } } catch (e) { continue; } } return null; } getButtonText(element) { if (!element) return ''; // 直接获取文本 const text = element.textContent || element.innerText || ''; // 如果当前元素没有文本,检查子元素 if (!text.trim() && element.children.length > 0) { for (const child of element.children) { const childText = this.getButtonText(child); if (childText.trim()) { return childText; } } } return text.trim(); } handleButton(buttonInfo) { if (!buttonInfo) return; const { element, text } = buttonInfo; const currentState = text; // 如果状态没变化,不做处理 if (currentState === this.lastState) { return; } this.log(`按钮状态变化: ${this.lastState || '无'} -> ${currentState}`); this.lastState = currentState; // 清除之前的等待计时器 if (this.waitingTimer) { clearTimeout(this.waitingTimer); this.waitingTimer = null; } // 根据按钮文字执行不同操作 if (currentState === '讲解') { this.log('检测到"讲解"按钮,立即点击'); this.clickButton(element); } else if (currentState === '取消讲解') { this.log('检测到"取消讲解"按钮,等待10秒后点击'); this.waitingTimer = setTimeout(() => { // 10秒后再次确认按钮状态 const currentButton = this.findButton(); if (currentButton && currentButton.text === '取消讲解') { this.log('10秒后点击"取消讲解"按钮'); this.clickButton(currentButton.element); } else { this.log('10秒后按钮状态已变化,取消点击'); } this.waitingTimer = null; }, 10000); } else { this.log(`未知按钮文字: "${currentState}",忽略`); } } clickButton(element) { if (!element) { this.log('错误: 按钮元素不存在'); return false; } try { this.log(`准备点击按钮: ${this.getButtonText(element)}`); // 模拟完整点击事件 ['mousedown', 'mouseup', 'click'].forEach(eventType => { element.dispatchEvent(new MouseEvent(eventType, { bubbles: true, cancelable: true, view: window })); }); // 触发实际点击 element.click(); this.log('点击成功'); return true; } catch (error) { this.log(`点击失败: ${error.message}`, 'error'); return false; } } checkLoop() { if (!this.isMonitoring) return; const buttonInfo = this.findButton(); if (buttonInfo) { this.handleButton(buttonInfo); } else { this.log('未找到讲解按钮'); } } startMonitoring() { if (this.isMonitoring) { this.log('监控已在运行中'); return; } this.log('🚀 开始监控讲解按钮'); this.isMonitoring = true; this.lastState = null; // 立即检查一次 this.checkLoop(); // 设置定时检查 this.monitorTimer = setInterval(() => { this.checkLoop(); }, this.config.checkInterval); } stopMonitoring() { this.log('⏸️ 停止监控'); this.isMonitoring = false; if (this.monitorTimer) { clearInterval(this.monitorTimer); this.monitorTimer = null; } if (this.waitingTimer) { clearTimeout(this.waitingTimer); this.waitingTimer = null; } } addControlPanel() { // 移除已存在的控制面板 const existingPanel = document.getElementById('talking-monitor-panel'); if (existingPanel) { existingPanel.remove(); } // 创建控制面板 const panel = document.createElement('div'); panel.id = 'talking-monitor-panel'; panel.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 10000; background: white; border-radius: 8px; box-shadow: 0 2px 20px rgba(0,0,0,0.1); padding: 15px; min-width: 220px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; border: 1px solid #e0e0e0; `; // 标题 const title = document.createElement('div'); title.innerHTML = '