IT之家移动页面热门评论高亮

在全部评论中匹配热门评论并高亮显示,避免重复查看热门评论、精简评论样式、隐藏0赞0反按钮、自动点击更多评论

// ==UserScript==
// @name         IT之家移动页面热门评论高亮
// @namespace    http://tampermonkey.net/
// @version      1.0.4
// @description  在全部评论中匹配热门评论并高亮显示,避免重复查看热门评论、精简评论样式、隐藏0赞0反按钮、自动点击更多评论
// @author       hui-Zz
// @match        http*://m.ithome.com/*
// @match        http*://bbs.hupu.com/*
// @icon         https://www.emojiall.com/en/header-svg/%F0%9F%93%B0.svg
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    /* 站点配置 */
    const SITE_CONFIG = {
        'm.ithome.com': {
            hotCommentSelector: '.hot-comment .placeholder',   // 热门评论容器选择器
            allCommentSelector: '.all-comment .placeholder',   // 全部评论容器选择器
            usernameSelector: '.user-name',                     // 用户名元素选择器
            contentSelector: '.user-review',                    // 评论内容选择器
            commentContainerHot: '.hot-comment',               // 热门评论区域选择器
            commentContainer: '.all-comment',                   // 全部评论区域选择器
            initAction: () => $('.hot-comment').hide()          // 初始化操作:隐藏热门评论区域
        }
    };

    // 获取当前站点配置
    const hostname = window.location.hostname;
    const config = SITE_CONFIG[hostname];
    if (!config) return; // 非目标站点直接退出
    config.initAction(); // 执行站点初始化操作

    /* 工具函数:生成评论唯一标识 */
    const getCommentKey = comment => `${comment.username}_${comment.content}`;

    /* 核心功能实现 */
    class CommentHighlighter {
        constructor() {
            this.hotComments = new Map();   // 使用Map存储热门评论(O(1)查找)
            this.isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
            this.initObservers();
            this.collectHotComments();     // 初始收集
            this.highlightComments();      // 初始高亮
        }

        /* 初始化MutationObserver监听 */
        initObservers() {
            // 热门评论区域监听
            this.observeArea(config.commentContainerHot, () => this.collectHotComments());
            // 全部评论区域监听
            this.observeArea(config.commentContainer, () => this.highlightComments());
        }

        /* 通用区域监听方法 */
        observeArea(selector, callback) {
            const targetNode = document.querySelector(selector);
            if (!targetNode) return;

            new MutationObserver(() => callback())
                .observe(targetNode, {
                    childList: true,  // 监听子元素变化
                    subtree: true     // 监听所有后代元素
                });
        }

        /* 收集热门评论 */
        collectHotComments() {
            this.hotComments.clear();

            document.querySelectorAll(config.hotCommentSelector)
                .forEach(commentElement => {
                    const username = this.getText(commentElement, config.usernameSelector);
                    const content = this.getText(commentElement, config.contentSelector);

                    if (username && content) {
                        this.hotComments.set(getCommentKey({ username, content }), true);
                        this.processSpecialElements(commentElement); // 处理特殊元素
                    }
                });
        }

        /* 高亮匹配评论 */
        highlightComments() {
            document.querySelectorAll(config.allCommentSelector)
                .forEach(commentElement => {
                    const username = this.getText(commentElement, config.usernameSelector);
                    const content = this.getText(commentElement, config.contentSelector);

                    if (hostname === 'm.ithome.com') {
                        // 点击更多评论
                        commentElement.querySelector('.look-more')?.click();
                        // 处理IP显示
                        this.processHupuIP(commentElement);
                        // 隐藏交互元素
                        this.hideInteractiveElements(commentElement);
                    }
                    // 高亮匹配的评论
                    if (username && content && this.hotComments.has(getCommentKey({ username, content }))) {
                        commentElement.classList.add('hot-comment-highlight');
                    }
                });
        }

        /* 辅助方法:安全获取文本内容 */
        getText(element, selector) {
            return element.querySelector(selector)?.textContent?.trim();
        }

        /* 处理IP地址显示 */
        processHupuIP(element) {
            const ipElement = element.querySelector('.user-ip');
            const ipText = ipElement?.textContent?.trim();
            const match = ipText?.match(/IT之家(.*?)网友/);
            if (match) ipElement.textContent = match[1];
        }

        /* 隐藏支持/反对等交互元素 */
        hideInteractiveElements(commentElement) {
            // 获取所有交互元素(安全访问)
            const standby = commentElement.querySelector('.stand-by');
            const oppose = commentElement.querySelector('.oppose');
            const reply = commentElement.querySelector('.reply');
            const reviewfooter = commentElement.querySelector('.review-footer');
            const userfloor = commentElement.querySelector('.user-floor');
            const userwritemsg = commentElement.querySelector('.user-write-msg');
            const userreview = commentElement.querySelector('.user-review');
            userfloor.style.float = 'none';
            userfloor.style.marginLeft = '10px';
            userwritemsg.style.float = 'right';
            userwritemsg.style.marginTop = '-20px';
            userreview.style.marginTop = '5px';

            // 处理支持按钮(仅隐藏0/1支持状态)
            if (standby) {
                const standbyText = standby.textContent?.trim();
                if (['支持(0)', '支持(1)'].includes(standbyText)) {
                    standby.style.display = 'none';
                }
            }

            // 处理反对按钮(仅隐藏0/1反对状态)
            if (oppose) {
                const opposeText = oppose.textContent?.trim();
                if (['反对(0)', '反对(1)'].includes(opposeText)) {
                    oppose.style.display = 'none';
                }
            }

            // 始终隐藏回复按钮(想回复评论注释掉此行代码)
            // if (reply) reply.style.display = 'none';

            // 当支持/反对都符合条件时隐藏底部栏
            if (reviewfooter && standby && oppose) {
                const standbyValid = ['支持(0)', '支持(1)'].includes(standby.textContent?.trim());
                const opposeValid = ['反对(0)', '反对(1)'].includes(oppose.textContent?.trim());
                if (standbyValid && opposeValid) {
                    reviewfooter.style.display = 'none';
                }
            }
        }

        /* 处理站点特殊元素 */
        processSpecialElements(element) {
            // IT之家特殊处理(示例)
            if (hostname === 'm.ithome.com') {
                element.style.display = 'block';
            }
        }
    }

    /* 样式注入 */
    const style = document.createElement('style');
    style.textContent = `
        .hot-comment-highlight {
            background-color: yellow !important;
            border: 2px solid orange !important;
        }
        @media (prefers-color-scheme: dark) {
            .hot-comment-highlight {
                background-color: #333 !important;
                color: #fff !important;
            }
        }
    `;
    document.head.appendChild(style);

    // 启动高亮系统
    new CommentHighlighter();

})();