前言
事情是这样的…抖音网页直播进入直播间后 送礼信息、福袋口令、礼物特效 都很影响观看直播效果,然后大佬出手搞定了它
废话不多说了 直接上代码 也有 @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 保存就好

© 版权声明
THE END



























暂无评论内容