您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds custom refresh buttons and enables a high-speed refresh mode.
// ==UserScript== // @name Finviz Refresh Overhaul // @namespace http://tampermonkey.net/ // @version 1.0 // @description Adds custom refresh buttons and enables a high-speed refresh mode. // @author Game Abuse Studios // @match https://elite.finviz.com/screener.ashx* // @license MIT // @grant none // @run-at document-idle // ==/UserScript== (function() { 'use strict'; /** * Checks for a stored refresh interval and reapplies it to the URL if needed. * This runs once at the very start of the script. */ function applyStoredInterval() { const currentUrl = new URL(window.location.href); const activeRefresh = currentUrl.searchParams.get('ar'); const storedRefresh = localStorage.getItem('finvizRefreshInterval'); // If there's no refresh interval in the URL but one is stored, // we redirect to the URL with the stored value. if (!activeRefresh && storedRefresh) { currentUrl.searchParams.set('ar', storedRefresh); window.location.replace(currentUrl.href); } } // --- Secondary Script Logic for Fast Refresh --- /** * Activates the high-speed refresh timer. * It overrides the default Finviz refresh function. * @param {number} interval - The refresh interval in milliseconds. */ function activateFastRefresh(interval) { // Prevent the original refresh timer from ever being set. if (typeof window.ScreenerRefreshInit === 'function') { window.ScreenerRefreshInit = function() { /* Do nothing */ }; } // Clear any existing custom timer before setting a new one. if (window.myCustomRefreshTimerId) { clearInterval(window.myCustomRefreshTimerId); } // Set our new refresh timer to run at the specified interval. if (typeof window.Refresh === 'function') { window.myCustomRefreshTimerId = setInterval(() => { window.Refresh(); }, interval); } } /** * Deactivates the high-speed refresh timer and allows * Finviz's default behavior to resume. */ function deactivateFastRefresh() { if (window.myCustomRefreshTimerId) { clearInterval(window.myCustomRefreshTimerId); window.myCustomRefreshTimerId = null; } } /** * Wipes the existing refresh links and rebuilds the entire set with custom options included. * @param {HTMLElement} container - The element where buttons should be rebuilt. */ function rebuildButtons(container) { // Define ALL buttons in the desired final order. const allButtons = [ { text: '0.25s', value: '0.25' }, { text: '1s', value: '1' }, { text: '5s', value: '5' }, { text: '10s', value: '10' }, { text: '1min', value: '60' }, { text: 'off', value: null } ]; // Find the specific span inside the container that holds the links. const buttonHolder = container.querySelector('span[style*="white-space: nowrap"]'); if (!buttonHolder) return; // --- Wipe existing buttons --- buttonHolder.innerHTML = ''; // Clear everything inside the span. // Get the current URL to determine which link should be active. const currentUrl = new URL(window.location.href); const activeRefresh = currentUrl.searchParams.get('ar'); // --- Rebuild from scratch --- const refreshTextSpan = document.createElement('span'); refreshTextSpan.textContent = 'Refresh: '; refreshTextSpan.style.color = '#676F85'; refreshTextSpan.style.fontWeight = 'bold'; buttonHolder.appendChild(refreshTextSpan); allButtons.forEach((button, index) => { const link = document.createElement('a'); link.className = 'tab-link'; link.textContent = button.text; // Add event listener to save the selection to local storage link.addEventListener('click', () => { if (button.value) { localStorage.setItem('finvizRefreshInterval', button.value); } else { localStorage.removeItem('finvizRefreshInterval'); } }); const url = new URL(window.location.href); if (button.value) { url.searchParams.set('ar', button.value); } else { url.searchParams.delete('ar'); } link.href = url.href; const isActive = (button.value === activeRefresh) || (!button.value && !activeRefresh); if (isActive) { link.classList.add('font-bold'); } buttonHolder.appendChild(link); if (index < allButtons.length - 1) { buttonHolder.appendChild(document.createTextNode(' | ')); } }); // --- Handle the secondary script activation --- if (activeRefresh === '0.25') { activateFastRefresh(250); // 250ms for 0.25s } else if (activeRefresh === '1') { activateFastRefresh(1000); // 1000ms for 1s } else if (activeRefresh === '5') { activateFastRefresh(5000); // 5000ms for 5s } else { deactivateFastRefresh(); } } /** * The main observer that watches for Finviz wiping our buttons. */ const mainObserver = new MutationObserver(() => { const container = document.getElementById('screener-fullview-links'); // If our buttons are gone, rebuild them. if (container && !container.querySelector('a[href*="&ar=0.25"]')) { rebuildButtons(container); } }); /** * This function checks if the page is ready for our script to run. * It looks for the container and at least one link inside it. */ function initialize() { const container = document.getElementById('screener-fullview-links'); const anyLinkInside = container ? container.querySelector('a.tab-link') : null; if (container && anyLinkInside) { // We're ready! Stop the checking. clearInterval(setupInterval); // Rebuild the buttons for the first time. rebuildButtons(container); // Start the permanent observer to watch for subsequent changes by Finviz. mainObserver.observe(container, { childList: true, subtree: true }); } } // --- Main Execution Block --- // 1. First, check if we need to redirect based on a stored value. applyStoredInterval(); // 2. Then, begin the process of initializing the buttons on the page. const setupInterval = setInterval(initialize, 1); })();