Yahoo - Disable Auto Refresh

Prevent Yahoo from automatically refreshing the page

目前為 2026-01-04 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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');

})();