您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds post authors to items in Reddit feed (on new Reddit)
// ==UserScript== // @name RedditorsInFeed // @namespace github.com/JasonAMelancon // @version 2025-08-18 // @description Adds post authors to items in Reddit feed (on new Reddit) // @author Jason Melancon // @license GNU AGPLv3 // @match http*://www.reddit.com/ // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // ==/UserScript== (function() { 'use strict'; const DEBUG = false; const CREDITED = "is-credited"; // my custom attribute for the post element const POST = "shreddit-post"; // Reddit's custom element name const FEED = "shreddit-feed"; // Reddit's custom element name const scriptName = GM_info.script.name; const feeds = document.getElementsByTagName(FEED); if (feeds.length > 1) { // I have no idea whether this is or will ever be necessary console.log(`[${scriptName}] Multiple Reddit feed nodes present`); } const feed = feeds[0]; debugLog(`[${scriptName}] ${feed.querySelectorAll("article").length} initial articles`); // Get the first few articles in the feed when the page loads, and add the author. feed.querySelectorAll("article").forEach(article => { if (!isCredited(article)) { creditAuthor(article); markCredited(article); } }); // Watch the page for new articles that appear when scrolling. var dynamicScroll = new MutationObserver((mutations) => { debugLog(`[${scriptName}] ${mutations.length} new mutation objects`); for (var mutation of mutations) { let newArticleArray = Array.from(mutation.addedNodes).filter(node => node.nodeName === "ARTICLE"); debugLog(`[${scriptName}] ${newArticleArray.length} new articles`); if (newArticleArray.length == 0) continue; // Add the author to the new articles as they appear. newArticleArray.forEach(article => { if (!isCredited(article)) { creditAuthor(article); markCredited(article); } }); } }); dynamicScroll.observe(feed, { childList: true, subtree: false, attributes: false, characterData: false }); // Put the author of a single article on the top line, next to the subreddit and post age. function creditAuthor(article) { const post = article.querySelector(POST); const author = post.getAttribute("author"); const creditBar = post.querySelector("span > span"); const separator = creditBar.querySelector(".created-separator").cloneNode(/*deep = */true); creditBar.appendChild(separator); if (author === "[deleted]") { creditBar.insertAdjacentHTML('beforeend', `<span class="whitespace-nowrap text-neutral-content-weak">by ${author}</span>`); } else { creditBar.insertAdjacentHTML('beforeend', `<span class="whitespace-nowrap text-neutral-content-weak">by <a href="/u/${author}">${author}</a></span>`); } } // When scrolling down far enough, Reddit unloads posts from the top of the page, // presumably to save memory. In general, Reddit unloads posts you scroll away from // and loads or reloads posts you scroll toward. Without checking to make sure the // post hasn't already been credited, this can cause this script to credit the post // multiple times when the MutationObserver notices a credited post reappear in the // feed. // // Therefore, check first. function isCredited(article) { const post = article.querySelector(POST); debugLog(`[${scriptName}] credited check: ${post.hasAttribute(CREDITED)}`); return post.hasAttribute(CREDITED); } // Marks a post as already credited. function markCredited (article) { const post = article.querySelector(POST); post.setAttribute(CREDITED, ""); } function debugLog(msg) { if (DEBUG) console.log(msg); } })();