您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
On New Reddit, makes post titles and post boxes link directly to the external website instead of the Reddit comments page.
当前为
// ==UserScript== // @name Reddit Direct Link // @namespace http://tampermonkey.net/ // @version 1.01 // @description On New Reddit, makes post titles and post boxes link directly to the external website instead of the Reddit comments page. // @author narrowstacks // @match *://www.reddit.com/* // @grant none // @license MIT // ==/UserScript== (function () { "use strict"; // List of Reddit media domains to preserve const REDDIT_MEDIA_DOMAINS = [ "i.redd.it", "v.redd.it", "preview.redd.it", "i.reddit.com", "reddit.com/gallery", ]; function isRedditMediaLink(url) { return REDDIT_MEDIA_DOMAINS.some((domain) => url.includes(domain)); } function findExternalLink(post) { // First try to find the link in the thumbnail slot as it's most reliable const thumbnailSlot = post.shadowRoot.querySelector( 'slot[name="thumbnail"]' ); if (thumbnailSlot) { const elements = thumbnailSlot.assignedElements(); for (const element of elements) { // Look for the direct link in the thumbnail area const links = element.querySelectorAll( 'a[rel="noopener nofollow ugc"]' ); for (const link of links) { // Skip if it's a Reddit media link if (isRedditMediaLink(link.href)) { return null; } if ( !link.href.includes("/comments/") && !link.href.includes("reddit.com") ) { return link; } } } } // Check content-href attribute first as it's more reliable than other slots const contentHref = post.getAttribute("content-href"); if (contentHref) { if (isRedditMediaLink(contentHref)) { return null; } if ( !contentHref.includes("/comments/") && !contentHref.includes("reddit.com") ) { return { href: contentHref }; } } // Fallback to other slots if needed const slotNames = ["title", "full-post-link", "content-href"]; for (const slotName of slotNames) { const slot = post.shadowRoot.querySelector(`slot[name="${slotName}"]`); if (!slot) continue; const elements = slot.assignedElements(); for (const element of elements) { // Check for links within the element const links = element.querySelectorAll("a"); for (const link of links) { if (isRedditMediaLink(link.href)) { continue; } if ( !link.href.includes("/comments/") && !link.href.includes("reddit.com") ) { return link; } } // Check for href attribute on the element itself if (element.href) { if (isRedditMediaLink(element.href)) { continue; } if ( !element.href.includes("/comments/") && !element.href.includes("reddit.com") ) { return element; } } } } return null; } function modifyLinks() { const posts = document.querySelectorAll("shreddit-post"); posts.forEach((post) => { // Check if post has shadowRoot if (!post.shadowRoot) { return; } // Find external link first const externalLink = findExternalLink(post); if (!externalLink) { return; } // Find and modify the title link const titleSlot = post.shadowRoot.querySelector('slot[name="title"]'); if (titleSlot) { const titleElements = titleSlot.assignedElements(); for (const element of titleElements) { const titleLink = element.querySelector("a"); if (titleLink) { titleLink.href = externalLink.href; titleLink.addEventListener("click", (e) => { e.stopPropagation(); }); } } } // Find and modify the full-post link const fullPostLinkSlot = post.shadowRoot.querySelector( 'slot[name="full-post-link"]' ); if (fullPostLinkSlot) { const fullPostElements = fullPostLinkSlot.assignedElements(); for (const element of fullPostElements) { if (element.tagName === "A") { element.href = externalLink.href; element.addEventListener("click", (e) => { e.stopPropagation(); }); } } } // Try to modify the post container const postContainer = post.shadowRoot.querySelector(".grid"); if (postContainer) { postContainer.style.cursor = "pointer"; postContainer.addEventListener("click", (e) => { // Only redirect if not clicking on interactive elements const interactive = e.target.closest('button, a, [role="button"]'); if (!interactive) { e.preventDefault(); e.stopPropagation(); window.location.href = externalLink.href; } }); } }); } // Wait for the page to be ready function init() { // Initial check modifyLinks(); // Observe for dynamically loaded posts const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.addedNodes.length) { setTimeout(modifyLinks, 100); // Small delay to ensure slots are populated } } }); observer.observe(document.body, { childList: true, subtree: true, }); } // Ensure the script runs after the page is loaded if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); } })();