您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Allows toggling pause on website's mousemove listeners, while local cursor still moves.
// ==UserScript== // @name Pause Mouse Movement for Website // @namespace http://tampermonkey.net/ // @version 1.0 // @description Allows toggling pause on website's mousemove listeners, while local cursor still moves. // @author Your Name Here // @match *://*/* // @grant none // @run-at document-start // @license MIT // ==/UserScript== (function() { 'use strict'; // --- Configuration --- const TOGGLE_KEY = 'm'; // Key to press for toggling const REQUIRE_CTRL = true; // Require Ctrl key? const REQUIRE_ALT = true; // Require Alt key? const REQUIRE_SHIFT = false; // Require Shift key? // --- End Configuration --- let isPaused = false; // Initial state: website mouse movement is NOT paused const listenerMap = new Map(); // Stores mapping: originalListener -> wrappedListener let statusIndicator = null; // Reference to the status indicator element console.log("Pause Mouse Movement Script: Initializing."); // --- Status Indicator --- function createStatusIndicator() { const indicator = document.createElement('div'); indicator.style.position = 'fixed'; indicator.style.bottom = '10px'; indicator.style.right = '10px'; indicator.style.padding = '5px 10px'; indicator.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; indicator.style.color = 'white'; indicator.style.fontSize = '12px'; indicator.style.borderRadius = '3px'; indicator.style.zIndex = '99999'; // Ensure it's on top indicator.style.fontFamily = 'sans-serif'; indicator.style.pointerEvents = 'none'; // Don't let it interfere with mouse events document.body.appendChild(indicator); return indicator; } function updateStatusIndicator() { if (!statusIndicator && document.body) { statusIndicator = createStatusIndicator(); } if (statusIndicator) { statusIndicator.textContent = `Website Mouse: ${isPaused ? 'Paused' : 'Active'} (Toggle: ${REQUIRE_CTRL ? 'Ctrl+' : ''}${REQUIRE_ALT ? 'Alt+' : ''}${REQUIRE_SHIFT ? 'Shift+' : ''}${TOGGLE_KEY.toUpperCase()})`; statusIndicator.style.backgroundColor = isPaused ? 'rgba(255, 0, 0, 0.7)' : 'rgba(0, 128, 0, 0.7)'; // Red when paused, Green when active } } // --- Toggle Function --- function togglePause() { isPaused = !isPaused; console.log(`Pause Mouse Movement Script: Website mousemove listeners ${isPaused ? 'paused' : 'activated'}.`); updateStatusIndicator(); } // --- Keyboard Shortcut Listener --- document.addEventListener('keydown', (event) => { // Check if the pressed key and modifiers match the configuration if (event.key.toLowerCase() === TOGGLE_KEY.toLowerCase() && event.ctrlKey === REQUIRE_CTRL && event.altKey === REQUIRE_ALT && event.shiftKey === REQUIRE_SHIFT) { // Prevent default action if the key combination might have one event.preventDefault(); event.stopPropagation(); togglePause(); } }, true); // Use capture phase to catch before page scripts // --- Intercept addEventListener --- const originalAddEventListener = EventTarget.prototype.addEventListener; EventTarget.prototype.addEventListener = function(type, listener, options) { if (type === 'mousemove' && typeof listener === 'function') { // Only wrap mousemove listeners if (!listenerMap.has(listener)) { const wrappedListener = function(...args) { if (!isPaused) { // If not paused, call the original listener // Use Reflect.apply to correctly handle 'this' context and arguments try { Reflect.apply(listener, this, args); } catch (e) { console.error("Error executing original mousemove listener:", e); } } // If paused, do nothing, effectively blocking the listener }; listenerMap.set(listener, wrappedListener); // Add the wrapped listener instead of the original originalAddEventListener.call(this, type, wrappedListener, options); // console.log("Wrapped mousemove listener added for:", this); } else { // Listener already wrapped, potentially re-adding? Call original to ensure browser handles it correctly. originalAddEventListener.call(this, type, listenerMap.get(listener), options); } } else { // For all other event types, call the original function directly originalAddEventListener.call(this, type, listener, options); } }; // --- Intercept removeEventListener --- const originalRemoveEventListener = EventTarget.prototype.removeEventListener; EventTarget.prototype.removeEventListener = function(type, listener, options) { if (type === 'mousemove' && typeof listener === 'function') { // If it's a mousemove listener, try to remove the wrapped version const wrappedListener = listenerMap.get(listener); if (wrappedListener) { // Remove the wrapped listener originalRemoveEventListener.call(this, type, wrappedListener, options); listenerMap.delete(listener); // Clean up the map // console.log("Wrapped mousemove listener removed for:", this); } else { // If no wrapper found (maybe added before script ran?), try removing original anyway originalRemoveEventListener.call(this, type, listener, options); } } else { // For all other event types, call the original function directly originalRemoveEventListener.call(this, type, listener, options); } }; console.log("Pause Mouse Movement Script: Event listener interception active."); // Update status indicator once the body is available if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', updateStatusIndicator); } else { // DOMContentLoaded has already fired updateStatusIndicator(); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址