Greasy Fork is available in English.
点击链接变暗并添加波浪线,标记会保存直到标签页关闭
当前为
// ==UserScript==
// @name 标记已点击链接(会话版)
// @description 点击链接变暗并添加波浪线,标记会保存直到标签页关闭
// @version 2.9
// @author WJ
// @match *://*/*
// @license MIT
// @grant none
// @namespace http://greasyfork.icu/users/914996
// ==/UserScript==
(function() {
// 加载存储的标记链接
const marked = JSON.parse(sessionStorage.xMarkedLinks || '{}');
// 标准化URL(核心简化版)
const normalizeUrl = url => {
try {
const u = new URL(url);
u.hash = '';
return u.href;
} catch {
return url;
}
};
// 标记链接样式
const markLink = a => {
a.style.cssText = 'text-decoration:underline wavy #00CED1; opacity:0.5';
};
// 标记所有匹配链接
const markAll = url => {
const normUrl = normalizeUrl(url);
marked[normUrl] = true;
sessionStorage.xMarkedLinks = JSON.stringify(marked);
document.querySelectorAll('a[href]').forEach(a => {
if (normalizeUrl(a.href) === normUrl) markLink(a);
});
};
// 初始化标记
const init = () => {
Object.keys(marked).forEach(url => {
document.querySelectorAll('a[href]').forEach(a => {
if (normalizeUrl(a.href) === url) markLink(a);
});
});
};
// 动态内容检测
new MutationObserver(init).observe(document, {
childList: true,
subtree: true
});
// 页面加载后初始化
document.addEventListener('DOMContentLoaded', init);
// 点击处理
document.addEventListener('click', e => {
const a = e.target.closest('a[href]');
if (!a || marked[normalizeUrl(a.href)]) return;
if (!a.closest(`
nav, .nav, .navbar, .navigation,
.menu, .menubar, .breadcrumb, header,
.header, footer, .footer, .pagination, .tabs,
.tabbar, .sidebar, .aside, #sidebar, #aside,
[role="navigation"], [role="menu"], [role="tablist"], [role="banner"]
`)) {
markAll(a.href);
}
}, true);
})();