您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
zh-cn
// ==UserScript== // @name 点击网址链接变色 Persistent Red Link // @namespace http://tampermonkey.net/ // @match *://*/* // @grant 市政502 // @version 2025.7.4 // @description zh-cn // @license GNU General Public License v3.0 // ==/UserScript== (function () { 'use strict'; // 存储配置 const STORAGE_KEY = 'visitedLinks_v3'; const MAX_STORAGE_SIZE = 4 * 1024 * 1024; // 4MB安全阈值 const SAVE_INTERVAL = 30000; // 30秒定期保存 const DEBOUNCE_DELAY = 1000; // 1秒防抖 // 内存数据结构 let visitedLinks = new Set(); let pendingChanges = new Set(); // 待保存的变更集 let saveTimeout = null; // 初始化存储 function initStorage() { try { const storedData = localStorage.getItem(STORAGE_KEY); if (storedData) { const parsed = JSON.parse(storedData); if (Array.isArray(parsed)) { for (const url of parsed) { visitedLinks.add(url); } } } } catch (e) { console.warn('存储解析失败,使用空集合初始化'); visitedLinks = new Set(); localStorage.removeItem(STORAGE_KEY); } } // 智能保存策略 function scheduleSave() { clearTimeout(saveTimeout); saveTimeout = setTimeout(persistStorage, DEBOUNCE_DELAY); } // 核心持久化方法 function persistStorage() { try { // 合并变更 for (const url of pendingChanges) { visitedLinks.add(url); } pendingChanges.clear(); // 数据压缩 const compressed = compressData(Array.from(visitedLinks)); // 存储前检查空间 if (compressed.length > MAX_STORAGE_SIZE - 1024) { // 保留1KB缓冲 handleStorageOverflow(); return; } localStorage.setItem(STORAGE_KEY, compressed); console.debug('成功保存', visitedLinks.size, '条记录'); } catch (e) { handleStorageError(e); } } // 数据压缩算法 function compressData(urls) { // 实现简单去重+排序压缩 return JSON.stringify(urls.sort()); } // 存储空间不足处理 function handleStorageOverflow() { const currentSize = localStorage.getItem(STORAGE_KEY)?.length || 0; console.warn(`存储空间不足: 当前使用 ${currentSize} 字节,建议清理缓存`); // 尝试删除旧数据(示例策略:保留最近10000条) if (visitedLinks.size > 10000) { const newSet = Array.from(visitedLinks).slice(-10000); visitedLinks = new Set(newSet); pendingChanges.clear(); scheduleSave(); } } // 存储错误处理 function handleStorageError(error) { if ((error.name === 'QuotaExceededError' || error.code === 22)) { alert('存储空间不足,请清理浏览器缓存'); } else { console.error('存储异常:', error); } } // 链接处理核心逻辑 function handleLink(link) { const linkUrl = link.href; if (visitedLinks.has(linkUrl)) { applyVisitedStyle(link); return; } link.addEventListener('click', () => { if (!visitedLinks.has(linkUrl)) { pendingChanges.add(linkUrl); applyVisitedStyle(link); scheduleSave(); } }); } // 样式应用 function applyVisitedStyle(link) { link.style.setProperty('color', '#FF0000', 'important'); } // 初始处理 function initializePage() { const links = document.querySelectorAll('a'); links.forEach(link => { if (visitedLinks.has(link.href)) { applyVisitedStyle(link); } handleLink(link); }); } // 动态内容监控 const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { const links = node.querySelectorAll('a'); links.forEach(link => { handleLink(link); if (visitedLinks.has(link.href)) { applyVisitedStyle(link); } }); } }); }); }); // 初始化流程 (function init() { initStorage(); initializePage(); observer.observe(document.body, { childList: true, subtree: true }); // 定期保存 setInterval(persistStorage, SAVE_INTERVAL); // 页面卸载时保存 window.addEventListener('beforeunload', persistStorage); })(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址