您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Confirm navigation for links containing 'user', 'permalink', or 'parent' on Reddit
// ==UserScript== // @name Add redirect confirmation to reddit links (written for old) // @namespace http://tampermonkey.net/ // @version 0.3 // @description Confirm navigation for links containing 'user', 'permalink', or 'parent' on Reddit // @author cgpt // @match *://*.reddit.com/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // Function to create and show the modal function showModal(link) { // Create the modal container const modal = document.createElement('div'); modal.style.position = 'fixed'; modal.style.left = '0'; modal.style.top = '0'; modal.style.width = '100vw'; modal.style.height = '100vh'; modal.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; modal.style.display = 'flex'; modal.style.justifyContent = 'center'; modal.style.alignItems = 'center'; modal.style.zIndex = '10000'; // Function to remove the modal function removeModal() { document.body.removeChild(modal); } // Event listener for modal close scenarios modal.addEventListener('click', function(event) { if (event.target === modal) { removeModal(); } }); // Escape key handler document.addEventListener('keydown', function(event) { if (event.key === 'Escape') { removeModal(); } }, { once: true }); // Automatically removes listener after first use // Create the modal content const modalContent = document.createElement('div'); modalContent.style.padding = '20px'; modalContent.style.backgroundColor = 'white'; modalContent.style.borderRadius = '5px'; modalContent.innerText = `Navigate to ${link.href}?`; // Create Yes button const yesButton = document.createElement('button'); yesButton.innerText = 'Yes'; yesButton.onclick = function() { window.location.href = link.href; }; // Create No button const noButton = document.createElement('button'); noButton.innerText = 'No'; noButton.onclick = removeModal; modalContent.appendChild(yesButton); modalContent.appendChild(document.createTextNode(' ')); // Spacer modalContent.appendChild(noButton); modal.appendChild(modalContent); document.body.appendChild(modal); } // Function to check if the hash fragment has a significant change function isHashFragmentChanged(oldUrl, newUrl) { const oldUrlObj = new URL(oldUrl); const newUrlObj = new URL(newUrl); // Check if the base URL (without the hash) is the same if (oldUrlObj.origin + oldUrlObj.pathname !== newUrlObj.origin + newUrlObj.pathname) { return true; // Base URL is different, so show the modal } // Check if the hash has significantly changed if (oldUrlObj.hash !== newUrlObj.hash && newUrlObj.hash) { const oldHash = oldUrlObj.hash.replace(/^#/, ''); const newHash = newUrlObj.hash.replace(/^#/, ''); // Compare hash changes. If they are not minor, return true to show the modal return oldHash !== newHash; } // No significant change return false; } // Function to determine if a URL is just appending a query or fragment function isNavigationRelevant(oldUrl, newUrl) { const ignoredParameters = ['utm_source', 'utm_medium', 'utm_name', 'utm_content']; const newUrlObj = new URL(newUrl); // Check if the URL has any ignored parameters or a new fragment if (newUrlObj.hash || ignoredParameters.some(param => newUrlObj.searchParams.has(param))) { // Check for relevant hash changes return isHashFragmentChanged(oldUrl, newUrl); } // No utm params and no relevant fragment change, so navigation is not relevant return true; } // Event listener for all 'a' elements document.addEventListener('click', function(e) { const target = e.target.closest('a'); const currentUrl = window.location.href; if (target && isNavigationRelevant(currentUrl, target.href) && (target.href.includes('user') || target.textContent.toLowerCase().includes('permalink') || target.textContent.toLowerCase().includes('parent'))) { e.preventDefault(); showModal(target); } }, true); })();