您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
按 Ctrl+Alt+E 展开所有B站评论(运行中持续提示)
// ==UserScript== // @name B站展开所有评论(Ctrl + Alt + E) // @namespace http://tampermonkey.net/ // @version 2025-07-31 // @description 按 Ctrl+Alt+E 展开所有B站评论(运行中持续提示) // @author You // @match https://www.bilibili.com/* // @grant none // ==/UserScript== (function () { 'use strict'; const sleep = ms => new Promise(res => setTimeout(res, ms)); //持久 Toast(返回DOM元素) function showToastPersistent(message) { const toast = document.createElement("div"); toast.textContent = message; toast.style.position = "fixed"; toast.style.top = "0px"; toast.style.left = "50%"; toast.style.transform = "translateX(-50%)"; toast.style.background = "rgba(0, 0, 0, 0.75)"; toast.style.color = "#fff"; toast.style.padding = "10px 16px"; toast.style.borderRadius = "8px"; toast.style.fontSize = "18px"; toast.style.zIndex = 9999; toast.style.boxShadow = "0 2px 6px rgba(0,0,0,0.3)"; toast.style.opacity = "0"; toast.style.transition = "opacity 0.3s ease"; document.body.appendChild(toast); requestAnimationFrame(() => toast.style.opacity = "1"); return toast; } // ✅ 替换内容 & 自动消失 function replaceToast(toastEl, newMsg, delay = 3000) { toastEl.textContent = newMsg; setTimeout(() => { toastEl.style.opacity = "0"; setTimeout(() => toastEl.remove(), 300); }, delay); } function getLoadedCommentCount() { try { const shadowHost = document.querySelector("#commentapp > bili-comments"); if (!shadowHost || !shadowHost.shadowRoot) return 0; const shadowRoot = shadowHost.shadowRoot; const items = shadowRoot.querySelectorAll("#feed > bili-comment-thread-renderer"); return items.length; } catch (e) { console.warn('获取评论数失败', e); return 0; } } async function scrollAndWaitForMoreComments(lastCount) { window.scrollTo(0, document.documentElement.scrollHeight); await sleep(1200); const newCount = getLoadedCommentCount(); console.log(`滚动后评论数:${newCount},上次:${lastCount}`); return newCount > lastCount ? newCount : lastCount; } async function loadAllComments(maxScrolls = 30) { for (let i = 0; i < 20; i++) { if (document.querySelector("#commentapp > bili-comments")) break; await sleep(500); } let lastCount = 0; for (let i = 0; i < maxScrolls; i++) { const newCount = await scrollAndWaitForMoreComments(lastCount); if (newCount === lastCount) { console.log('评论数未增加,可能加载完毕,停止滚动'); break; } lastCount = newCount; } console.log(`最终加载评论数: ${lastCount}`); } async function expandAllClickToView() { const mainHost = document.querySelector("#commentapp > bili-comments"); if (!mainHost || !mainHost.shadowRoot) { console.warn('找不到评论组件'); return; } const mainRoot = mainHost.shadowRoot; const threads = mainRoot.querySelectorAll("#feed > bili-comment-thread-renderer"); let count = 0; for (const thread of threads) { const threadRoot = thread.shadowRoot; if (!threadRoot) continue; const replies = threadRoot.querySelector("#replies > bili-comment-replies-renderer"); if (!replies || !replies.shadowRoot) continue; const viewMore = replies.shadowRoot.querySelector("#view-more > bili-text-button"); if (viewMore) { try { viewMore.click(); count++; await sleep(300); } catch (e) { console.warn("点击失败", e); } } } console.log(`展开“点击查看”按钮数量:${count}`); } async function main() { const toast = showToastPersistent("正在展开评论..."); await loadAllComments(); await expandAllClickToView(); replaceToast(toast, "所有评论已展开", 3000); } // 快捷键监听:Ctrl + Alt + E document.addEventListener('keydown', function (e) { if (e.ctrlKey && e.altKey && e.key.toLowerCase() === 'e') { main(); } }); })();