@NeiNei #9 发布于2026/10/3 10:57:59 @lianssss9 #4 脚本发下 // ==UserScript== // @name ✅ NodeSeek 💡 高亮 & ❌ 屏蔽 // @namespace https://github.com/you/nodeseek-hotkey // @version 260907 // @description 高亮和屏蔽 nodeseek.com 论坛帖子标题及用户回复 // @author Claude 首发于 260907 // @match https://www.nodeseek.com/* // @icon https://www.nodeseek.com/static/image/favicon/favicon-32x32.png // @grant none // @run-at document-end // ==/UserScript== (function () { 'use strict'; const config = { // ❌ 屏蔽关键词(不区分大小写)- 空格分隔 blockKeywords: 'Vmiss DeepSeek 鹈鹕 国模 意见稿', // ✅ 高亮关键词(不区分大小写)- 空格分隔 highlightKeywords: '免费 白嫖 羊毛 福利 限免 开源 开放 公益 赠送 送出 赠出 邀请码', highlightColor: '#2ea44f', // ❌ 屏蔽用户黑名单(不区分大小写)- 空格分隔 blockUsers: '', // ✅ 高亮用户名单(不区分大小写)- 空格分隔 highlightUsers: '', highlightUserColor: '#FFD700', // ❌ 屏蔽正则 blockRegexPatterns: [ /第.{0,3}期/i, /招.{0,4}(人|员|募)/i, /(问|请问).{0,10}(哪|怎|如何|能不能|可以吗)/i, /分享.{0,5}(经验|心得|体验|感受)/i, ], }; // ── 解析关键词 ── function parseKws(str) { return str.trim().split(/\s+/).filter(k => k.length > 0); } const highlightKwArr = parseKws(config.highlightKeywords); const blockKwArr = parseKws(config.blockKeywords); const blockUsersArr = parseKws(config.blockUsers).map(u => u.toLowerCase()); const highlightUsersArr = parseKws(config.highlightUsers).map(u => u.toLowerCase()); // ── 注入样式 ── function injectStyles() { const id = 'ns-filter-style'; document.getElementById(id)?.remove(); const style = document.createElement('style'); style.id = id; style.textContent = ` .ns-user-hl { background-color: ${config.highlightUserColor} !important; color: #333 !important; padding: 1px 4px !important; border-radius: 4px !important; font-weight: bold !important; } `; document.head.appendChild(style); } injectStyles(); if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', injectStyles); window.addEventListener('load', injectStyles); // ── 判断函数 ── function shouldBlock(title) { const low = title.toLowerCase(); if (blockKwArr.some(k => low.includes(k.toLowerCase()))) return true; return config.blockRegexPatterns.some(r => r.test(title)); } function shouldHighlight(title) { const low = title.toLowerCase(); return highlightKwArr.some(k => low.includes(k.toLowerCase())); } function isBlockedUser(name) { if (!name) return false; return blockUsersArr.includes(name.toLowerCase()); } function isHighlightUser(name) { if (!name) return false; return highlightUsersArr.includes(name.toLowerCase()); } // ── 关键词高亮(标题内嵌 span)── function highlightKwInTitle(el, text) { const escaped = highlightKwArr.map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')); const regex = new RegExp(`(${escaped.join('|')})`, 'gi'); el.innerHTML = text.replace(regex, match => `<span style="background:${config.highlightColor};color:#fff;padding:1px 3px;border-radius:3px;font-weight:bold">${match}</span>` ); } // ── 处理列表帖子行 ── // NodeSeek DOM: // li.post-list-item // .post-title > a ← 标题链接 // .avatar-normal[data-uid] ← 发帖人头像(data-uid) // .avatar-normal img[title]← 发帖人名(部分版本) function processRow(row) { if (row.dataset.nsFiltered) return; row.dataset.nsFiltered = '1'; const titleLink = row.querySelector('.post-title > a'); if (!titleLink) return; const title = titleLink.textContent.trim(); // 取发帖人:优先用头像 data-uid 旁边的用户信息, // NodeSeek 列表的作者名藏在 .post-meta .author a 或 .avatar img[title] const authorEl = row.querySelector('.post-meta .author a') || row.querySelector('.post-meta a[href*="/space/"]') || row.querySelector('.nsk-post-meta a[href*="/space/"]'); const author = authorEl ? authorEl.textContent.trim() : ''; // 1. 屏蔽用户 if (author && isBlockedUser(author)) { row.style.display = 'none'; return; } // 2. 屏蔽关键词 if (shouldBlock(title)) { row.style.display = 'none'; return; } // 3. 高亮用户(整行标题金色底) if (author && isHighlightUser(author)) { titleLink.classList.add('ns-user-hl'); return; } // 4. 高亮关键词 if (shouldHighlight(title)) { highlightKwInTitle(titleLink, title); } } // ── 处理帖子详情页回复楼层 ── // NodeSeek 帖子页 DOM: // .content-item // .nsk-content-meta-info .author-info > a ← 楼层作者 function processReply(item) { if (item.dataset.nsFiltered) return; // 跳过1楼(帖主) const floorNum = item.dataset.index || item.dataset.floor; if (floorNum === '0' || floorNum === '1') { item.dataset.nsFiltered = '1'; return; } const authorEl = item.querySelector('.nsk-content-meta-info .author-info > a') || item.querySelector('.author-info > a'); const author = authorEl ? authorEl.textContent.trim() : ''; item.dataset.nsFiltered = '1'; if (author && isBlockedUser(author)) { item.remove(); } } // ── 批量处理 ── function processAll() { document.querySelectorAll('li.post-list-item').forEach(processRow); document.querySelectorAll('.content-item').forEach(processReply); } processAll(); // ── MutationObserver 监听动态加载 ── const observer = new MutationObserver(mutations => { let needList = false, needReply = false; for (const m of mutations) { for (const node of m.addedNodes) { if (node.nodeType !== 1) continue; if (node.matches?.('li.post-list-item') || node.querySelector?.('li.post-list-item')) needList = true; if (node.matches?.('.content-item') || node.querySelector?.('.content-item')) needReply = true; } if (m.type === 'childList') { const p = m.target.closest?.('li.post-list-item'); if (p) needList = true; const r = m.target.closest?.('.content-item'); if (r) needReply = true; } } if (needList) document.querySelectorAll('li.post-list-item').forEach(processRow); if (needReply) document.querySelectorAll('.content-item').forEach(processReply); }); observer.observe(document.body, { childList: true, subtree: true }); // ── 滚动(下拉无限加载)── let scrollT; window.addEventListener('scroll', () => { clearTimeout(scrollT); scrollT = setTimeout(processAll, 300); }, { passive: true }); // ── SPA 路由切换 ── let lastUrl = location.href; new MutationObserver(() => { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(processAll, 500); } }).observe(document.body, { childList: true, subtree: true }); console.log('[NS-Filter v1.0] 已启动 | 高亮词:', highlightKwArr.length, '| 屏蔽词:', blockKwArr.length); })();
可以用插件屏蔽
@冠希陈 #40 哈哈哈哈 已经厌倦了
@Zelensky #41 在了解了
@NeiNei [#37]是的,常年放货但几乎很少有人买,出都是折价
习惯就好 比甲骨文刷屏好多了 之前甲骨文刷屏全是垃圾消息