Greasy Fork

Greasy Fork is available in English.

战字加粗 (优化版)

将网页中所有的"战"字加粗显示,优化性能防止卡死

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         战字加粗 (优化版)
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  将网页中所有的"战"字加粗显示,优化性能防止卡死
// @author       您的名字
// @match        *://*/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';
    
    // 配置选项
    const config = {
        processDelay: 1000,          // 初始延迟时间(毫秒)
        batchSize: 100,              // 每批处理的节点数量
        batchDelay: 50,              // 批次间延迟(毫秒)
        observerThrottle: 2000,      // 观察者触发间隔(毫秒)
        targetChar: '战'             // 需要加粗的字符
    };
    
    // 存储已处理的节点,避免重复处理
    const processedNodes = new WeakSet();
    
    // 节点处理队列
    let nodeQueue = [];
    let isProcessing = false;
    let lastObserverTime = 0;
    
    // 创建一个函数来处理文本节点
    function processTextNode(textNode) {
        if (processedNodes.has(textNode) || !textNode.nodeValue.includes(config.targetChar)) {
            return;
        }
        
        try {
            // 创建一个文档片段来存储修改后的内容
            const fragment = document.createDocumentFragment();
            
            // 分割文本节点内容
            const parts = textNode.nodeValue.split(config.targetChar);
            
            // 重建节点,将"战"字替换为加粗版本
            for (let i = 0; i < parts.length; i++) {
                // 添加原始文本部分
                if (parts[i]) {
                    fragment.appendChild(document.createTextNode(parts[i]));
                }
                
                // 添加加粗的"战"字(除了最后一个分割之后)
                if (i < parts.length - 1) {
                    const bold = document.createElement('strong');
                    bold.textContent = config.targetChar;
                    fragment.appendChild(bold);
                }
            }
            
            // 标记为已处理
            processedNodes.add(textNode);
            
            // 使用修改后的内容替换原始文本节点
            if (textNode.parentNode) {
                textNode.parentNode.replaceChild(fragment, textNode);
            }
        } catch (e) {
            console.error('处理文本节点时出错:', e);
        }
    }
    
    // 收集DOM树中的所有文本节点
    function collectTextNodes(node) {
        // 跳过已处理的节点
        if (processedNodes.has(node)) {
            return;
        }
        
        // 处理文本节点
        if (node.nodeType === Node.TEXT_NODE) {
            if (node.nodeValue && node.nodeValue.includes(config.targetChar)) {
                nodeQueue.push(node);
            }
            return;
        }
        
        // 跳过不需要处理的元素
        if (node.nodeName === 'SCRIPT' || node.nodeName === 'STYLE' || 
            node.nodeName === 'NOSCRIPT' || node.nodeName === 'TEXTAREA' || 
            node.nodeName === 'INPUT' || node.nodeName === 'SVG' ||
            node.className === '战字加粗-已处理') {
            return;
        }
        
        // 递归处理子节点
        try {
            const childNodes = node.childNodes;
            for (let i = 0; i < childNodes.length; i++) {
                collectTextNodes(childNodes[i]);
            }
        } catch (e) {
            console.error('收集节点时出错:', e);
        }
    }
    
    // 分批处理节点队列
    function processBatch() {
        if (nodeQueue.length === 0) {
            isProcessing = false;
            return;
        }
        
        isProcessing = true;
        
        // 获取当前批次需要处理的节点
        const batchNodes = nodeQueue.splice(0, config.batchSize);
        
        // 处理这一批节点
        for (const node of batchNodes) {
            if (node.parentNode) {  // 确保节点仍然在DOM中
                processTextNode(node);
            }
        }
        
        // 处理下一批
        if (nodeQueue.length > 0) {
            setTimeout(processBatch, config.batchDelay);
        } else {
            isProcessing = false;
        }
    }
    
    // 开始处理页面
    function startProcessing() {
        // 收集文本节点
        collectTextNodes(document.body);
        
        // 如果没有正在处理的任务,开始处理
        if (!isProcessing && nodeQueue.length > 0) {
            setTimeout(processBatch, 0);
        }
    }
    
    // 设置触发条件
    function setupTriggers() {
        // 1. 初始延迟加载
        setTimeout(startProcessing, config.processDelay);
        
        // 2. 滚动触发
        let scrollTimeout;
        window.addEventListener('scroll', function() {
            if (scrollTimeout) {
                clearTimeout(scrollTimeout);
            }
            scrollTimeout = setTimeout(startProcessing, 200);
        }, { passive: true });
        
        // 3. 点击触发
        document.addEventListener('click', function() {
            setTimeout(startProcessing, 100);
        }, { passive: true });
        
        // 4. 页面可见性变化触发
        document.addEventListener('visibilitychange', function() {
            if (!document.hidden) {
                setTimeout(startProcessing, 100);
            }
        });
    }
    
    // 使用 MutationObserver 监听 DOM 变化
    function setupObserver() {
        const observer = new MutationObserver(function(mutations) {
            // 限制观察者触发频率
            const now = Date.now();
            if (now - lastObserverTime < config.observerThrottle) {
                return;
            }
            lastObserverTime = now;
            
            let hasNewNodes = false;
            mutations.forEach(function(mutation) {
                if (mutation.addedNodes && mutation.addedNodes.length > 0) {
                    for (let i = 0; i < mutation.addedNodes.length; i++) {
                        if (!processedNodes.has(mutation.addedNodes[i])) {
                            collectTextNodes(mutation.addedNodes[i]);
                            hasNewNodes = true;
                        }
                    }
                }
            });
            
            if (hasNewNodes && !isProcessing && nodeQueue.length > 0) {
                setTimeout(processBatch, 0);
            }
        });
        
        // 配置 MutationObserver - 使用更具体的配置来减少不必要的触发
        observer.observe(document.body, {
            childList: true,
            subtree: true,
            attributes: false,
            characterData: false
        });
    }
    
    // 初始化
    function init() {
        // 防止在某些特殊页面上运行
        if (window.location.href.includes('chrome://') || 
            window.location.href.includes('about:') ||
            !document.body) {
            return;
        }
        
        // 设置触发条件
        setupTriggers();
        
        // 设置观察者
        setupObserver();
        
        // 添加调试信息(可在生产版本中移除)
        console.log('战字加粗脚本已加载');
    }
    
    // 当DOM加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();