您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
已读标题变灰,帖子的url根据最新回复数会每次刷新
当前为
// ==UserScript== // @name S1论坛帖子已读样式 // @namespace http://tampermonkey.net/ // @version 1.3 // @description 已读标题变灰,帖子的url根据最新回复数会每次刷新 // @author You // @match *.saraba1st.com/2b/forum* // @match *.saraba1st.com/2b/thread* // @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, "children[3].children[0].text"); const title = get(thread, "children[1].children[2]"); 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", } ); } if (isThreadList()) { initObserver(); 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; } }); // window.addEventListener('storage', (event) => { // console.log(event.key, event.newValue) // }) } if (isThread()) { asyncRun(() => { if (window.tid) { const span = document.querySelector( "#postlist > table:nth-child(1) > tbody > tr > td.pls.ptn.pbn > div > span:nth-child(5)" ); if (span) { updateThreadReplyNum(window.tid, span.textContent); } return true; } }); } })();