标记已访问的帖子标题,支持搜同网和 TT1069 论坛,标记放左边,避免误标!
当前为
// ==UserScript==
// @name Multi Forum Read Marker (Soutong + TT1069)
// @namespace https://felixchristian.dev/userscripts/multi-forum-read-marker
// @version 1.1.0
// @description 标记已访问的帖子标题,支持搜同网和 TT1069 论坛,标记放左边,避免误标!
// @author FelixChristian
// @license MIT
// @match https://soutong.men/forum.php?mod=forumdisplay&fid=*
// @match https://soutong.men/forum.php?mod=viewthread&tid=*
// @match https://www.tt1069.com/bbs/forum-*-*.html
// @match https://www.tt1069.com/bbs/thread-*-*-*.html
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
(function () {
'use strict';
const HOST = location.hostname;
const isSoutong = HOST.includes('soutong.men');
const isTT1069 = HOST.includes('tt1069.com');
const STORAGE_KEY = 'visitedTids';
let visitedTids = GM_getValue(STORAGE_KEY, {});
// 解析当前页面帖子的唯一 ID(tid)
function getCurrentTid() {
if (isSoutong) {
const url = new URL(location.href);
return url.searchParams.get('tid');
}
if (isTT1069) {
const match = location.pathname.match(/thread-(\d+)-\d+-\d+\.html/);
return match ? match[1] : null;
}
return null;
}
// 记录访问
function recordTidVisit(tid) {
if (tid) {
visitedTids[tid] = Date.now();
GM_setValue(STORAGE_KEY, visitedTids);
}
}
// 标记已读
function markReadThreads() {
let threadLinks;
if (isSoutong) {
threadLinks = document.querySelectorAll('a.xst');
} else if (isTT1069) {
threadLinks = Array.from(document.querySelectorAll('a.xst')).filter(link => {
return /thread-(\d+)-/.test(link.href);
});
}
if (!threadLinks || threadLinks.length === 0) {
setTimeout(markReadThreads, 500);
return;
}
threadLinks.forEach(link => {
let tid;
if (isSoutong) {
try {
const fullUrl = new URL(link.href, location.origin);
tid = fullUrl.searchParams.get('tid');
} catch (e) { return; }
} else if (isTT1069) {
const match = link.href.match(/thread-(\d+)-/);
tid = match ? match[1] : null;
}
if (tid && visitedTids[tid] && !link.dataset.markedVisited) {
const tag = document.createElement('span');
tag.textContent = '[已读] ';
tag.style.color = 'red';
tag.style.fontWeight = 'bold';
tag.style.marginRight = '4px';
link.insertBefore(tag, link.firstChild);
link.dataset.markedVisited = 'true';
}
});
}
// 页面识别逻辑
const isViewThread = (isSoutong && location.href.includes('mod=viewthread')) ||
(isTT1069 && /thread-\d+-\d+-\d+\.html/.test(location.pathname));
const isForumDisplay = (isSoutong && location.href.includes('mod=forumdisplay')) ||
(isTT1069 && /forum-\d+-\d+\.html/.test(location.pathname));
if (isViewThread) {
const tid = getCurrentTid();
recordTidVisit(tid);
}
if (isForumDisplay) {
window.addEventListener('load', markReadThreads);
const observer = new MutationObserver(markReadThreads);
observer.observe(document.body, { childList: true, subtree: true });
}
})();