在用户名后面添加备注
// ==UserScript==
// @name 豆瓣用户备注
// @namespace http://tampermonkey.net/
// @version 2025-10-31
// @description 在用户名后面添加备注
// @author Betty
// @match https://www.douban.com/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
const siteConfig = [
{
// 豆瓣小组帖子
pattern: /douban\.com\/group\/topic/,
selector: '.topic-doc .from a, .bg-img-green h4 a',
idRegex: /\/people\/([A-Za-z0-9_-]+)/
},
{
// 豆瓣个人主页
pattern: /douban\.com\/people\//,
selector: '#db-usr-profile',
idRegex: /\/people\/([A-Za-z0-9_-]+)/
},
];
const currentConfig = siteConfig.find(c => c.pattern.test(location.href));
const NOTES_KEY = "userNotesByID";
const notes = JSON.parse(localStorage.getItem(NOTES_KEY) || "{}");
function saveNotes() {
localStorage.setItem(NOTES_KEY, JSON.stringify(notes));
}
// Extract the user ID
function getUserId(userEl) {
// Try from the link first
const hrefMatch = userEl.href?.match(currentConfig.idRegex);
if (hrefMatch) return hrefMatch[1];
// Fallback: try to get from the current page URL
const urlMatch = location.href.match(currentConfig.idRegex);
if (urlMatch) return urlMatch[1];
return null;
}
function addNotesToUsers() {
document.querySelectorAll(currentConfig.selector).forEach(userEl => {
// Avoid adding notes multiple times
if (userEl.dataset.noteAttached) return;
const userId = getUserId(userEl);
if (!userId) return;
const noteText = notes[userId] || "";
// Create or show the note span
const noteSpan = document.createElement('span');
noteSpan.textContent = noteText ? `${noteText}` : "+";
noteSpan.style.color = '#333';
noteSpan.style.background = '#ddd';
noteSpan.style.cursor = 'pointer';
noteSpan.style.margin = '0 5px';
noteSpan.style.padding = '2px 5px';
// Click to edit
noteSpan.onclick = () => {
const newNote = prompt(`Note for user ${userId}:`, notes[userId] || "");
if (newNote !== null) {
notes[userId] = newNote.trim();
saveNotes();
noteSpan.textContent = newNote ? ` ${newNote} ` : "";
}
};
userEl.after(noteSpan);
// Add a data-note-attached attribute to avoid adding notes multiple times
userEl.dataset.noteAttached = true;
});
}
addNotesToUsers();
const observer = new MutationObserver(addNotesToUsers);
observer.observe(document.body, { childList: true, subtree: true });
})();