您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Based on AttachHowOldtoUserinPosts, to tag users in Bangumi. Now with clickable badges to edit notes.
当前为
// ==UserScript== // @name TagBangumiUserPro 班固米用户备注 // @version 3.0 // @description Based on AttachHowOldtoUserinPosts, to tag users in Bangumi. Now with clickable badges to edit notes. // @author age_anime // @match https://bgm.tv/* // @match https://chii.in/* // @match https://bangumi.tv/* // @grant none // @license MIT // @namespace https://gf.qytechs.cn/users/1426310 // ==/UserScript== (function () { 'use strict'; // 3.0版本说明:将零散的userNote_集中管理,避免对网页缓存产生较大负担。减少外显按钮,尽可能减少对bangumi原界面的影响。 // 组件函数功能说明:(数据保存在本地,显示和修改在前端,可直接修改和清除) // displayUserNote(userId, note):在指定用户的用户名旁边显示备注标签 // markUserNotes():显示对应的备注标签 // openUserNoteManager():用户备注管理界面 // openColorManager():颜色管理界面 // addButtonFunctions():添加功能按钮 // 默认颜色配置 const defaultNoteColors = { "预设0": "#40E0D0", "预设1": "#BB44BB", "预设2": "#000000", "预设3": "#DD6D22", "预设4": "#CC3333", "预设5": "#DD6D22", "设置6": "#3C3CC4" }; let noteColors = JSON.parse(localStorage.getItem('userNoteColors_')) || defaultNoteColors; // 用户备注配置(默认为空白,) let userNoteTable_AGE = JSON.parse(localStorage.getItem('userNoteTable_AGE')) || {}; // 旧版本兼容:迁移原先零散的数据,集中在userNoteTable_AGE(AGE是作者的用户名,避免和其他组件冲突,求求审核别和之前的混为一谈) Object.keys(localStorage).forEach(key => { if (key.startsWith('userNote_')) { const userId = key.substring('userNote_'.length); userNoteTable_AGE[userId] = localStorage.getItem(key); localStorage.removeItem(key); } }); localStorage.setItem('userNoteTable_AGE', JSON.stringify(userNoteTable_AGE)); const defaultNote = "bgmer"; const defaultColor = "rgba(102, 170, 85, 0.2)"; function displayUserNote(userId, note) { const userAnchor = $("strong a.l[href='/user/" + userId + "']"); if (userAnchor.length > 0 && userAnchor.next(".note-badge").length === 0) { const badgeColor = noteColors[note] || defaultColor; const badge = $(` <span class="note-badge" style=" background-color: ${badgeColor}; font-size: 11px; padding: 2px 5px; color: #FFF; border-radius: 100px; line-height: 150%; display: inline-block; cursor: pointer; " title="点击编辑备注">${note}</span>`); badge.click(function () { const newNote = prompt("请输入新的备注:", note); if (newNote !== null) { const trimmedNote = newNote.trim(); if (trimmedNote === "") { delete userNoteTable_AGE[userId]; localStorage.setItem('userNoteTable_AGE', JSON.stringify(userNoteTable_AGE)); badge.remove(); } else if (trimmedNote !== note) { userNoteTable_AGE[userId] = trimmedNote; localStorage.setItem('userNoteTable_AGE', JSON.stringify(userNoteTable_AGE)); badge.text(trimmedNote); const newBadgeColor = noteColors[trimmedNote] || defaultColor; badge.css("background-color", newBadgeColor); } } }); userAnchor.after(badge); } } function markUserNotes() { $(".note-badge").remove(); $("strong a.l:not(.avatar)").each(function () { const userLink = $(this).attr("href"); const userId = userLink.split("/").pop(); const note = userNoteTable_AGE[userId] || defaultNote; displayUserNote(userId, note); }); } // 按钮颜色管理区 function openColorManager() { const modal = document.createElement('div'); Object.assign(modal.style, { position: 'fixed', left: '50%', top: '50%', transform: 'translate(-50%, -50%)', backgroundColor: 'white', padding: '20px', borderRadius: '5px', boxShadow: '0 0 10px rgba(0,0,0,0.5)', zIndex: '9999', width: '450px' }); // 添加颜色 const form = document.createElement('div'); form.style.marginBottom = '5px'; const nameLabel = document.createElement('label'); nameLabel.textContent = '名称:'; nameLabel.style.color = '#333333'; nameLabel.style.marginRight = '5px'; const nameInput = document.createElement('input'); nameInput.type = 'text'; nameInput.style.minWidth = '240px'; nameInput.style.width = 'auto'; nameInput.style.height = '22px'; nameInput.style.marginRight = '5px'; nameInput.style.position = 'relative'; nameInput.style.top = '-5px'; const colorLabel = document.createElement('label'); colorLabel.textContent = '颜色:'; colorLabel.style.color = '#333333'; colorLabel.style.marginRight = '5px'; const colorInput = document.createElement('input'); colorInput.type = 'color'; colorInput.style.marginRight = '5px'; const addButton = document.createElement('button'); addButton.textContent = '添加'; addButton.onclick = () => { const name = nameInput.value.trim(); const color = colorInput.value; if (name && color) { noteColors[name] = color; textarea.value = JSON.stringify(noteColors, null, 4); nameInput.value = ''; colorInput.value = '#000000'; } else { alert('名称和颜色不能为空!'); } }; form.append(nameLabel, nameInput, colorLabel, colorInput, addButton); const textarea = document.createElement('textarea'); textarea.style.cssText = 'width: 100%; height: 200px; margin-bottom: 10px;'; textarea.value = JSON.stringify(noteColors, null, 4); const buttonContainer = document.createElement('div'); buttonContainer.style.cssText = 'text-align: right;'; const cancelBtn = document.createElement('button'); cancelBtn.textContent = '取消'; cancelBtn.onclick = () => modal.remove(); const saveBtn = document.createElement('button'); saveBtn.textContent = '保存'; saveBtn.style.marginLeft = '8px'; saveBtn.onclick = () => { try { const newColors = JSON.parse(textarea.value); if (typeof newColors !== 'object' || newColors === null) { throw new Error('请输入有效的JSON对象'); } localStorage.setItem('userNoteColors_', JSON.stringify(newColors)); noteColors = newColors; document.querySelectorAll('.note-badge').forEach(badge => { const note = badge.textContent; badge.style.backgroundColor = noteColors[note] || defaultColor; }); modal.remove(); } catch (error) { alert('错误: 请检查JSON格式(其他行的末尾是有英文逗号的,最后一行的末尾是没有逗号的!),还不会就把错误代码和JSON内容放在AI里面问问: ' + error.message); } }; buttonContainer.append(cancelBtn, saveBtn); modal.append(form, textarea, buttonContainer); document.body.appendChild(modal); } // 用户备注管理区 function openUserNoteManager() { const modal = document.createElement('div'); Object.assign(modal.style, { position: 'fixed', left: '50%', top: '50%', transform: 'translate(-50%, -50%)', backgroundColor: 'white', padding: '20px', borderRadius: '5px', boxShadow: '0 0 10px rgba(0,0,0,0.5)', zIndex: '9999', width: '450px' }); // 添加上方输入框 const form = document.createElement('div'); form.style.marginBottom = '10px'; const idInput = document.createElement('input'); idInput.placeholder = '用户ID'; idInput.style.marginRight = '5px'; const noteInput = document.createElement('input'); noteInput.placeholder = '备注'; noteInput.style.marginRight = '5px'; const addButton = document.createElement('button'); addButton.textContent = '添加'; addButton.onclick = () => { const userId = idInput.value.trim(); const note = noteInput.value.trim(); if (userId && note) { userNoteTable_AGE[userId] = note; textarea.value = JSON.stringify(userNoteTable_AGE, null, 4); idInput.value = ''; noteInput.value = ''; } }; form.append(idInput, noteInput, addButton); // JSON编辑区 const textarea = document.createElement('textarea'); textarea.style.cssText = 'width: 100%; height: 200px; margin: 10px 0;'; textarea.value = JSON.stringify(userNoteTable_AGE, null, 4); const buttonContainer = document.createElement('div'); buttonContainer.style.cssText = 'text-align: right;'; const importBtn = document.createElement('button'); importBtn.textContent = '导入'; importBtn.onclick = () => { const input = document.createElement("input"); input.type = "file"; input.accept = "application/json"; input.onchange = function (event) { const file = event.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function (e) { try { const imported = JSON.parse(e.target.result); userNoteTable_AGE = imported; // 直接替换当前内容 textarea.value = JSON.stringify(userNoteTable_AGE, null, 4); localStorage.setItem('userNoteTable_AGE', JSON.stringify(userNoteTable_AGE)); markUserNotes(); // 刷新页面显示 alert("导入成功!"); } catch (error) { alert("错误: 请检查JSON格式(其他行的末尾是有英文逗号的,最后一行的末尾是没有逗号的!),还不会就把错误代码和JSON内容放在AI里面问问:" + error); } }; reader.readAsText(file); } }; input.click(); }; const exportBtn = document.createElement('button'); exportBtn.textContent = '导出'; exportBtn.style.marginLeft = '5px'; exportBtn.onclick = () => { const blob = new Blob([textarea.value], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `user_notes_${Date.now()}.json`; a.click(); URL.revokeObjectURL(url); }; const cancelBtn = document.createElement('button'); cancelBtn.textContent = '取消'; cancelBtn.style.marginLeft = '5px'; cancelBtn.onclick = () => modal.remove(); const saveBtn = document.createElement('button'); saveBtn.textContent = '保存'; saveBtn.style.marginLeft = '5px'; saveBtn.onclick = () => { try { const newNotes = JSON.parse(textarea.value); localStorage.setItem('userNoteTable_AGE', JSON.stringify(newNotes)); userNoteTable_AGE = newNotes; markUserNotes(); modal.remove(); } catch (error) { alert('JSON格式错误:' + error.message); } }; buttonContainer.append(importBtn, exportBtn, cancelBtn, saveBtn); modal.append(form, textarea, buttonContainer); document.body.appendChild(modal); } function addButtonFunctions() { const badgeUserPanel = document.querySelector("ul#badgeUserPanel"); if (badgeUserPanel) { // 用户备注管理按钮 const userNoteLi = document.createElement('li'); const userNoteBtn = document.createElement('a'); userNoteBtn.href = '#'; userNoteBtn.textContent = '管理用户备注'; userNoteBtn.onclick = (e) => { e.preventDefault(); openUserNoteManager(); }; userNoteLi.appendChild(userNoteBtn); // 颜色管理按钮 const colorLi = document.createElement('li'); const colorBtn = document.createElement('a'); colorBtn.href = '#'; colorBtn.textContent = '管理颜色配置'; colorBtn.onclick = (e) => { e.preventDefault(); openColorManager(); }; colorLi.appendChild(colorBtn); badgeUserPanel.append(userNoteLi, colorLi); } } if (document.body) { markUserNotes(); } else { window.onload = markUserNotes; } setTimeout(addButtonFunctions, 1000); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址