您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
适配新版B站消息中心,可自定义保留顶部通知数量
// ==UserScript== // @name b站一键删除消息中心通知(更新可选择性删除) // @namespace http://tampermonkey.net/ // @version 2.1.0 // @description 适配新版B站消息中心,可自定义保留顶部通知数量 // @author szhclear // @match https://message.bilibili.com/* // @icon https://static.hdslb.com/images/favicon.ico // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function() { 'use strict'; // 自定义一次运行的最大次数 const MAX_COUNT = 999; // 等待网页加载完毕 window.addEventListener('load', function() { // 创建控制容器 let container = document.createElement('div'); container.id = "sp-ac-container"; container.style.position = "fixed"; container.style.right = "20px"; container.style.top = "105px"; container.style.zIndex = "999999"; container.style.padding = "15px"; container.style.borderRadius = "8px"; container.style.background = "rgba(0, 0, 0, 0.8)"; container.style.boxShadow = "0 4px 20px rgba(0, 0, 0, 0.5)"; container.style.color = "#fff"; container.style.fontFamily = "sans-serif"; container.style.backdropFilter = "blur(10px)"; container.style.border = "1px solid rgba(255, 255, 255, 0.15)"; container.style.width = "280px"; container.style.maxHeight = "90vh"; container.style.overflowY = "auto"; // 控制面板 container.innerHTML = '<div style="text-align: center; margin-bottom: 15px;">' + '<div style="display: inline-flex; align-items: center; background: rgba(0, 161, 214, 0.2); padding: 5px 15px; border-radius: 20px; margin-bottom: 10px;">' + '<div style="width: 24px; height: 24px; background: #00a1d6; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; margin-right: 8px;">B</div>' + '<div style="font-weight: bold; color: #00a1d6; font-size: 16px;">B站通知清理工具</div>' + '</div>' + '</div>' + '<div style="margin-bottom: 15px;">' + '<label style="display: block; margin-bottom: 8px; font-size: 14px; color: #a0a0c0;">保留顶部通知数量:</label>' + '<div style="display: flex; align-items: center;">' + '<input type="number" id="preserveCount" min="0" value="0" ' + 'style="flex: 1; padding: 10px 12px; border: 1px solid #2d2d4d; ' + 'border-radius: 6px; background: rgba(20, 20, 30, 0.7); color: #fff; font-size: 14px;">' + '<div style="margin-left: 10px; font-size: 12px; color: #8888aa;">0=全部删除</div>' + '</div>' + '</div>' + '<div style="display: flex; justify-content: center; margin-bottom: 15px;">' + '<button id="deleteAllBtn" style="' + 'width: 100%;' + 'padding: 12px;' + 'font-size: 16px;' + 'background: linear-gradient(135deg, #00a1d6, #0087b4);' + 'color: white;' + 'border: none;' + 'border-radius: 6px;' + 'cursor: pointer;' + 'font-weight: bold;' + 'box-shadow: 0 4px 10px rgba(0,0,0,0.3);' + 'transition: all 0.3s;' + '">' + '开始删除通知' + '</button>' + '</div>' + '<div id="progress" style="' + 'padding: 12px;' + 'background: rgba(30, 30, 45, 0.6);' + 'border-radius: 6px;' + 'font-size: 13px;' + 'text-align: center;' + 'margin-bottom: 10px;' + '">' + '<div id="statusText" style="font-size: 14px; margin-bottom: 5px;">准备就绪</div>' + '<div id="countText" style="font-size: 12px; color: #8888aa; margin-bottom: 10px;">保留顶部: 0 条通知</div>' + '<div style="height: 8px; background: rgba(0, 0, 0, 0.3); border-radius: 4px; overflow: hidden;">' + '<div id="progressBar" style="height: 100%; background: linear-gradient(90deg, #00a1d6, #00c1a4); border-radius: 4px; width: 0%; transition: width 0.3s;"></div>' + '</div>' + '</div>' + '<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 10px;">' + '<div style="background: rgba(40, 40, 60, 0.5); border-radius: 6px; padding: 10px; text-align: center;">' + '<div id="deletedCount" style="font-size: 20px; font-weight: bold; color: #00a1d6;">0</div>' + '<div style="font-size: 11px; color: #8888aa;">已删除</div>' + '</div>' + '<div style="background: rgba(40, 40, 60, 0.5); border-radius: 6px; padding: 10px; text-align: center;">' + '<div id="skippedCount" style="font-size: 20px; font-weight: bold; color: #00a1d6;">0</div>' + '<div style="font-size: 11px; color: #8888aa;">已跳过</div>' + '</div>' + '<div style="background: rgba(40, 40, 60, 0.5); border-radius: 6px; padding: 10px; text-align: center;">' + '<div id="errorCount" style="font-size: 20px; font-weight: bold; color: #00a1d6;">0</div>' + '<div style="font-size: 11px; color: #8888aa;">错误</div>' + '</div>' + '</div>' + '<div style="margin-top: 15px; font-size: 10px; color: #666688; text-align: center; padding-top: 10px; border-top: 1px solid rgba(255, 255, 255, 0.05);">' + '设置自动保存,刷新页面后仍然有效' + '</div>'; document.body.appendChild(container); // 添加样式 GM_addStyle( '#deleteAllBtn:hover {' + 'background: linear-gradient(135deg, #0087b4, #006e95) !important;' + 'transform: translateY(-2px);' + 'box-shadow: 0 6px 14px rgba(0,0,0,0.4) !important;' + '}' + '#deleteAllBtn:active {' + 'transform: translateY(0) !important;' + '}' + '#preserveCount:focus {' + 'outline: none;' + 'border-color: #00a1d6 !important;' + 'box-shadow: 0 0 0 3px rgba(0, 161, 214, 0.3) !important;' + '}' + '#sp-ac-container::-webkit-scrollbar {' + 'width: 6px;' + '}' + '#sp-ac-container::-webkit-scrollbar-track {' + 'background: rgba(0,0,0,0.1);' + '}' + '#sp-ac-container::-webkit-scrollbar-thumb {' + 'background: #00a1d6;' + 'border-radius: 3px;' + '}' ); // 加载设置 const preserveCountInput = document.getElementById('preserveCount'); const savedPreserveCount = GM_getValue('biliPreserveCount', 0); preserveCountInput.value = savedPreserveCount; // 保存设置 preserveCountInput.addEventListener('change', function() { const value = parseInt(this.value) || 0; GM_setValue('biliPreserveCount', value); document.getElementById('countText').textContent = `保留顶部: ${value} 条通知`; }); // 初始化 document.getElementById('countText').textContent = `保留顶部: ${savedPreserveCount} 条通知`; document.getElementById('deleteAllBtn').addEventListener('click', startDeletion); async function startDeletion() { const btn = document.getElementById('deleteAllBtn'); const statusText = document.getElementById('statusText'); const countText = document.getElementById('countText'); const preserveCountInput = document.getElementById('preserveCount'); const progressBar = document.getElementById('progressBar'); const deletedCountEl = document.getElementById('deletedCount'); const skippedCountEl = document.getElementById('skippedCount'); const errorCountEl = document.getElementById('errorCount'); // 获取保留数量 let preserveCount = parseInt(preserveCountInput.value); if (isNaN(preserveCount)) preserveCount = 0; preserveCount = Math.max(0, preserveCount); // 保存设置 GM_setValue('biliPreserveCount', preserveCount); countText.textContent = `保留顶部: ${preserveCount} 条通知`; // 禁用按钮 btn.disabled = true; btn.textContent = "删除中..."; btn.style.opacity = "0.7"; btn.style.cursor = "not-allowed"; statusText.textContent = "开始删除..."; statusText.style.color = "#fff"; // 重置统计 let deletedCount = 0; let skippedCount = 0; let errorCount = 0; deletedCountEl.textContent = "0"; skippedCountEl.textContent = "0"; errorCountEl.textContent = "0"; try { for (let i = 0; i < MAX_COUNT; i++) { // 更新进度条 const progressPercent = Math.min(100, Math.floor(i / MAX_COUNT * 100)); progressBar.style.width = `${progressPercent}%`; // 获取所有删除按钮 const deleteButtons = document.querySelectorAll('.interaction-item__btn.invisible.delete'); if (!deleteButtons || deleteButtons.length === 0) { statusText.textContent = "未找到更多通知"; break; } // 计算要删除的索引(跳过前preserveCount个) const indexToDelete = preserveCount; if (indexToDelete >= deleteButtons.length) { statusText.textContent = `已完成 (保留 ${preserveCount} 条)`; break; } // 获取要删除的按钮 const deleteBtn = deleteButtons[indexToDelete]; // 点击删除按钮 try { deleteBtn.click(); await sleep(300); // 获取确认按钮 const confirmBtn = document.querySelector('.b-modal-confirm'); if (confirmBtn) { confirmBtn.click(); deletedCount++; deletedCountEl.textContent = deletedCount; statusText.textContent = `正在删除通知 ${i+1}/${MAX_COUNT}`; statusText.style.color = "#00a1d6"; } else { errorCount++; errorCountEl.textContent = errorCount; statusText.textContent = "未找到确认按钮"; statusText.style.color = "#f44336"; } } catch (e) { errorCount++; errorCountEl.textContent = errorCount; console.error("删除过程中出错:", e); statusText.textContent = `错误: ${e.message || "未知错误"}`; statusText.style.color = "#f44336"; } await sleep(500); } if (deletedCount > 0) { statusText.textContent = `删除完成!`; statusText.style.color = "#4caf50"; progressBar.style.width = "100%"; progressBar.style.background = "#00c853"; } else { statusText.textContent = "没有需要删除的通知"; statusText.style.color = "#ff9800"; progressBar.style.width = "100%"; progressBar.style.background = "#ff9800"; } } catch (e) { console.error("删除过程中出错:", e); statusText.textContent = "操作出错,请重试"; statusText.style.color = "#f44336"; progressBar.style.background = "#f44336"; } finally { // 恢复按钮状态 btn.disabled = false; btn.textContent = "开始删除通知"; btn.style.opacity = "1"; btn.style.cursor = "pointer"; } } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } }); })();