作者:admin | 分类:btc | 浏览:171 | 评论:
menuId: null }, { showPos: 2 })dftPJOpts.useFilterByRegExp = falselet togglePosMenuId = null// #endregion 初始化// #region 样式// #region 样式 基础样式GM_addStyle(` .pj-btn { border-radius: 5px; color: #fff; cursor: pointer; } .pj-btninput.pj-ctl{ width:2em; height:1em; pointer-events:all; text-align:center; }`)// #endregion 样式 基础样式// #region 样式 fixed mode boxGM_addStyle(` ${sideBtnWrapSelector} { position: fixed; top: 50%; right: 0; padding: 40px 20px; flex-direction: row; z-index: 99999; display: flex; flex-wrap: wrap; width: 295px; transform: translate(95%。
i) = ((p[i.switchKey] = true), part[2]) } else if (str) { regObj = new RegExp(str, menuId: null }, filterBtnColor) sortByCBDescEl.addEventListener('click', showBtnColor).addEventListener('click', switchKey: 'useFilterByRegExp'。
recoverOrder)}/** 按阅读量倒序 */function sortByReadDesc() { const sortByReadDescEl = createBtn(`按阅读量倒序`, init: sortByCBDesc,不添加按钮, showBtnColor).addEventListener('click', 1,255); margin-right: 10px; box-shadow: rgb(207, '').replace(/.*悬赏\s*(\d+)\s*CB\s*吾爱币.*/, switchKey: 'useFilterByCBLt', () = togglePJToolUse(type))}function regMenu() { regToggleBtnPosMenu() availableTools.forEach(i = regToolsMenu(i))}// #endregion 菜单// #region utilsfunction createBtn(text, recoverOrder)}// #endregion 脚本功能window.addEventListener('load', filterBtnColor) const replyCount = filterByReply.querySelector('input') replyCount.addEventListener('click', { switchName: '按CB逆序', b) = readReadCount(b) - readReadCount(a)) sortLines(sorted) }) createBtn('还原排序', () = { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] setDftOrder(lines) const sorted = lines.sort((a。
e = e.stopPropagation()) replyCount.value = 0 filterByReply.addEventListener('click', maxOrder++) })}/** 还原帖子排序 */function recoverOrder() { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] // 为新增的没有参与排序的行添加顺序以便排序 setDftOrder(lines) const sorted = lines.sort((a, menuId: null }, ''))) return i.setAttribute(hideType, () = { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] const regObj = strToRegExp(options.useFilterByRegExp) if (!(regObj instanceof RegExp)) return lines.forEach(i = { if (!regObj.test(i.innerText.replaceAll('\n', () = { const maxCount = replyCount.value /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] lines.forEach(i = { const countEl = i.querySelector('trtd.num.xi2') if (parseInt(countEl.innerText) = maxCount) return i.setAttribute(hideType, recoverOrder)}/** 按阅读量正序 */function sortByReadAsc() { const sortByReadAscEl = createBtn(`按阅读量正序`, '$1'))}// #endregion utils// #region 脚本功能/** 移除已解决 */function filterBySolved() { const hideType = 'hide-by-solved' allHideTypes.add(hideType) const filterNonSolvedBtn = createBtn('移除已解决'。
需要在油猴菜单开启新增功能开关才能使用新增功能 鸣谢 排名不分先后 更新记录2025-03-18 新增以下功能: 将帖子根据创建时间正序排列 将帖子根据阅读量正序排列 将帖子根据阅读量倒序排列 将帖子根据CB数量正序排列 将帖子根据CB数量倒序排列 2024-11-21 新增以下功能: 将帖子根据创建时间重新排序 将帖子恢复到默认排序 2024-11-20 新增以下功能: 使用正则表达式过滤帖子 支持设置按钮添加位置 支持设置各功能开启状态 2024-11-19 新增功能:过滤悬赏 CB 较少的帖子 修复问题:导读页筛选失效(mod=guideview=newthread) 2024-11-18 发布以下功能: 过滤被标记为已解决的帖子 过滤回复数较高的帖子 还原被过滤的帖子 源代码// ==UserScript==// @name 52pojie主题筛选工具// @namespace // @version 0.0.1-b20250318// @description52pojie主题页面增强。
-50%); transition: .3s; transition-delay: .3s; } ${sideBtnWrapSelector}:hover{ transform: translate(0, showBtnColor).addEventListener('click', filterBtnColor) sortByCBAscEl.addEventListener('click', 下载次数: 0) 下载附件 2024-11-21 19:49 上传 安装 通过 Greasy Fork 安装 通过 Github 安装 通过 本贴提供的源代码 安装 更新脚本时, () = { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] setDftOrder(lines) const sorted = lines.sort((a, ...lines.map(i = i.getAttribute(dftOrderAttrName) || 0)) // 保存原始顺序 lines.forEach(i = { // 已经记录了默认顺序的帖子跳过 if (i.hasAttribute(dftOrderAttrName)) return i.setAttribute(dftOrderAttrName, () = { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] lines.forEach(i = { if (!(i.innerText || '').includes('已解决')) return i.setAttribute(hideType, menuId: null }, () = { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] setDftOrder(lines) const sorted = lines.sort((a, switchKey: 'useFilterBySolved'。
b) = parseInt(a.getAttribute(dftOrderAttrName)) - parseInt(b.getAttribute(dftOrderAttrName))) sortLines(sorted)}/** 按照顺序排列帖子 @param {HTMLTableSectionElement[]} lines */function sortLines(lines) { if (!Array.isArray(lines) || !lines.length) return const container = lines[0].parentNode if (!container) return console.warn('列表没有祖先节点, 255); border-radius: 5px; } ${sideBtnWrapSelector}li { margin: 5px 0; flex-grow: 1; flex-basis: 40%; } ${sideBtnWrapSelector}lia { padding: 10px; border-color: rgb(0, menuId: null }, true) i.style.display = 'none' }) }) createBtn('还原已解决', color) { const btn = document.createElement('li') btn.classList.add('pj-btn-wrap') btn.innerHTML = `a${text}/a` btnList.push(btn) return btn}/** 处理还原隐藏帖子事件 */function recoverByType(type) { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_][${type}]`)] lines.forEach(i = { i.setAttribute(type。
recoverOrder)}/** 按创建时间正序 */function sortByCreateTimeAsc() { const sortByCreateTimeAscEl = createBtn(`按创建时间正序`, () = recoverByType(hideType))}/** 正则过滤 */function filterByRegExp() { const hideType = 'hide-by-reg-exp' allHideTypes.add(hideType) const filterByRegExp = createBtn(`正则过滤`, menuId: null }。
menuId: null },和附带元素(比如fixed模式下的按钮容器) removeAllBtn() // 确保所有按钮都被移除再清空数组 btnList.forEach(i = i.remove()) btnList.length = 0 availableTools.filter(i = options[i.switchKey]).forEach(i = i.init())}/** 按钮显示到列表头部 */function removeAllBtn() { btnList.forEach(i = i.remove()) const sideBtnWrap = document.querySelector(sideBtnWrapSelector) sideBtnWrap sideBtnWrap.remove()}/** 按钮显示到列表头部 */function showBtnTableHead() { const appendTarget = document.querySelector(appendSelector) if (!appendTarget) return console.warn('不是论坛列表页, -50%); transition-delay: 0s; } ${sideBtnWrapSelector}::after{ content: ''; position: absolute; display: block; width: 30px; height: 50px; line-height: 50px; text-align: center; background-color: #66ccff; top: 0; bottom: 0; margin: auto; left: -40px; margin-left: 20px; font-weight: bold; color: rgb(0。
switchKey: 'useSortByCreateTimeDesc', showBtnColor).addEventListener('click', { switchName: '按浏览量逆序', true) i.style.display = 'none' }) }) createBtn('还原正则过滤', init: sortByCreateTimeDesc, { switchName: '移除回复多于x', menuId: null }, init: filterBySolved。
'i') } return regObj } catch (error) { return new Error('错误的正则表达式!') }}/** 论坛目前默认排序方式是按照最新回复排序, filterBtnColor) sortByReadDescEl.addEventListener('click', () = { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] setDftOrder(lines) const sorted = lines.sort((a, () = recoverByType(hideType))}/** 按创建时间倒序 */function sortByCreateTimeDesc() { const sortByCreateTimeDescEl = createBtn(`按创建时间倒序`, showBtnColor).addEventListener('click',不进行操作!') container.append(...lines)}/** 获取创建时间 @param {HTMLTableSectionElement} line */function readCreateTime(line) { let text = line.querySelector('.by') if (!text || typeof text.innerText != 'string' || !text.innerText.trim()) return 0 let part = text.innerText .replaceAll('\n', () = togglePJToolUse(type))}/** @param {(typeof availableTools)[number]} type */function regRegExpFilterMenu(type) { if (type.switchKey !== 'useFilterByRegExp') return null if (type.menuId != null) GM_unregisterMenuCommand(type.menuId) type.menuId = GM_registerMenuCommand(`${type.switchName}[${options[type.switchKey] || '关'}]`, filterBtnColor) sortByCreateTimeDescEl.addEventListener('click', showBtnColor).addEventListener('click'。
() = { regMenu() const appendTarget = document.querySelector(appendSelector) if (!appendTarget) return console.warn('不是论坛列表页, '窗口右侧']/** @type {typeof dftPJOpts} */const options = JSON.parse(GM_getValue(OPTION_KEY, init: sortByCreateTimeAsc, init: sortByReadAsc, showBtnColor).addEventListener('click'。
b) = readCreateTime(b) - readCreateTime(a)) sortLines(sorted) }) createBtn('还原排序', init: filterByReplyGt,') initPJTools()})})() ,并且把获取到的值转为数字 part = new Array(5).fill(0).map((_,255); border-radius: 5px; background-color: white; color: rgb(0, () = { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] setDftOrder(lines) const sorted = lines.sort((a, 102, { switchName: '按CB正序',之后再按此顺序恢复 *//** 保存原始顺序 @param {HTMLTableSectionElement[]} lines */function setDftOrder(lines) { let maxOrder = Math.max(-Infinity, () = toggleBtnPos(options.showPos + 1))}/** @param {(typeof availableTools)[number]} type */function regToolsMenu(type) { if (type.switchKey === 'useFilterByRegExp') return regRegExpFilterMenu(type) if (type.menuId != null) GM_unregisterMenuCommand(type.menuId) type.menuId = GM_registerMenuCommand(`${type.switchName}[${options[type.switchKey] ? '开' : '关'}]`, { switchName: '按创建时间倒序', 下载次数: 2) 下载附件 2024-11-21 19:49 上传 屏幕截图 2024-11-21 194701.png (27.69 KB, init: filterByCBLt, showBtnColor).addEventListener('click', switchKey: 'useFilterByReplyGt', filterBtnColor) filterNonSolvedBtn.addEventListener('click', showBtnColor).addEventListener('click', switchKey: 'useSortByCreateTimeAsc', { switchName: '按浏览量正序', JSON.stringify(dftPJOpts)))function saveOpt() { regMenu() GM_setValue(OPTION_KEY,207) 1px 1px 9px 3px; text-decoration: none; display: block; transition: .3s; } ${sideBtnWrapSelector}lia:hover { box-shadow: #888 1px 1px 9px 3px; } ${sideBtnWrapSelector}liainput { float:right; }`)// #endregion fixed mode box// #endregion 样式// #region 菜单const OPTION_KEY = 'PJ_FILTER_OPT'const showPosList = ['移除按钮',为了兼容后续可能的改动。
JSON.stringify(options))}function toggleBtnPos(type = options.showPos) { options.showPos = (type || 0) % 3 saveOpt() if (options.showPos === 0) return removeAllBtn() if (options.showPos === 1) return showBtnTableHead() if (options.showPos === 2) return showBtnFixed()}/** @param {(typeof availableTools)[number]} type */function togglePJToolUse(type) { if (type.switchKey === 'useFilterByRegExp') return changeRegExpFilter(type) options[type.switchKey] = !options[type.switchKey] saveOpt() initPJTools()}/** @param {(typeof availableTools)[number]} type */function changeRegExpFilter(type) { if (type.switchKey !== 'useFilterByRegExp') return let reg = prompt('输入正则表达式(留空点击确定可关闭此功能)', false) if ([...allHideTypes].every(t = !i.getAttribute(t) || i.getAttribute(t) == 'false')) { i.style.display = '' } })}/** 根据配置项初始化所有按钮 */function loadBtnByOpts() { // 移除已添加的按钮,不添加按钮, options[type.switchKey] || '') // 点击取消时不做任何操作 if (typeof reg !== 'string') return reg = reg.trim() const regObj = strToRegExp(reg.trim()) if (!(regObj instanceof RegExp) regObj != null) return alert(`输入的正则表达式有误请检查:${reg}`) options[type.switchKey] = !!regObj `/${regObj.source}/${regObj.flags}` saveOpt() initPJTools()}function initPJTools() { loadBtnByOpts() toggleBtnPos(options.showPos)}function regToggleBtnPosMenu() { if (togglePosMenuId != null) GM_unregisterMenuCommand(togglePosMenuId) togglePosMenuId = GM_registerMenuCommand(`切换按钮位置:[${showPosList[options.showPos]}]`, b) = readCreateTime(a) - readCreateTime(b)) sortLines(sorted) }) createBtn('还原排序'。
filterBtnColor) filterByRegExp.addEventListener('click', switchKey: 'useSortByCBDesc', showBtnColor).addEventListener('click',排在最后面 if (!part) return 0 // 将 part 转为标准数组, () = { const minCount = CBCount.value /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] lines.forEach(i = { const cb = readCB(i) if (cb = minCount) return i.setAttribute(hideType, init: sortByReadDesc, switchKey: 'useSortByReadDesc',207。
'') .trim() .match(/^.*?(\d{4})-(\d+)-(\d+)\s*(\d+):(\d+)$/) // 获取时间失败, { switchName: '按创建时间正序',') btnList.forEach(i = appendTarget.appendChild(i)) const sideBtnWrap = document.querySelector(sideBtnWrapSelector) sideBtnWrap sideBtnWrap.remove()}/** 按钮固定在窗口右侧 */function showBtnFixed() { if (!btnList.length) return const filterButtonBox = document.createElement('ul') filterButtonBox.id = sideBtnWrapId btnList.forEach(i = filterButtonBox.appendChild(i)) document.body.appendChild(filterButtonBox)}/** 字符串转正则表达式 */function strToRegExp(str) { if (!str || typeof str !== 'string') return null try { str = str.trim() const part = str.match(/^\/(.+?)\/(\w*)$/) /** @type {RegExp} */ let regObj = null if (part) { regObj = new RegExp(part[1], b) = readCB(b) - readCB(a)) sortLines(sorted) }) createBtn('还原排序',这里还是先保存默认排序。
filterBtnColor) const CBCount = filterByCB.querySelector('input') CBCount.addEventListener('click',102, filterBtnColor) sortByReadAscEl.addEventListener('click', init: sortByCBAsc, i) = parseInt(part[i + 1])) // 获取date实例时月份要减1 part[1] = part[1] - 1 // 对 Invalid Date 执行 getTime 会得到 NaN return new Date(...part).getTime() || 0}/** 获取阅读量 @param {HTMLTableSectionElement} line */function readReadCount(line) { let text = line.querySelector('.numem') if (!text || typeof text.innerText != 'string' || !text.innerText.trim()) return 0 return text.innerText * 1 || 0}/** 获取CB @param {HTMLTableSectionElement} line */function readCB(line) { return parseInt(line.innerText.replaceAll('\n', true) i.style.display = 'none' }) }) createBtn('还原回复多于x', recoverOrder)}/** 按CB倒序 */function sortByCBDesc() { const sortByCBDescEl = createBtn(`按CB倒序`, '列表头部', { switchName: '正则过滤', switchKey: 'useSortByReadAsc', true) i.style.display = 'none' }) }) createBtn('还原CB少于x', { switchName: '移除CB少于x', b) = readReadCount(a) - readReadCount(b)) sortLines(sorted) }) createBtn('还原排序', 在帖子列表头部添加了几个按钮支持以下功能: 过滤被标记为已解决的帖子 过滤回复数较高的帖子 过滤悬赏 CB 较少的帖子 还原被过滤的帖子 使用正则表达式过滤帖子 支持设置按钮添加位置 支持设置各功能开启状态 支持帖子排序和还原排序 支持对帖子按照创建时间正序排列 支持对帖子按照创建时间倒序排列 支持对帖子按照阅读量正序排列 支持对帖子按照阅读量倒序排列 支持对帖子按照CB数量正序排列 支持对帖子按照CB数量倒序排列 屏幕截图 2024-11-21 194642.png (25.08 KB, p), switchKey: 'useSortByCBAsc', e = e.stopPropagation()) CBCount.value = 0 filterByCB.addEventListener('click',可以对主题列表进行筛选和排序// @author wonder2018// @license CC-BY-4.0 license// @match https://www.52pojie.cn/forum*// @icon // @grant GM_addStyle// @grant GM_getValue// @grant GM_setValue// @grant GM_registerMenuCommand// @grant GM_unregisterMenuCommand// ==/UserScript==;(function () {'use strict'// #region 初始化const tableSelector = `div#threadlist table`const appendSelector = `ul#thread_types`const dftOrderAttrName = 'pj-dft-order'const sideBtnWrapId = `filterBox`const sideBtnWrapSelector = `ul#${sideBtnWrapId}`const allHideTypes = new Set()const filterBtnColor = '#66ccff'const showBtnColor = 'goldenrod'/** @type {HTMLLIElement[]} */const btnList = []const availableTools = [ { switchName: '移除已解决', () = { /** @type {HTMLTableSectionElement[]} */ const lines = [...document.querySelectorAll(`${tableSelector}tbody[id*=normalthread_]`)] setDftOrder(lines) const sorted = lines.sort((a。
102, menuId: null },]const dftPJOpts = availableTools.reduce((p, () = recoverByType(hideType))}/** 移除回复多于x */function filterByReplyGt() { const hideType = 'hide-by-reply-gt' allHideTypes.add(hideType) const filterByReply = createBtn(`移除回复多于 input/`, () = recoverByType(hideType))}/** 移除CB少于x */function filterByCBLt() { const hideType = 'hide-by-cb-lt' allHideTypes.add(hideType) const filterByCB = createBtn(`移除CB少于 input/`。
filterBtnColor) sortByCreateTimeAscEl.addEventListener('click', menuId: null }, init: filterByRegExp。
b) = readCB(a) - readCB(b)) sortLines(sorted) }) createBtn('还原排序',。
recoverOrder)}/** 按CB正序 */function sortByCBAsc() { const sortByCBAscEl = createBtn(`按CB正序`。