可能是更优雅的知乎网页版暗黑模式 - Zhihu Dark Mode

知乎网页版的暗黑模式就写了一半,我帮它尽量写完

// ==UserScript==
// @name         可能是更优雅的知乎网页版暗黑模式 - Zhihu Dark Mode
// @version      0.1.13
// @description  知乎网页版的暗黑模式就写了一半,我帮它尽量写完
// @author       ByronLeeeee
// @match        *://*.zhihu.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// @namespace https://github.com/ByronLeeeee/Zhihu-Dark-Mode
// ==/UserScript==

(function () {
    'use strict';

    // 检查用户保存的深色模式偏好
    const isDark = localStorage.getItem('zhihu-dark-mode') === 'true';

    // 在页面解析之前设置初始主题,避免白屏
    document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');

    // 在页面解析前注入CSS样式
    const style = document.createElement('style');
    style.textContent = `
        /* 悬浮效果 */
        button:hover {
            opacity: 0.8;
            transform: scale(1.1);
            transition: all 0.2s ease;
        }

        /* 顶部导航栏 (banner) */
        [data-theme="dark"] .AppHeader,
        [data-theme="dark"] header[role="banner"],
        [data-theme="dark"] .ColumnPageHeader,
        [data-theme="dark"] .css-1ppjin3,
        [data-theme="dark"] .css-nbr1cj,
        [data-theme="dark"] .css-2lvw8d{
            background-color: var(--header-bg) !important;
            border-bottom: 1px solid var(--border-color) !important;
            --header-bg: #191b1f;
            --border-color: #404040;
        }

        /* 想法编辑区 */
        [data-theme="dark"] .css-odpg9,
        [data-theme="dark"] .css-tl7t4z{
        background-color: #191b1f !important;
        color: #b0b0b0 !important;
        }

        /* 导航栏内的文字和链接 */
        [data-theme="dark"] .Tabs-link {
            color: #b0b0b0 !important;
        }

        [data-theme="dark"] .Tabs-link.is-active {
            color: #ffffff !important;
        }

        /* 搜索框 */
        [data-theme="dark"] .SearchBar-input {
            background-color: #333333 !important;
            color: #b0b0b0 !important;
            border: 1px solid var(--border-color) !important;
        }

        /* 移除消息、私信、创作中心按钮的边框 */
        [data-theme="dark"] .AppHeader-notifications,
        [data-theme="dark"] .AppHeader-messages,
        [data-theme="dark"] .css-18vqx7l .Button {
            border: none !important;
            background-color: var(--header-bg) !important;
            color: #b0b0b0 !important;
        }

        /* SVG 图标颜色 */
        [data-theme="dark"] .ZDI {
            fill: #b0b0b0 !important;
        }

        /* logo 调整(保持可见性) */
        [data-theme="dark"] .css-1hlrcxk {
            filter: brightness(0) invert(1) !important;
        }

        /* 用户头像边框 */
        [data-theme="dark"] .AppHeader-profileAvatar {
            border: 1px solid var(--border-color) !important;
        }

        /* 正文标题颜色调整 */
        [data-theme="dark"] h1,
        [data-theme="dark"] .ContentItem-title,
        [data-theme="dark"] .QuestionHeader-title {
            color: #d3d3d3 !important;
        }

        /* 常见深色背景浅色字 */
        [data-theme="dark"] .css-nomdw0,
        [data-theme="dark"] .css-i9ss08,
        [data-theme="dark"] .css-1nr5ql7,
        [data-theme="dark"] .css-157mis2,
        [data-theme="dark"] .css-7hb6gj,
        [data-theme="dark"] .css-1mbpn2d,
        [data-theme="dark"] .css-1yjqd5z,
        [data-theme="dark"] .css-12lqyc0,
        [data-theme="dark"] .css-35pmty,
        [data-theme="dark"] .css-1t0dqk7,
        [data-theme="dark"] .css-1cr4989,
        [data-theme="dark"] .css-1357f6,
        [data-theme="dark"] .css-1ury69a,
        [data-theme="dark"] .css-looxkda,
        [data-theme="dark"] .Sticky,
        [data-theme="dark"] .css-xpmfhx,
        [data-theme="dark"] .css-3zr8ne,
        [data-theme="dark"] .CreationManage-CreationCard,
        [data-theme="dark"] .css-slqtjm,
        [data-theme="dark"] .css-1rniuv1,
        [data-theme="dark"] .Tabs,
        [data-theme="dark"] .css-k5im1d,
        [data-theme="dark"] .css-986uza,
        [data-theme="dark"] .css-1w24404,
        [data-theme="dark"] .css-xoei2t,
        [data-theme="dark"] .css-1m8gbjc,
        [data-theme="dark"] .css-1oqbvad,
        [data-theme="dark"] .css-1ta275q,
        [data-theme="dark"] .css-ndiv23,
        [data-theme="dark"] .css-1wof2n,
        [data-theme="dark"] .css-fqja0q,
        [data-theme="dark"] .css-114mqx8,
        [data-theme="dark"] .css-1iazx5e,
        [data-theme="dark"] .css-yckfye,
        [data-theme="dark"] .css-lztgnc,
        [data-theme="dark"] .Creator-salt-author-welfare,
        [data-theme="dark"] .Creator-salt-author-welfare-card,
        [data-theme="dark"] .CreatorSalt-personalInfo,
        [data-theme="dark"] .css-d1sc5t,
        [data-theme="dark"] .CreatorSalt-sideBar-wrapper,
        [data-theme="dark"] .css-19nug30,
        [data-theme="dark"] .css-h9kawn,
        [data-theme="dark"] .css-127i0sx,
        [data-theme="dark"] .WriteIndexLayout-main,
        [data-theme="dark"] .css-1so3nbl,
        [data-theme="dark"] .css-wmwsyx,
        [data-theme="dark"] .ListShortcut,
        [data-theme="dark"] .css-4jezjh,
        [data-theme="dark"] .css-10kzyet,
        [data-theme="dark"] .css-1byd3cx,
        [data-theme="dark"] .css-15k5nix,
        [data-theme="dark"] .css-15aftra,
        [data-theme="dark"] .css-kt4t4n,
        [data-theme="dark"] .css-1e7fksk,
        [data-theme="dark"] .css-70t8h2,
        [data-theme="dark"] .css-13445jb,
        [data-theme="dark"] .css-smf7y2,
        [data-theme="dark"] .css-h07o3w,
        [data-theme="dark"] .css-7tlwbh,
        [data-theme="dark"] .css-jtt4ph,
        [data-theme="dark"] .css-qf4x08,
        [data-theme="dark"] .css-1y416g7,
        [data-theme="dark"] .css-1p9otau,
        [data-theme="dark"] .css-qgxdhd,
        [data-theme="dark"] .css-16xfl53,
        [data-theme="dark"] .css-89btt1,
        [data-theme="dark"] .css-3wnwue,
        [data-theme="dark"] .css-1tny33p
        {
            background-color: #1a1a1a !important;
            color: #b0b0b0 !important;
        }

        /* 纯黑 */
        [data-theme="dark"] .css-2sopzd{
            background-color: #000000 !important;
        }

        /* 代码背景 */
        [data-theme="dark"] code,
        [data-theme="dark"] .css-ob6uua pre{
            background-color: #242424 !important;
        }

        /* 针对表格的整体样式 */
        [data-theme="dark"] table.css-our8ff {
            background-color: #1a1a1a !important; /* 表格整体背景色 */
            color: #b0b0b0 !important; /* 文本颜色 */
        }

        /* 覆盖所有行(tr)的背景色 */
        [data-theme="dark"] table.css-our8ff tr {
            background-color: #1a1a1a !important; /* 强制每行背景一致 */
        }

        /* 覆盖所有单元格(td 和 th)的背景色和文本颜色 */
        [data-theme="dark"] table.css-our8ff td,
        [data-theme="dark"] table.css-our8ff th {
            background-color: #1a1a1a !important; /* 单元格背景 */
            color: #b0b0b0 !important; /* 单元格文本颜色 */
        }

        /* 针对整个卡片容器 */
        [data-theme="dark"] .LinkCard{
            background-color: #ffffff !important; /* 卡片背景色,稍亮于页面背景 */
            border: 1px solid #444444 !important; /* 边框增加层次感 */
            border-radius: 8px !important; /* 圆角 */
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important; /* 微弱阴影 */
        }

        /* 卡片链接(a 标签) */
        [data-theme="dark"] .LinkCard.new.css-1vqsdx1 {
            background-color: transparent !important; /* 避免重复背景色 */
            color: #d0d0d0 !important; /* 卡片整体文本颜色 */
            text-decoration: none !important; /* 去掉下划线 */
        }

        /* 卡片内容区域 */
        [data-theme="dark"] .LinkCard-contents {
            background-color: transparent !important; /* 内容区域背景透明 */
        }

        /* 标题 */
        [data-theme="dark"] .LinkCard-title {
            color: #e0e0e0 !important; /* 标题使用更亮的灰白色 */
            font-weight: 600 !important; /* 增加标题粗细 */
        }

        /* 描述区域 */
        [data-theme="dark"] .LinkCard-desc {
            color: #b0b0b0 !important; /* 描述文字稍暗,层次分明 */
        }

        /* 标签(如“视频”) */
        [data-theme="dark"] .LinkCard-tag {
            background-color: #3a3a3a !important; /* 标签背景稍亮 */
            color: #c5c5c5 !important; /* 标签文字颜色 */
            border-radius: 4px !important; /* 标签圆角 */
            padding: 2px 6px !important; /* 标签内边距 */
        }

        /* 图片区域 */
        [data-theme="dark"] .LinkCard-image {
            background-color: #1a1a1a !important; /* 图片区域背景稍暗 */
            border: 1px solid #555555 !important; /* 图片边框 */
            border-radius: 4px !important; /* 图片区域圆角 */
        }

        /* 图片 */
        [data-theme="dark"] .LinkCard-image img {
            opacity: 0.9 !important; /* 降低图片亮度,避免过于刺眼 */
            transition: opacity 0.3s ease !important; /* 添加过渡效果 */
        }

        /* 图片 hover 效果 */
        [data-theme="dark"] .LinkCard-image img:hover {
            opacity: 1 !important; /* 鼠标悬停时恢复亮度 */
        }

        /* 播放图标区域 */
        [data-theme="dark"] .LinkCard-image--video {
            background-color: rgba(0, 0, 0, 0.5) !important; /* 播放图标背景半透明 */
            border-radius: 50% !important; /* 圆形背景 */
        }

        /* 播放图标 */
        [data-theme="dark"] .LinkCard-image--video .Zi.Zi--Play {
            color: #ffffff !important; /* 播放图标为纯白,确保可见 */
        }

        /* 卡片 hover 效果 */
        [data-theme="dark"] .LinkCard.new.css-1vqsdx1:hover {
            background-color: #333333 !important; /* 鼠标悬停时背景稍微高亮 */
            transition: background-color 0.3s ease !important; /* 平滑过渡 */
        }

        /* 页面背景 */
        [data-theme="dark"] .css-1so3nbl{
            background-color: #2a2a2a !important;
        }

        /* 编辑区背景 */
        [data-theme="dark"] .WriteIndex-titleInput,
        [data-theme="dark"] .EditorSnapshotWrapper,
        [data-theme="dark"] .css-13mrzb0,
        [data-theme="dark"] .css-qhzfje{
            background-color: #2a2a2a !important;
        }


        /* 用户信息区域 */
        [data-theme="dark"] .LevelInfoV2-creatorInfo,
        [data-theme="dark"] .css-vurnku,
        [data-theme="dark"] .css-cnnstd,
        [data-theme="dark"] .css-180vb7x,
        [data-theme="dark"] .css-1fu8ne5,
        [data-theme="dark"] .css-1yn8tbw,
        [data-theme="dark"] .css-ac5rcx,
        [data-theme="dark"] .css-12kq1qx,
        [data-theme="dark"] .css-33pnco,
        [data-theme="dark"] .css-dpt3mb,
        [data-theme="dark"] .css-1brgq4x,
        [data-theme="dark"] .css-1yuw5jz,
        [data-theme="dark"] .css-1jrei64,
        [data-theme="dark"] .css-1czelnl {
            color: #d3d3d3 !important;
        }

        [data-theme="dark"] .css-sgbbgb {
            color: #b0b0b0 !important;
        }

        /* 通用标题文本 */
        [data-theme="dark"] .Creator-QuestionShared-title,
        [data-theme="dark"] .css-1o7uqnr,
        [data-theme="dark"] .css-atxtl4,
        [data-theme="dark"] .css-qlj5ur,
        [data-theme="dark"] .css-1kq86bv,
        [data-theme="dark"] .css-z06s02,
        [data-theme="dark"] .css-1xvfl67,
        [data-theme="dark"] .css-1yijwry,
        [data-theme="dark"] .css-1rspjpf,
        [data-theme="dark"] .css-15box0,
        [data-theme="dark"] .css-urncze,
        [data-theme="dark"] .css-1k65ame,
        [data-theme="dark"] .css-g62hty,
        [data-theme="dark"] .css-rg9c67,
        [data-theme="dark"] .css-1oq372o,
        [data-theme="dark"] .css-141xy67,
        [data-theme="dark"] .css-vm9s9s,
        [data-theme="dark"] .css-68ooft,
        [data-theme="dark"] .css-1t3in1,
        [data-theme="dark"] .ToolsCopyright-FieldName,
        [data-theme="dark"] .Create-salt-author-complaint-page-content h2,
        [data-theme="dark"] .css-bjox9u,
        [data-theme="dark"] .css-1w0nc6z,
        [data-theme="dark"] .css-1k10w8f,
        [data-theme="dark"] .css-10u695f,
        [data-theme="dark"] .CommentContent,
        [data-theme="dark"] .css-19m36yt,
        [data-theme="dark"] .css-1yj4uzm,
        [data-theme="dark"] .css-1yj4uzm,
        [data-theme="dark"] .css-1pmadmj,
        [data-theme="dark"] .css-rv8vcy,
        [data-theme="dark"] .css-1tvhjhb,
        [data-theme="dark"] .css-f3930v,
        [data-theme="dark"] .css-13awyku,
        [data-theme="dark"] .css-1f4cz9u,
        [data-theme="dark"] .css-1k10w8f,
        [data-theme="dark"] .css-r4op92,
        [data-theme="dark"] .css-1ptti3p,
        [data-theme="dark"] .css-m9wflr,
        [data-theme="dark"] .css-9rfw7f
        {
            color: #b0b0b0 !important;
        }

        /* 正文 */
        [data-theme="dark"] .css-1ggwcl9,
        [data-theme="dark"] .css-4uviby,
        [data-theme="dark"] .css-lmmx7rh,
        [data-theme="dark"] .css-1iz9tag,
        [data-theme="dark"] .css-roes5o,
        [data-theme="dark"] .css-1qqcn7d,
        [data-theme="dark"] .css-yn7rjo,
        [data-theme="dark"] .css-me2vqk,
        [data-theme="dark"] .css-e0p248,
        [data-theme="dark"] .css-iotqsc,
        [data-theme="dark"] .css-onu91o,
        [data-theme="dark"] .Create-salt-author-complaint-page-content p,
        [data-theme="dark"] .css-h5rdys,
        [data-theme="dark"] .css-1symrae,
        [data-theme="dark"] .css-705zp9,
        [data-theme="dark"] .CommentContent,
        [data-theme="dark"] .css-l2s8o9{
            color: #b0b0b0 !important;
        }

        /* 副文 */
        [data-theme="dark"] .css-1dydzuy {
            color: #999999 !important;
        }

        /* 突出文字 */
        [data-theme="dark"] .css-anmzua,
        [data-theme="dark"] .css-1woiwqg,
        [data-theme="dark"] .MCNQuestionListItem-answerBtn,
        [data-theme="dark"] .css-66w2mh {
            color: #ffffff !important;
        }

        /* 浅色超链接 */
        [data-theme="dark"] .css-b7erz1,
        [data-theme="dark"] .css-140fcia{
            color: #86b8ff !important;
        }


        [data-theme="dark"] .css-oxh2a1,
        [data-theme="dark"] .css-1946lac,
        [data-theme="dark"] .css-1wp1nud,
        [data-theme="dark"] .css-zkfaav,
        [data-theme="dark"] .css-qlzdd2,
        [data-theme="dark"] .css-14w1mp,
        [data-theme="dark"] .css-2kp40o,
        [data-theme="dark"] .css-risksa,
        [data-theme="dark"] .css-6j0ktf {
            color: #ffffff !important;
        }

        [data-theme="dark"] .css-1eqmq6 {
            color: #b0b0b0 !important;
        }

        /* 导航菜单项 */
        [data-theme="dark"] .css-5fegde {
            background-color: #1a1a1a !important;
        }

        [data-theme="dark"] .css-133xqjo {
            color: #b0b0b0 !important;
        }

        [data-theme="dark"] .css-133xqjo svg {
            fill: #b0b0b0 !important;
        }

        [data-theme="dark"] .css-17rhbf0 {
            color: #b0b0b0 !important;
        }

        [data-theme="dark"] .css-17rhbf0:hover {
            background-color: #333333 !important;
            color: #ffffff !important;
        }

        /* 特殊图标和标签 */
        [data-theme="dark"] .css-1bh8qzv path:first-child {
            fill: #d32f2f !important;
        }

        [data-theme="dark"] .css-1bh8qzv path:last-child {
            fill: #ffffff !important;
        }

        /* 稍后答按钮 */
        [data-theme="dark"] .css-3470e2,
        [data-theme="dark"] .css-wuse5b {
            color: #b0b0b0 !important;
            background-color: transparent !important;
        }

        [data-theme="dark"] .css-3470e2 svg,
        [data-theme="dark"] .css-wuse5b svg {
            fill: #b0b0b0 !important;
        }

        [data-theme="dark"] .css-3470e2:hover,
        [data-theme="dark"] .css-wuse5b:hover {
            color: #ffffff !important;
            background-color: #333333 !important;
        }

        [data-theme="dark"] .css-3470e2:hover svg,
        [data-theme="dark"] .css-wuse5b:hover svg {
            fill: #ffffff !important;
        }

        /* 暗黑模式下的按钮 */
        [data-theme="dark"] .css-hdz1a3,
        [data-theme="dark"] .css-1q65fkr,
        [data-theme="dark"] .css-97fdvh{
            color: #b0b0b0 !important;
            background-color: #2d2d2d !important;
            border: 1px solid #404040 !important;
        }

        /* 悬浮状态 */
        [data-theme="dark"] .css-hdz1a3:hover {
            color: #ffffff !important;
            background-color: #333333 !important;
            border-color: #606060 !important;
        }

        /* 滚动条 */
        [data-theme="dark"] .StrollBar {
            background-color: transparent !important;
        }

        [data-theme="dark"] .StrollBar > div {
            background-color: rgba(255, 255, 255, 0.3) !important;
        }
    `;

    // 立即将样式添加到页面,即使DOM还未完全加载
    document.head ? document.head.appendChild(style) : document.documentElement.appendChild(style);

    // 页面加载完成后执行后续逻辑
    window.addEventListener('DOMContentLoaded', () => {
        // 设置主题函数
        const setTheme = (theme) => {
            document.documentElement.setAttribute('data-theme', theme);
        };

        // 创建切换按钮
        const toggleBtn = document.createElement('button');
        toggleBtn.style.position = 'fixed';
        toggleBtn.style.top = '10px';
        toggleBtn.style.right = '10px';
        toggleBtn.style.zIndex = '9999';
        toggleBtn.style.width = '32px';
        toggleBtn.style.height = '32px';
        toggleBtn.style.padding = '0';
        toggleBtn.style.backgroundColor = isDark ? '#333333' : '#ffffff';
        toggleBtn.style.border = '1px solid #404040';
        toggleBtn.style.borderRadius = '50%';
        toggleBtn.style.cursor = 'pointer';
        toggleBtn.style.display = 'flex';
        toggleBtn.style.alignItems = 'center';
        toggleBtn.style.justifyContent = 'center';
        toggleBtn.style.boxShadow = '0 2px 4px rgba(0,0,0,0.2)';
        toggleBtn.title = isDark ? '切换到浅色模式' : '切换到深色模式';

        // SVG 图标(太阳和月亮)
        const sunIcon = `
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#FFD700" stroke-width="2">
                <circle cx="12" cy="12" r="5"></circle>
                <line x1="12" y1="1" x2="12" y2="3"></line>
                <line x1="12" y1="21" x2="12" y2="23"></line>
                <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
                <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
                <line x1="1" y1="12" x2="3" y2="12"></line>
                <line x1="21" y1="12" x2="23" y2="12"></line>
                <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
                <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
            </svg>
        `;

        const moonIcon = `
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#C0C0C0" stroke-width="2">
                <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
            </svg>
        `;

        // 设置初始图标
        toggleBtn.innerHTML = isDark ? sunIcon : moonIcon;

        // 点击切换主题
        toggleBtn.onclick = () => {
            const currentTheme = document.documentElement.getAttribute('data-theme');
            if (currentTheme === 'dark') {
                setTheme('light');
                toggleBtn.innerHTML = moonIcon;
                toggleBtn.style.backgroundColor = '#ffffff';
                toggleBtn.title = '切换到深色模式';
                localStorage.setItem('zhihu-dark-mode', 'false');
            } else {
                setTheme('dark');
                toggleBtn.innerHTML = sunIcon;
                toggleBtn.style.backgroundColor = '#333333';
                toggleBtn.title = '切换到浅色模式';
                localStorage.setItem('zhihu-dark-mode', 'true');
            }
        };

        // 添加按钮到页面
        document.body.appendChild(toggleBtn);

        // 使用 MutationObserver 监控 data-theme 变化
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.attributeName === 'data-theme') {
                    const currentTheme = document.documentElement.getAttribute('data-theme');
                    const shouldBeDark = localStorage.getItem('zhihu-dark-mode') === 'true';
                    if (shouldBeDark && currentTheme !== 'dark') {
                        setTheme('dark');
                    } else if (!shouldBeDark && currentTheme !== 'light') {
                        setTheme('light');
                    }
                }
            });
        });

        // 开始观察 <html> 的属性变化
        observer.observe(document.documentElement, {
            attributes: true,
            attributeFilter: ['data-theme']
        });
    });
})();