Greasy Fork is available in English.
Prevent websites from detecting tab focus without breaking functionality
// ==UserScript==
// @name Prevent Tab Focus Detection
// @description Prevent websites from detecting tab focus without breaking functionality
// @version 2026.02.12
// @author Claude Sonnet 4.5
// @grant none
// @inject-into auto
// @run-at document-start
// @match *://*/*
// @namespace https://greasyfork.org/users/1519047
// ==/UserScript==
(function() {
'use strict';
// Store original functions
const originalGetters = {};
const originalMethods = {};
// Override document visibility properties
const overrideProperty = (obj, prop, fakeValue) => {
const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
if (descriptor && descriptor.get) {
originalGetters[prop] = descriptor.get;
}
try {
Object.defineProperty(obj, prop, {
configurable: true,
enumerable: true,
get: function() {
return fakeValue;
}
});
} catch(e) {
console.debug('Tab focus prevention: Failed to override', prop, e);
}
};
// Override all Page Visibility API properties (including vendor prefixes)
overrideProperty(document, 'hidden', false);
overrideProperty(document, 'visibilityState', 'visible');
overrideProperty(document, 'webkitHidden', false);
overrideProperty(document, 'webkitVisibilityState', 'visible');
overrideProperty(document, 'mozHidden', false);
overrideProperty(document, 'mozVisibilityState', 'visible');
overrideProperty(document, 'msHidden', false);
overrideProperty(document, 'msVisibilityState', 'visible');
// Override hasFocus methods to always return true
if (document.hasFocus) {
originalMethods.documentHasFocus = document.hasFocus;
document.hasFocus = function() {
return true;
};
}
if (window.hasFocus) {
originalMethods.windowHasFocus = window.hasFocus;
window.hasFocus = function() {
return true;
};
}
// Intercept visibility change events
const interceptEvent = (e) => {
e.stopImmediatePropagation();
};
// Only intercept Page Visibility API events (safest approach)
const eventsToIntercept = [
'visibilitychange',
'webkitvisibilitychange',
'mozvisibilitychange',
'msvisibilitychange'
];
eventsToIntercept.forEach(eventType => {
window.addEventListener(eventType, interceptEvent, true);
document.addEventListener(eventType, interceptEvent, true);
});
console.debug('Tab focus detection prevention active');
})();