您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Make website completely invisible to the user switching to another window or tab. May break some websites.
- // ==UserScript==
- // @name Sabotage Window/Tab Switch Visibility
- // @description Make website completely invisible to the user switching to another window or tab. May break some websites.
- // @author owowed <island@owowed.moe>
- // @version 0.0.3
- // @namespace util.owowed.moe
- // @license GPL-3.0-or-later
- // @match *://*/*
- // @grant unsafeWindow
- // @run-at document-start
- // @copyright All rights reserved. Licensed under GPL-3.0-or-later. View license at https://spdx.org/licenses/GPL-3.0-or-later.html
- // ==/UserScript==
- !function () {
- /* Disable focus and blur event of document and window */
- const windowProto = globalThis.unsafeWindow ?? window;
- console.log("Sabotage Window/Tab Switch Visibility is executing...");
- disableFocusBlurEvent(Document.prototype);
- disableFocusBlurEvent(windowProto);
- function disableFocusBlurEvent(objPrototype) {
- const eventBlocklist = ["focus", "blur"];
- for (const event of eventBlocklist) {
- defineGetterSetter(objPrototype, `on${event}`, {
- set: () => undefined,
- });
- }
- const oldEventListener = objPrototype.addEventListener;
- objPrototype.addEventListener = function (event, ...args) {
- if (eventBlocklist.includes(event)) return;
- oldEventListener.call(this, event, ...args);
- }
- }
- /* Disable Page Visibility API */
- defineGetterSetter(Document.prototype, "hidden", {
- get: () => false
- });
- defineGetterSetter(Document.prototype, "visibilityState", {
- get: () => "visible"
- });
- document.addEventListener("visibilitychange", function(e) {
- e.stopImmediatePropagation();
- }, true);
- /* Partially disable blur and focus event (and other events) of element */
- const safeBoxSize = 800;
- const elementOldEventListener = Element.prototype.addEventListener;
- const eventBlocklist = [
- "blur",
- "focus",
- "mouseleave",
- "hasFocus"
- ];
- // Element.on{event} properties, like Element.onfocus, Element.onblur etc.
- for (const event of eventBlocklist) {
- if (event == "hasFocus") continue;
- let registered = false;
- defineGetterSetter(Element.prototype, `on${event}`, {
- set(callback) {
- if (!registered) {
- this.addEventListener(event, callback)
- registered = true;
- }
- }
- });
- }
- // override Element.addEventListener
- Element.prototype.addEventListener = function (event, callback, ...args) {
- if (eventBlocklist.includes(event)) {
- const elem = this;
- elementOldEventListener.call(this, event, (...eventArgs) => {
- const clientRect = elem.getBoundingClientRect();
- if (clientRect.width >= safeBoxSize || clientRect.height >= safeBoxSize) {
- return;
- }
- callback(...eventArgs);
- }, ...args);
- }
- else elementOldEventListener.call(this, event, callback, ...args);
- };
- /* Disable CSS prefers-reduced-motion for JavaScript */
- const windowOldMatchMedia = windowProto.matchMedia;
- windowProto.matchMedia = function (matchMedia, ...args) {
- if (matchMedia.includes("prefers-reduced-motion") && matchMedia.includes("reduce")) {
- return false;
- }
- return windowOldMatchMedia.call(this, matchMedia, ...args);
- }
- console.log("Sabotage Window/Tab Switch Visibility executed");
- }();
- function defineGetterSetter(proto, property, { get, set } = {}) {
- Object.defineProperty(proto, property, {
- get, set,
- enumerable: true, configurable: true
- })
- }