您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在排行页面右上角增加按钮,可开启屏蔽模式进行条目屏蔽或管理已屏蔽条目,支持本地持久保存。
当前为
// ==UserScript== // @name Bangumi排行榜条目屏蔽器 // @namespace https://gf.qytechs.cn/zh-CN/scripts/544368 // @version 1.1 // @description 在排行页面右上角增加按钮,可开启屏蔽模式进行条目屏蔽或管理已屏蔽条目,支持本地持久保存。 // @author forary // @license MIT // @match https://bgm.tv/*/browser*sort=rank* // @match https://bangumi.tv/*/browser*sort=rank* // @match https://chii.in/*/browser*sort=rank* // @grant none // ==/UserScript== (function () { 'use strict'; const category = (function () { const path = location.pathname; if (path.startsWith('/anime/')) return 'anime'; if (path.startsWith('/book/')) return 'book'; if (path.startsWith('/music/')) return 'music'; if (path.startsWith('/game/')) return 'game'; if (path.startsWith('/real/')) return 'real'; return 'wrong'; })(); const STORAGE_KEY = `bangumi_rank_blocked_items_${category}`; const SETTINGS_KEY = 'bangumi_rank_user_settings'; function getUserSettings() { const raw = localStorage.getItem(SETTINGS_KEY); return raw ? JSON.parse(raw) : { renumberRanks: true }; } function setUserSettings(settings) { localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings)); } function getBlockedMap() { const raw = localStorage.getItem(STORAGE_KEY); return raw ? JSON.parse(raw) : {}; } function setBlockedMap(map) { localStorage.setItem(STORAGE_KEY, JSON.stringify(map)); } function addToBlockedMap(id, name) { const map = getBlockedMap(); if (!(id in map)) { map[id] = name; setBlockedMap(map); } } function removeFromBlockedMap(id) { const map = getBlockedMap(); if (id in map) { delete map[id]; setBlockedMap(map); } } // v1.1 判断排行榜是否开启筛选 function isFiltered() { const pathname = location.pathname; const searchParams = new URLSearchParams(location.search); // 未筛选时 pathname 是 /anime/browser 或 /anime/browser/ const isCleanPath = pathname === '/anime/browser' || pathname === '/anime/browser/'; // 判断是否包含额外的 pathname 参数,如分类、时间 const isPathFiltered = !isCleanPath; // 判断是否含有筛选用的 query,如 orderby const hasFilterParams = searchParams.has('orderby'); return isPathFiltered || hasFilterParams; } // 更改界面,隐藏当前页面中的已屏蔽条目 function blockExistingItems() { const blockedMap = getBlockedMap(); const items = document.querySelectorAll('li[id^="item_"]'); // 页面中存在的条目列表 items.forEach(item => { const idMatch = item.id.match(/^item_(\d+)$/); // 提取出数值ID if (!idMatch) return; // 失败则跳过 const id = idMatch[1]; if (id in blockedMap) { item.remove(); } }); const settings = getUserSettings(); if (!isFiltered() && settings.renumberRanks) { renumberRanks(); } } // v1.1 更改Rank数值,避免页内数字间隔 function renumberRanks() { const items = Array.from(document.querySelectorAll('li[id^="item_"]')); let rankOffset = (function () { // 从 URL 中读取 page 参数,未指定时为第一页 const pageMatch = location.search.match(/[?&]page=(\d+)/); const page = pageMatch ? parseInt(pageMatch[1], 10) : 1; return (page - 1) * 24; })(); items.forEach((item, index) => { const rankElem = item.querySelector('.rank small'); if (rankElem && rankElem.nextSibling?.nodeType === Node.TEXT_NODE) { rankElem.nextSibling.textContent = (rankOffset + index + 1).toString(); } }); } // 显示每个条目的 “屏蔽” 按钮 function showBlockButtons() { const items = document.querySelectorAll('li[id^="item_"]'); items.forEach(item => { const idMatch = item.id.match(/^item_(\d+)$/); if (!idMatch) return; const id = idMatch[1]; const btn = document.createElement('button'); btn.textContent = '×'; btn.className = 'bangumi-block-btn'; Object.assign(btn.style, { position: 'absolute', bottom: '8px', right: '10px', width: '18px', height: '18px', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '16px', padding: '0', background: '#f66', color: '#fff', border: 'none', borderRadius: '4px', cursor: 'pointer', }); btn.onclick = () => { const nameElem = item.querySelector('.inner h3 a'); const name = nameElem?.textContent?.trim() || '未知标题'; addToBlockedMap(id, name); item.remove(); }; item.style.position = 'relative'; item.appendChild(btn); }); } // 隐藏每个条目的 “屏蔽” 按钮 function hideBlockButtons() { const buttons = document.querySelectorAll('.bangumi-block-btn'); buttons.forEach(btn => { btn.parentElement?.removeChild(btn); }); } // 控制按键 function createControlPanel() { const toggleBtn = document.createElement('button'); toggleBtn.textContent = '添加屏蔽'; Object.assign(toggleBtn.style, { position: 'absolute', right: '90px', padding: '8px 8px', background: '#F09199', color: '#fff', border: 'none', borderRadius: '12px', cursor: 'pointer', fontSize: '12px', lineHeight: '1', }); toggleBtn.onclick = () => { if (toggleBtn.textContent === '添加屏蔽') { showBlockButtons(); toggleBtn.textContent = '退出'; } else { hideBlockButtons(); toggleBtn.textContent = '添加屏蔽'; } }; const showListBtn = document.createElement('button'); showListBtn.textContent = '管理屏蔽'; Object.assign(showListBtn.style, { position: 'absolute', right: '20px', padding: '8px 8px', background: '#F09199', color: '#fff', border: 'none', borderRadius: '12px', cursor: 'pointer', fontSize: '12px', lineHeight: '1', }); showListBtn.onclick = showBlockedList; const header = document.querySelector('#header'); if (header) { header.style.position = 'relative'; header.appendChild(toggleBtn); header.appendChild(showListBtn); } } // 管理界面 function showBlockedList() { // 遮挡 const blocked = getBlockedMap(); const overlay = document.createElement('div'); Object.assign(overlay.style, { position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.5)', zIndex: 10000, display: 'flex', justifyContent: 'center', alignItems: 'center', }); // 粉色主体 const modal = document.createElement('div'); Object.assign(modal.style, { position: 'relative', background: '#F09199', padding: '16px 20px', borderRadius: '10px', width: '300px', maxHeight: '400px', overflowY: 'auto', }); // 标题1 const title1 = document.createElement('h3'); title1.textContent = `设置选项`; title1.style.marginBottom = '10px'; // 标题2 const title2 = document.createElement('h3'); title2.textContent = `已屏蔽${category}条目`; title2.style.marginBottom = '10px'; // 关闭按键 const closeBtn = document.createElement('button'); closeBtn.textContent = '关闭'; Object.assign(closeBtn.style, { position: 'absolute', top: '13px', right: '14px', padding: '4px 8px', background: '#888', color: '#fff', border: 'none', borderRadius: '6px', cursor: 'pointer', fontSize: '12px', }); closeBtn.onclick = () => overlay.remove(); // 设置项 const settingContainer = document.createElement('div'); Object.assign(settingContainer.style, { marginBottom: '15px', fontSize: '13px', display: 'flex', alignItems: 'center', gap: '6px', }); const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = getUserSettings().renumberRanks; checkbox.id = 'renumber-toggle'; checkbox.style.cursor = 'pointer'; const label = document.createElement('label'); label.textContent = '重新编号 Rank 排名'; label.htmlFor = 'renumber-toggle'; // label 绑定 input checkbox.onchange = () => { const settings = getUserSettings(); settings.renumberRanks = checkbox.checked; setUserSettings(settings); }; settingContainer.appendChild(checkbox); settingContainer.appendChild(label); // 内容项 const list = document.createElement('ul'); for (const [id, name] of Object.entries(blocked)) { const li = document.createElement('li'); Object.assign(li.style, { display: 'flex', alignItems: 'center', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', width: '100%', marginBottom: '5px', }); // 创建文本节点(会自动省略过长文本) const textSpan = document.createElement('span'); textSpan.textContent = `${id} - ${name}`; Object.assign(textSpan.style, { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flexGrow: 1, }); const unhideBtn = document.createElement('button'); unhideBtn.textContent = '取消屏蔽'; Object.assign(unhideBtn.style, { marginRight: '8px', padding: '2px 6px', fontSize: '12px', background: '#4CAF50', color: '#fff', border: 'none', borderRadius: '4px', cursor: 'pointer', }); unhideBtn.onclick = () => { removeFromBlockedMap(id); li.remove(); }; li.appendChild(unhideBtn); li.appendChild(textSpan); list.appendChild(li); } modal.appendChild(closeBtn); modal.appendChild(title1); modal.appendChild(settingContainer); modal.appendChild(title2); modal.appendChild(list); overlay.appendChild(modal); document.body.appendChild(overlay); } function init() { blockExistingItems(); createControlPanel(); } window.addEventListener('load', init); const observer = new MutationObserver(() => { blockExistingItems(); }); observer.observe(document.body, { childList: true, subtree: true }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址