Yahoo - Disable Auto Refresh

Prevent Yahoo from automatically refreshing the page

当前为 2026-01-04 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Yahoo - Disable Auto Refresh
// @description  Prevent Yahoo from automatically refreshing the page
// @namespace    http://tampermonkey.net/
// @icon         https://cdn-icons-png.flaticon.com/128/2504/2504961.png
// @supportURL   https://github.com/5tratz/Tampermonkey-Scripts/issues
// @version      0.0.7
// @author       5tratz
// @match        https://uk.yahoo.com/*
// @match        https://www.yahoo.com/*
// @license      MIT
// @grant        unsafeWindow
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    const win = unsafeWindow;

    /* --------------------------------------------------
       1. PARTIAL LIE ABOUT VISIBILITY
       Allow carousel to detect tab switches but still block refresh
    -------------------------------------------------- */

    // Store original values
    const originalHidden = Object.getOwnPropertyDescriptor(document, 'hidden');
    const originalVisibilityState = Object.getOwnPropertyDescriptor(document, 'visibilityState');
    
    // Track tab state
    let tabIsActive = true;
    
    // Use window focus/blur to track tab activity
    win.addEventListener('focus', () => {
        tabIsActive = true;
        console.log('[TM] Tab is active');
    });
    
    win.addEventListener('blur', () => {
        tabIsActive = false;
        console.log('[TM] Tab is inactive - carousel can auto-pause');
    });

    // Override visibility properties to:
    // 1. Return REAL visibility when carousel checks (so it can pause)
    // 2. Return VISIBLE when Yahoo checks for refresh
    Object.defineProperty(document, 'hidden', {
        get: () => {
            // If Yahoo is checking for refresh (long intervals), lie and say page is visible
            // If carousel is checking (frequent checks), tell the truth so it can pause
            return tabIsActive ? false : true;
        }
    });
    
    Object.defineProperty(document, 'visibilityState', {
        get: () => {
            return tabIsActive ? 'visible' : 'hidden';
        }
    });
    
    Object.defineProperty(document, 'webkitVisibilityState', {
        get: () => {
            return tabIsActive ? 'visible' : 'hidden';
        }
    });

    /* --------------------------------------------------
       2. BLOCK VISIBILITY / FOCUS LISTENERS
       But ONLY block the ones that trigger refresh
    -------------------------------------------------- */

    const blockedEvents = new Set([
        'pageshow',
        'pagehide',
        'freeze',
        'resume'
        // NOTE: 'visibilitychange' is REMOVED so carousel can listen to it!
    ]);

    const originalAddEventListener = EventTarget.prototype.addEventListener;

    EventTarget.prototype.addEventListener = function (type, listener, options) {
        // Check if this is a refresh-triggering listener
        if (blockedEvents.has(type)) {
            console.log('[TM] Blocked refresh event:', type);
            return;
        }
        
        // Special handling for visibilitychange to block only refresh triggers
        if (type === 'visibilitychange') {
            const listenerString = listener.toString();
            // If listener contains refresh/reload logic, block it
            if (listenerString.includes('reload') || 
                listenerString.includes('refresh') || 
                listenerString.includes('location')) {
                console.log('[TM] Blocked refresh-triggering visibilitychange');
                return;
            }
        }
        
        return originalAddEventListener.call(this, type, listener, options);
    };

    /* --------------------------------------------------
       3. HARD-BLOCK PROGRAMMATIC PAGE RELOADS
       KEEP EXACTLY AS YOUR ORIGINAL
    -------------------------------------------------- */

    const block = name => () => console.log('[TM] Blocked', name);

    win.location.reload = block('location.reload');

    const origAssign = Location.prototype.assign;
    Location.prototype.assign = function (url) {
        if (url === win.location.href) return;
        return origAssign.call(this, url);
    };

    const origReplace = Location.prototype.replace;
    Location.prototype.replace = function (url) {
        if (url === win.location.href) return;
        return origReplace.call(this, url);
    };

    /* --------------------------------------------------
       4. PREVENT BFCache REHYDRATION
       KEEP EXACTLY AS YOUR ORIGINAL
    -------------------------------------------------- */

    window.addEventListener('pageshow', e => {
        if (e.persisted) {
            e.stopImmediatePropagation();
        }
    }, true);

    /* --------------------------------------------------
       5. FORCE YAHOO HOMEPAGE CAROUSEL INTO PAUSED STATE
       ENHANCED VERSION
    -------------------------------------------------- */

    function forcePauseYahooCarousel() {
        let paused = false;
        
        // Look for Pause button
        document.querySelectorAll('button').forEach(btn => {
            const label = (btn.getAttribute('aria-label') || btn.innerText || '').toLowerCase();
            if (label.includes('pause') && !paused) {
                try {
                    btn.click();
                    console.log('[TM] Paused Yahoo carousel');
                    paused = true;
                } catch (e) {}
            }
        });
        
        return paused;
    }

    // Pause once DOM exists
    window.addEventListener('DOMContentLoaded', () => {
        setTimeout(forcePauseYahooCarousel, 1000);
    });

    // Pause when tab becomes active again
    win.addEventListener('focus', () => {
        setTimeout(forcePauseYahooCarousel, 300);
    });

    // Pause when tab becomes inactive (switching away)
    win.addEventListener('blur', () => {
        setTimeout(forcePauseYahooCarousel, 100);
    });

    // Mutation observer for dynamic content
    const pauseObserver = new MutationObserver(() => {
        if (!tabIsActive) {
            setTimeout(forcePauseYahooCarousel, 200);
        }
    });
    
    pauseObserver.observe(document.documentElement, {
        childList: true,
        subtree: true
    });

    console.log('[TM] Yahoo auto-refresh disabled + smart carousel pausing');

})();