您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
使用正则表达式根据用户设置的关键词过滤主题
// ==UserScript== // @name colgThemeFilter // @namespace http://tampermonkey.net/ // @version 0.3 // @description 使用正则表达式根据用户设置的关键词过滤主题 // @author Genmaicha // @license MIT // @match https://bbs.colg.cn/forum* // @icon https://static.colg.cn/image/mobile/images/app-icon.png // @grant none // ==/UserScript== (function() { 'use strict'; const searchUrl = "https://bbs.colg.cn/search.php?mod=forum_list&"; var platformType; const platform = { "电脑版": { "userMenu": "#um", "threadList": "#threadlisttableid", "titleBlock": "tbody", "titleTag": ".s.xst", "newTitleBlock": ".newthread" }, "触屏版": { "userMenu": ".footer", "threadList": ".threadlist", "titleBlock": "li", "titleTag": "a", "newTitleBlock": "" }, "标准版": { "userMenu": ".pd2", "threadList": ".bm", "titleBlock": ".bm_c", "titleTag": "a", "newTitleBlock": "" } } const titleStyle = [{ "id": "prefer", "head": "偏好主题", "styles": { "高亮": "background: #2B65B7;color: #fff;", "红色": "font-weight: bold;color: #EE1B2E;", "自定义": "" } }, { "id": "disgust", "head": "厌恶主题", "styles": { "删除线": "text-decoration-line: line-through;", "隐藏": "display: none;", "自定义": "" } }] Main(); function Main() { checkPlatForm(); createSettingAnchor(); updateAllTheme(); observeNewTheme(); } function checkPlatForm() { for (let key in platform) { let queryStr = platform[key]; let userMenu = document.querySelector(queryStr["userMenu"]); if (userMenu) { platformType = key; continue; } } if (!platformType) { alert("未识别平台类型,无法获取页面信息"); return; } window.addEventListener('load', function() { if (platformType == "触屏版") { try { // 简化界面 let callUpContainer = document.getElementById("callUpContainer"); callUpContainer.style.display = "none"; // 搜索选项 let logo = document.querySelector('.logo-icon'); logo.outerHTML = `<select> <option value=3>全文</option> <option value=4>标题</option> <option value=2>用户</option> </select>` // 搜索框 let serchContainer = document.querySelector('.search-container'); serchContainer.removeAttribute('onclick'); serchContainer.style = "margin-left: 15px;"; let marquee = serchContainer.querySelector('.marquee'); marquee.style.display = 'none'; let input = serchContainer.querySelector('input'); input.type = "search"; input.addEventListener('search',onSearchButtonClick); } catch (e) { window.console.log(e); } } }) } async function onSearchButtonClick(e){ let select = e.target.parentElement.previousElementSibling; let type = select.options[select.selectedIndex].value; let keyword = e.target.value; let url = searchUrl + `type=${type}&keyword=${keyword}`; window.location.href = url; } function createSettingAnchor() { let anchor = document.createElement('a'); anchor.href = "javascript:void(0);"; anchor.textContent = "主题过滤器"; anchor.addEventListener('click', callDialog); let userMenu = document.querySelector((platform[platformType])["userMenu"]); let p = userMenu.querySelector('p'); if (!p) { userMenu.appendChild(anchor); return; } p.appendChild(anchor); } function callDialog() { let userMenu = document.querySelector((platform[platformType])["userMenu"]); let dialog = userMenu.querySelector('dialog'); if (!dialog) { let closeButton = document.createElement('button'); closeButton.textContent = "x"; closeButton.style = "position:absolute;top:0;right:0;border:none;"; closeButton.addEventListener('click', closeDialog); let form = createSettingForm(); dialog = document.createElement('dialog'); dialog.appendChild(closeButton); dialog.appendChild(form); userMenu.appendChild(dialog); } if (typeof dialog.showModal != 'function') { alert("不支持dialog API,请升级你的浏览器"); return; } dialog.showModal(); } function createSettingForm() { let div = document.createElement('div'); let setting = !localStorage.setting ? {} : JSON.parse(localStorage.setting); for (let item of titleStyle) { let ul = document.createElement('ul'); ul.id = item.id; let headli = document.createElement('li'); headli.innerHTML = item.head; ul.appendChild(headli); let selectli = document.createElement('li'); let select = document.createElement('select'); let subsetting = setting[item.id] || {}; for (let key in item.styles) { let option = document.createElement('option'); if (subsetting && subsetting.head && subsetting.head == key) { option.setAttribute('selected', ""); option.value = subsetting.style; } else { option.value = (item.styles)[key]; } option.textContent = key; select.appendChild(option); } select.addEventListener('change', function(e) { let input = e.target.nextElementSibling; input.value = e.target.options[select.selectedIndex].value; }); let input = document.createElement('input'); input.size = 35; input.style = "margin-left:10px;" input.value = select.options[select.selectedIndex].value; selectli.appendChild(select); selectli.appendChild(input); ul.appendChild(selectli); let datali = document.createElement('li'); let keyword = !subsetting ? "" : subsetting["keyword"]; datali.innerHTML = `关键词</br><textarea rows="5" cols="50" placeholder="任意关键词1|关键词2|关键词3">${keyword}</textarea>` ul.appendChild(datali); div.appendChild(ul); } let p = document.createElement('p'); p.style = "text-align: center;"; p.appendChild(createButton("保存", onSaveButtonClick)); p.appendChild(createButton("取消", closeDialog)); div.appendChild(p); return div; } function createButton(text, event) { let button = document.createElement('button'); button.textContent = text; button.style = "margin-right:30px;"; button.addEventListener('click', event); return button; } function onSaveButtonClick(e) { let p = e.target.parentElement; let div = p.parentElement; let uls = div.querySelectorAll('ul'); let setting = {}; for (let i = 0; i < uls.length; i++) { let ul = uls[i]; let select = ul.querySelector('select'); let input = ul.querySelector('input'); let textarea = ul.querySelector('textarea'); setting[ul.id] = { "head": select.options[select.selectedIndex].text, "style": input.value, "keyword": textarea.value } } localStorage.setting = JSON.stringify(setting); localStorage.themeRecord = ""; closeDialog(); alert("保存成功"); updateAllTheme(); } function closeDialog() { let dialog = document.querySelector('dialog'); if (!dialog) { return; } dialog.close(); } function updateAllTheme() { let threadList = document.querySelector((platform[platformType])["threadList"]); if (!threadList) { return; } let anchorParent = threadList.querySelectorAll((platform[platformType])["titleBlock"]); updateThemeStyle(anchorParent); } function observeNewTheme() { let threadList = document.querySelector((platform[platformType])["threadList"]); if(!threadList){ return; } const config = { childList: true }; const threadListOBS = new MutationObserver(updatePartTheme); threadListOBS.observe(threadList, config); } function updatePartTheme() { let threadList = document.querySelector((platform[platformType])["threadList"]); let anchorParent = threadList.querySelectorAll((platform[platformType])["newTitleBlock"]); if(!anchorParent){ return; } updateThemeStyle(anchorParent); } function updateThemeStyle(anchorParent) { if (!localStorage.setting) { alert("请点击主题过滤器设置关键词"); return; } let setting = JSON.parse(localStorage.setting); let themeRecord = !localStorage.themeRecord ? {} : JSON.parse(localStorage.themeRecord); for (let parent of anchorParent) { let anchor = parent.querySelector((platform[platformType])["titleTag"]); if (!anchor) { continue; } let id = anchor.href.match("\\d{2,}").toString(); let title = anchor.textContent; if (themeRecord[id]) { anchor.style = themeRecord[id]; } else { for (var key in setting) { let subsetting = setting[key]; let keyword = subsetting["keyword"]; if (title.search(keyword) != -1) { let style = subsetting["style"]; anchor.style = style; themeRecord[id] = style; } } } if (anchor.style.display == 'none') { block.style.display = 'none'; } } localStorage.themeRecord = JSON.stringify(themeRecord); } })();