几年的产品了连这个都没做?豆包前端是不是自己不用?程序员自己没需求吗?
// ==UserScript==
// @name 豆包网页暗色自适应增强
// @namespace https://tampermonkey.custom.local
// @version 1.0.2
// @description 网页端豆包全局暗色适配,修复SVG图标、代码悬浮弹窗反色模糊,右上角固定切换按钮,低性能占用
// @author cmd137
// @match *://doubao.com/*
// @match *://*.doubao.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const STORAGE_KEY = 'doubao_dark_mode_state';
let domWatcher = null;
let themeSwitchBtn = null;
// 全局修复页面媒体、图标、弹窗控件
function repairAllVisualElements() {
// 图片、头像、截图资源修复
const imageElements = document.querySelectorAll(
'img, video, iframe, .emoji, .code-img, .avatar, .chat-image, .icon-img'
);
imageElements.forEach(el => {
el.style.filter = "invert(1) hue-rotate(180deg)";
});
// 全部SVG矢量图标深度修复
const allSvgIcons = document.querySelectorAll('svg, svg *');
allSvgIcons.forEach(el => {
el.style.filter = "invert(1) hue-rotate(180deg)";
});
// 悬浮气泡、右键弹窗、代码操作浮层
const popTooltipLayers = document.querySelectorAll(
'[role="tooltip"], [role="menu"], .tooltip, .popup, .code-pop, [data-popup]'
);
popTooltipLayers.forEach(el => {
el.style.filter = "invert(1) hue-rotate(180deg)";
});
// 底部输入栏、代码底部操作容器
const bottomControlAreas = document.querySelectorAll('.chat-bottom-bar, .code-footer, .code-action');
bottomControlAreas.forEach(el => {
el.style.filter = "invert(1) hue-rotate(180deg)";
});
}
// 清空所有自定义滤镜,切回浅色模式
function clearAllCustomFilter() {
const imageElements = document.querySelectorAll(
'img, video, iframe, .emoji, .code-img, .avatar, .chat-image, .icon-img'
);
imageElements.forEach(el => el.style.filter = "");
const allSvgIcons = document.querySelectorAll('svg, svg *');
allSvgIcons.forEach(el => el.style.filter = "");
const popTooltipLayers = document.querySelectorAll(
'[role="tooltip"], [role="menu"], .tooltip, .popup, .code-pop, [data-popup]'
);
popTooltipLayers.forEach(el => el.style.filter = "");
const bottomControlAreas = document.querySelectorAll('.chat-bottom-bar, .code-footer, .code-action');
bottomControlAreas.forEach(el => el.style.filter = "");
}
// 启动DOM动态监听,自动修复新加载元素
function startDomObserver() {
if (domWatcher) return;
domWatcher = new MutationObserver(() => repairAllVisualElements());
domWatcher.observe(document.body, { childList: true, subtree: true, attributes: true });
}
// 销毁监听释放性能
function stopDomObserver() {
if (domWatcher) {
domWatcher.disconnect();
domWatcher = null;
}
}
// 开启暗色模式
function enableDarkVisual() {
document.documentElement.style.filter = "invert(1) hue-rotate(180deg)";
repairAllVisualElements();
startDomObserver();
localStorage.setItem(STORAGE_KEY, 'dark');
themeSwitchBtn.innerText = '黑夜模式 关';
}
// 关闭暗色模式
function disableDarkVisual() {
document.documentElement.style.filter = "";
clearAllCustomFilter();
stopDomObserver();
localStorage.setItem(STORAGE_KEY, 'light');
themeSwitchBtn.innerText = '黑夜模式 开';
}
// 创建固定位置切换按钮(移除拖拽逻辑,降低性能消耗)
function buildThemeToggleButton() {
themeSwitchBtn = document.createElement('button');
themeSwitchBtn.style.cssText = `
position: fixed; right: 22px; z-index: 9999999;
padding: 7px 14px; border: none; border-radius: 8px;
background: #2c384a; color: #f0f4f9; font-size: 13px; cursor: pointer;
box-shadow: 0 2px 10px rgba(0,0,0,0.35); transition: all 0.25s cubic-bezier(0.2,0,0.2,1);
user-select: none; letter-spacing: 0.3px;
visibility: hidden;
`;
// hover交互渐变
themeSwitchBtn.onmouseover = () => {
themeSwitchBtn.style.background = "#3d4c63";
themeSwitchBtn.style.transform = "translateY(-2px) scale(1.03)";
};
themeSwitchBtn.onmouseout = () => {
themeSwitchBtn.style.background = "#2c384a";
themeSwitchBtn.style.transform = "translateY(0) scale(1)";
};
// 点击切换明暗
themeSwitchBtn.addEventListener('click', () => {
const currentMode = localStorage.getItem(STORAGE_KEY) || 'dark';
currentMode === 'dark' ? disableDarkVisual() : enableDarkVisual();
});
document.body.appendChild(themeSwitchBtn);
// 计算默认top:向下偏移2倍按钮自身高度
const btnHeight = themeSwitchBtn.offsetHeight;
themeSwitchBtn.style.top = `${btnHeight * 6}px`;
themeSwitchBtn.style.visibility = "visible";
}
// 页面初始化入口
function pageInit() {
buildThemeToggleButton();
const savedMode = localStorage.getItem(STORAGE_KEY) || 'dark';
savedMode === 'dark' ? enableDarkVisual() : disableDarkVisual();
}
// 等待页面DOM加载完成再初始化,减少闪烁
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", pageInit);
} else {
pageInit();
}
// 单页路由跳转自动修复视觉
window.addEventListener('popstate', () => {
const currentMode = localStorage.getItem(STORAGE_KEY) || 'dark';
if (currentMode === 'dark') repairAllVisualElements();
});
})();