// ==UserScript== // @name 记住访问过的链接 // @version 1.6 // @description 记住网页上访问过的链接,并将其颜色设置为浅蓝色。脚本菜单支持单独域名启用/禁用脚本。 // @author ChatGPT // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @run-at document-end // @namespace https://greasyfork.org/users/452911 // @downloadURL https://update.greasyfork.icu/scripts/507733/%E8%AE%B0%E4%BD%8F%E8%AE%BF%E9%97%AE%E8%BF%87%E7%9A%84%E9%93%BE%E6%8E%A5.user.js // @updateURL https://update.greasyfork.icu/scripts/507733/%E8%AE%B0%E4%BD%8F%E8%AE%BF%E9%97%AE%E8%BF%87%E7%9A%84%E9%93%BE%E6%8E%A5.meta.js // ==/UserScript== (function() { 'use strict'; const domain = window.location.hostname; const scriptKey = `scriptEnabled_${domain}`; let isEnabled = GM_getValue(scriptKey, true); function updateMenu() { GM_unregisterMenuCommand('toggleScriptMenuCommand'); GM_unregisterMenuCommand('clearLinksMenuCommand'); const toggleText = isEnabled ? '禁用记住访问过的链接脚本' : '启用记住访问过的链接脚本'; GM_registerMenuCommand(toggleText, toggleScript); GM_registerMenuCommand('清除所有记住的链接', clearLinks); } function toggleScript() { isEnabled = !isEnabled; GM_setValue(scriptKey, isEnabled); updateMenu(); if (isEnabled) { initScript(); } else { removeScript(); } } function clearLinks() { GM_setValue('visitedLinks', []); document.querySelectorAll('a[href]:not([href="javascript:;"])').forEach(link => { link.style.color = ''; }); } function initScript() { const visitedLinks = new Set(GM_getValue('visitedLinks', [])); function updateLinkStatus(link) { if (visitedLinks.has(link.href)) { link.style.color = '#88C6E5'; } else { link.addEventListener('click', () => { visitedLinks.add(link.href); GM_setValue('visitedLinks', Array.from(visitedLinks)); link.style.color = '#88C6E5'; }); } } document.querySelectorAll('a[href]:not([href="javascript:;"])').forEach(updateLinkStatus); const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { node.querySelectorAll('a[href]:not([href="javascript:;"])').forEach(updateLinkStatus); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); } function removeScript() { document.querySelectorAll('a[href]:not([href="javascript:;"])').forEach(link => { link.style.color = ''; }); } updateMenu(); if (isEnabled) { initScript(); } })();