您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
已读标题变灰,帖子的url根据最新回复数会每次刷新
当前为
// ==UserScript== // @name S1论坛帖子已读样式 // @namespace http://tampermonkey.net/ // @version 1.4 // @description 已读标题变灰,帖子的url根据最新回复数会每次刷新 // @author You // @match *.saraba1st.com/2b/forum* // @grant none // @run-at document-body // ==/UserScript== function get(data, key) { const keys = key.replace(/\[(\d+)\]/g, ".$1").split("."); let result = data; while (keys.length && result) { result = result[keys.shift()]; } return result; } // function isThread() { // return location.pathname.includes("thread"); // } // function isThreadList() { // return location.pathname.includes("forum"); // } function asyncRun(callback) { const timer = setInterval(() => { const ret = callback(); if (ret) { clearInterval(timer); } }, 100); } function updateThreadReplyNum(id, num) { localStorage.setItem(id, num); } function getThreadLastReplyNum(id) { const num = localStorage.getItem(id); return num ? +num : null; } function appendStyle() { const style = document.createElement("style"); style.type = "text/css"; style.appendChild( document.createTextNode( ".tl th a:visited, .tl td.fn a:visited {color: #818588}" ) ); style.appendChild( document.createTextNode( ".tl th a:hover, .tl td.fn a:hover {color: #022C80}" ) ); document.body.appendChild(style); } (function () { "use strict"; // 修改帖子样式 appendStyle(); // 动态修改url const hasReplacedIds = new Set(); let table = null; let lastThreadNum = 0; let observer = null; function observeThreads() { const threads = Array.from( document.querySelectorAll("#threadlisttableid tbody tr") ).filter((element) => !hasReplacedIds.has(element.parentNode.id)); threads.forEach((t) => observer.observe(t)); } function initObserver() { observer = new IntersectionObserver( (entities) => { entities.forEach((entity) => { if (entity.isIntersecting) { const thread = entity.target; observer.unobserve(thread); const id = thread.parentNode.id; if (hasReplacedIds.has(id)) { return; } hasReplacedIds.add(id); // url const replyNum = get(thread.querySelector('.num a'), 'textContent'); const title = thread.querySelector('.xst'); if (title && replyNum) { title.href += `#${replyNum}`; } // reply num const tid = get(id.match(/\d+/), "0"); const lastReplyNum = +getThreadLastReplyNum(tid); if (lastReplyNum && replyNum && replyNum - lastReplyNum > 0) { title.textContent = `+${replyNum - lastReplyNum} ${ title.textContent }`; } } }); }, { rootMargin: "100px", } ); } function onThreadClick() { asyncRun(() => { if (table) { table.addEventListener('click', (e) => { let element = e.target; const validClick = (element.tagName === 'A' && element.href.includes('thread-')) || (element.tagName === 'IMG' && element.src === 'https://static.saraba1st.com/image/s1/folder_common.gif'); if (!validClick) { return; } while (element.parentNode) { if (element.tagName === 'TBODY') { const replyNum = get(element.querySelector('.num a'), 'textContent'); const tid = get(element.id.match(/\d+/), "0"); if (replyNum && tid) { updateThreadReplyNum(tid, replyNum); } break; } if (element === table) { break; } element = element.parentNode; } }); return true; } }) } initObserver(); onThreadClick(); asyncRun(() => { table = document.getElementById("threadlisttableid"); // 实际发现只检测table并不能保证帖子全加载了 const nextPageBtn = document.querySelector("#autopbn"); if (table && nextPageBtn) { lastThreadNum = table.childElementCount; observeThreads(); return true; } }); // 监控下一页 asyncRun(() => { const nextPageBtn = document.querySelector("#autopbn"); if (nextPageBtn) { nextPageBtn.addEventListener("click", () => { asyncRun(() => { if (table.childElementCount > lastThreadNum) { lastThreadNum = table.childElementCount; observeThreads(); return true; } }); }); return true; } }); })();