【油猴脚本】抖音网页直播间自动关闭送礼信息、福袋口令、屏蔽礼物特效
| 原因 事情是这样的...抖音网页直播进入直播间后 送礼信息、福袋口令、礼物特效 都很影响观看直播效果,然后大佬出手搞定了它 废话不多说了 直接上代码 也有 @Zker(The-rapist) 大佬协助 效果预览图 进入直播间后会自动点击,然后关闭悬浮窗... 快去试试吧. 代码 // ==UserScript==// @name 抖音直播自动设置// @namespace https://live.douyin.com/660292215268// @version 1.0// @description 自动关闭送礼信息、福袋口令和礼物特效// @author By Zker(The-rapist)、anwen// @match *://*.douyin.com/*// @icon https://lf3-static.bytednsdoc.com/obj/eden-cn/666eh7nuhfvhpebd/douyin_web/douyin_web/pwa_v3/512_512.png// @grant none// ==/UserScript==(function() { 'use strict'; console.log('[抖音直播自动设置] 脚本已加载'); // 等待页面完全加载 function waitForPageLoad() { return new Promise((resolve) => { if (document.readyState === 'complete') { resolve(); } else { window.addEventListener('load', resolve); } }); } // 等待元素出现 function waitForElement(selector, timeout = 120000) { return new Promise((resolve, reject) => { console.log(`[等待元素] 查找: ${selector}`); const element = document.querySelector(selector); if (element) { console.log(`[等待元素] 立即找到: ${selector}`); resolve(element); return; } const observer = new MutationObserver((mutations, obs) => { const element = document.querySelector(selector); if (element) { console.log(`[等待元素] 观察到: ${selector}`); obs.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => { observer.disconnect(); reject(new Error(`等待元素超时: ${selector}`)); }, timeout); }); } // 模拟 React 悬浮事件 function hoverReactElement(element) { console.log('[悬浮元素]', element); // 触发 React 能够监听的悬浮相关事件 const hoverEvents = [ 'mouseenter', // 鼠标进入元素 'mouseover', // 鼠标移动到元素上(冒泡) 'mousemove' // 鼠标在元素上移动 ]; hoverEvents.forEach(eventType => { const event = new MouseEvent(eventType, { view: window, bubbles: true, cancelable: true, clientX: 0, clientY: 0, buttons: 0 // 没有按钮按下 }); element.dispatchEvent(event); }); // 也触发 pointer 悬浮事件 const pointerHoverEvents = ['pointerenter', 'pointerover', 'pointermove']; pointerHoverEvents.forEach(eventType => { const event = new PointerEvent(eventType, { view: window, bubbles: true, cancelable: true, isPrimary: true, clientX: 0, clientY: 0, buttons: 0 // 没有按钮按下 }); element.dispatchEvent(event); }); } // 移除悬浮状态 function unhoverReactElement(element) { console.log('[移除悬浮]', element); // 触发鼠标离开事件 const leaveEvents = [ 'mouseleave', // 鼠标离开元素 'mouseout' // 鼠标移出元素(冒泡) ]; leaveEvents.forEach(eventType => { const event = new MouseEvent(eventType, { view: window, bubbles: true, cancelable: true, clientX: 0, clientY: 0, buttons: 0 }); element.dispatchEvent(event); }); // 也触发 pointer 离开事件 const pointerLeaveEvents = ['pointerleave', 'pointerout']; pointerLeaveEvents.forEach(eventType => { const event = new PointerEvent(eventType, { view: window, bubbles: true, cancelable: true, isPrimary: true, clientX: 0, clientY: 0, buttons: 0 }); element.dispatchEvent(event); }); } // 模拟 React 点击事件 function clickReactElement(element) { console.log('[点击元素]', element); // 触发多种事件以确保 React 能够捕获 const events = ['mousedown', 'mouseup', 'click']; events.forEach(eventType => { const event = new MouseEvent(eventType, { view: window, bubbles: true, cancelable: true, buttons: 1 }); element.dispatchEvent(event); }); // 也尝试触发 pointer 事件 const pointerEvents = ['pointerdown', 'pointerup']; pointerEvents.forEach(eventType => { const event = new PointerEvent(eventType, { view: window, bubbles: true, cancelable: true, isPrimary: true }); element.dispatchEvent(event); }); } // 等待一段时间 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 查找并关闭开关 async function toggleOffSwitches() { try { console.log('[关闭开关] 开始查找送礼信息和福袋口令的开关'); // 等待设置面板出现 await sleep(10); // 查找所有包含开关的容器 const allContainers = document.querySelectorAll('.R8qN4fs1'); console.log(`[关闭开关] 找到 ${allContainers.length} 个容器`); // 遍历所有容器,查找包含"送礼信息"和"福袋口令"的容器 for (const container of allContainers) { const textContent = container.textContent || ''; // 如果容器包含"送礼信息"或"福袋口令"文字 if (textContent.includes('送礼信息') || textContent.includes('福袋口令')) { console.log('[关闭开关] 找到包含送礼信息/福袋口令的容器'); // 查找该容器内的所有行 const rows = container.querySelectorAll('.tvFMszYY'); for (const row of rows) { const rowText = row.textContent || ''; // 只处理"送礼信息"和"福袋口令"这两行 if (rowText.includes('送礼信息') || rowText.includes('福袋口令')) { console.log(`[关闭开关] 处理: ${rowText.includes('送礼信息') ? '送礼信息' : '福袋口令'}`); // 查找该行内的开关 const switchElement = row.querySelector('.dNuSIvAp.SpsbqNUm.cA0AmKoK'); if (switchElement) { // 检查开关是否已经关闭(通过检查是否有 cA0AmKoK 类) // cA0AmKoK 表示开关是开启的状态 const isOn = switchElement.classList.contains('cA0AmKoK'); console.log(`[关闭开关] ${rowText.includes('送礼信息') ? '送礼信息' : '福袋口令'} 状态: ${isOn ? '开启' : '关闭'}`); // 如果开关是开启状态,点击关闭 if (isOn) { console.log(`[关闭开关] 点击关闭 ${rowText.includes('送礼信息') ? '送礼信息' : '福袋口令'}`); clickReactElement(switchElement); await sleep(10); } } else { console.error('[关闭开关] 未找到开关元素'); } } } } } console.log('[关闭开关] 送礼信息和福袋口令处理完成'); return true; } catch (error) { console.error('[关闭开关] 操作失败:', error); return false; } } // 主执行流程 async function main() { try { console.log('[主流程] 等待页面加载完成...'); await waitForPageLoad(); console.log('[主流程] 页面已加载'); // 等待额外的时间确保所有元素都渲染完成 await sleep(10); // 步骤1: 悬浮弹幕设置图标 console.log('[步骤1] 查找弹幕设置图标...'); const danmakuIcon = await waitForElement('div[data-e2e="danmaku-setting-icon"]'); if (danmakuIcon) { console.log('[步骤1] 找到弹幕设置图标,准备悬浮'); hoverReactElement(danmakuIcon); console.log('[步骤1] 已悬浮弹幕设置图标'); } else { console.error('[步骤1] 未找到弹幕设置图标'); return; } // 等待设置面板打开 await sleep(10); // 步骤2: 关闭送礼信息和福袋口令 console.log('[步骤2] 开始关闭送礼信息和福袋口令...'); await toggleOffSwitches(); // 等待一下 await sleep(10); // 步骤3: 悬浮礼物设置图标 console.log('[步骤3] 查找礼物设置图标...'); const giftIcon = await waitForElement('div[data-e2e="gift-setting"]'); if (giftIcon) { console.log('[步骤3] 找到礼物设置图标,准备悬浮'); hoverReactElement(giftIcon); console.log('[步骤3] 已悬浮礼物设置图标'); } else { console.error('[步骤3] 未找到礼物设置图标'); return; } // 等待礼物设置面板打开 await sleep(10); // 步骤4: 开启"屏蔽礼物特效" console.log('[步骤4] 开始开启屏蔽礼物特效...'); // 等待礼物设置面板完全加载 await sleep(10); // 直接通过 data-e2e 属性查找屏蔽礼物特效开关 const effectSwitch = await waitForElement('div[data-e2e="effect-switch"]'); if (effectSwitch) { console.log('[步骤4] 找到屏蔽礼物特效开关'); // 查找开关元素 const switchElement = effectSwitch.querySelector('.dNuSIvAp.EkEDO2Hs'); if (switchElement) { // 检查开关是否已经开启(根据你提供的HTML,关闭状态是 EkEDO2Hs,开启状态应该有额外的类) // 我们需要检查是否有 cA0AmKoK 类或其他表示开启的类 const isOn = switchElement.classList.contains('cA0AmKoK') || switchElement.querySelector('.Cri3cNdU.gDrxzyfK') !== null; console.log(`[步骤4] 屏蔽礼物特效 状态: ${isOn ? '开启' : '关闭'}`); // 如果开关是关闭状态,点击开启 if (!isOn) { console.log('[步骤4] 点击开启 屏蔽礼物特效'); clickReactElement(switchElement); await sleep(10); } else { console.log('[步骤4] 屏蔽礼物特效 已经是开启状态,无需操作'); } } else { console.error('[步骤4] 未找到屏蔽礼物特效开关元素'); } } else { console.error('[步骤4] 未找到屏蔽礼物特效开关容器'); } // 步骤5: 移除所有悬浮状态 console.log('[步骤5] 开始移除悬浮状态...'); await sleep(10); // 移除礼物设置图标的悬浮状态 if (giftIcon) { console.log('[步骤5] 移除礼物设置图标悬浮状态'); unhoverReactElement(giftIcon); } await sleep(10); // 移除弹幕设置图标的悬浮状态 if (danmakuIcon) { console.log('[步骤5] 移除弹幕设置图标悬浮状态'); unhoverReactElement(danmakuIcon); } console.log('[主流程] ✅ 所有设置已完成'); } catch (error) { console.error('[主流程] 执行出错:', error); } } // 启动脚本 console.log('[抖音直播自动设置] 准备执行主流程...'); main();})();复制代码结语&添加也欢迎大佬优化的更好一些 嘿嘿~ 有需要的自取吧添加方式也简单,新建然后复制代码进去 Ctrl+S 保存就好 ![]() |



