您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
置顶未读消息,自动滚动消息列表到底部,查看下一条未读
// ==UserScript== // @name 置顶bilibili未读私信 // @namespace http://tampermonkey.net/ // @version 2025.2.27 // @description 置顶未读消息,自动滚动消息列表到底部,查看下一条未读 // @author 悠亚Yua的洗脚俾 // @match https://message.bilibili.com/* // @icon https://www.bilibili.com/favicon.ico // @run-at document-end // @license MIT // ==/UserScript== /* jshint esversion: 8 */ const CLASS = { CONTAINER: '.list-container', // 消息列表 LIST: '.list', // 侧边功能栏列表元素 ITEM: '.list-item', // 消息列表内对话人 NOTIFY: 'div.notify-number', // 消息列表内红点标识 SIDE_BAR: '.side-bar', // 侧边功能栏 NOTIFY_TOTAL: 'span.notify-number' }; const MAX_ATTEMPTS = 30; // 限制尝试次数,考虑到ua的群发一般在500内设为30次 // 创建能自然融入侧边栏的元素 const createScopedElement = (tag, cls, text='')=> { const element = document.createElement(tag); element.className = cls; element.setAttribute('data-v-60ecf32f', ''); if(tag==='li'){ const link = document.createElement('a'); link.href = 'javascript:void(0);'; link.setAttribute('data-v-60ecf32f', ''); // 添加文本节点 const textNode = document.createTextNode(text); link.appendChild(textNode); element.appendChild(link); } return element; }; // 下一条未读消息 const nextMsg = async () => { const container = document.querySelector(CLASS.CONTAINER); if (!document.querySelector(CLASS.NOTIFY_TOTAL)) { // 查看侧边栏我的消息是否有红点 console.log('没有新消息的说'); return; } // 查找未读消息 const findUnreadMsg = async () => { let unreadMsg = document.querySelector(CLASS.NOTIFY); // 查看已加载对话中是否有未读 let attempts = 0; while (!unreadMsg && attempts < MAX_ATTEMPTS) { // 循环直到找到消息或最大次数 container.scrollTop = container.scrollHeight; // 滚动到底部 await new Promise(resolve => setTimeout(resolve, 500)); // 等待 500 毫秒让 DOM 更新 unreadMsg = document.querySelector(CLASS.NOTIFY); // 再次查找 attempts++; } if (unreadMsg) { unreadMsg.scrollIntoView(); setTimeout(() => unreadMsg.click(), 300); // 点击前稍微延迟 } else { alert('未在限制次数内找到未读消息,可再次点击继续查找'); } }; await findUnreadMsg(); }; // 未读消息置顶 const moveNewMessageToTop = () => { const container = document.querySelector(CLASS.CONTAINER); // 消息列表容器 let total = document.querySelector(CLASS.NOTIFY_TOTAL).textContent; // 未读总数 let msgs = document.querySelectorAll(CLASS.NOTIFY); // 列表内的未读消息标识 // 置顶消息 const move = () =>{ msgs = document.querySelectorAll(CLASS.NOTIFY); console.log(msgs.length); if (msgs.length>=total) { for (let i = msgs.length - 1; i >= 0; i--) { // 反向遍历维持原时间顺序 container.prepend(msgs[i].parentElement); } container.scrollTop = 0; // 回到顶部 return true; } return false; } // 页面中的未读消息数小于总数则自动滚动加载更多消息 if (container){ if (move()) return; let intervalId = null; let attempts = 0; intervalId = setInterval(() => { if (!move()&&attempts < MAX_ATTEMPTS) { container.scrollTop = container.scrollHeight; // 滚动到消息列表底部 attempts++; }else{ clearInterval(intervalId); } }, 500); } }; // 自动滚动加载消息 const setupAutoScroll = (button) => { let intervalId = null; const toggleScroll = () => { const container = document.querySelector(CLASS.CONTAINER); if (!container) return; // 每500ms滚动到底部一次,再次点击停止滚动 if (!intervalId) { intervalId = setInterval(() => { container.scrollTop = container.scrollHeight; }, 500); button.firstChild.textContent = '停止滚动'; } else { clearInterval(intervalId); intervalId = null; button.firstChild.textContent = '滚动加载'; } }; return toggleScroll; }; /* 初始化 */ const init = () => { // 创建插件title const title = createScopedElement('div', 'title'); title.textContent='UQU 私信小助手'; // 创建容纳按钮的list const ul = createScopedElement('ul', 'list'); // 创建list内的item const pinButton = createScopedElement('li', 'item', '未读置顶' ); const loadButton = createScopedElement('li', 'item', '滚动加载'); const nextButton = createScopedElement('li', 'item', '下个未读'); // 设置按钮功能 pinButton.addEventListener('click', moveNewMessageToTop); loadButton.addEventListener('click', setupAutoScroll(loadButton)); nextButton.addEventListener('click', nextMsg); // 添加按钮到列表 [pinButton, loadButton, nextButton].forEach(item=>{ ul.appendChild(item); }); // 等待目标容器加载 const observer = new MutationObserver((_, obs) => { const spaceLeft = document.querySelector(CLASS.SIDE_BAR); if (spaceLeft) { spaceLeft.append(title); spaceLeft.append(ul); obs.disconnect(); console.log('list已注入'); } }); observer.observe(document, { childList: true, subtree: true }); }; // 启动脚本 init();