Press Q to leave game quickly.
// ==UserScript==
// @name GeoGuessr: Leave Game Shortcut (Q)
// @namespace https://gf.qytechs.cn/users/your-name
// @version 1.2.0
// @description Press Q to leave game quickly.
// @author Rotski
// @license MIT
// @match https://www.geoguessr.com/*
// @run-at document-start
// @grant none
// ==/UserScript==
(function () {
'use strict';
// ---- Tweaks ----
const HOTKEY = 'q'; // trigger key
const DELAY_MS = 50; // wait after ESC
const TIMEOUT_MS = 5000; // max time to keep searching for the button
function isTypingTarget(el){
const t = (el && el.tagName || '').toLowerCase();
return t === 'input' || t === 'textarea' || (el && el.isContentEditable);
}
function sendEscEverywhere(){
const opts = { key: 'Escape', code: 'Escape', keyCode: 27, bubbles: true, cancelable: true, composed: true };
const targets = [window, document, document.documentElement, document.body, document.activeElement].filter(Boolean);
for (const tg of targets) tg.dispatchEvent(new KeyboardEvent('keydown', opts));
for (const tg of targets) tg.dispatchEvent(new KeyboardEvent('keyup', opts));
}
function isVisible(el){
return !!(el && el.offsetParent !== null);
}
function findWrapperButtons() {
// exact wrapper class
const wrappers = Array.from(document.querySelectorAll('.button_wrapper__zayJ3'));
// or any hashed variant if it ever changes:
const wildcards = Array.from(document.querySelectorAll('[class^="button_wrapper__"], [class*=" button_wrapper__"]'));
const all = wrappers.length ? wrappers : wildcards;
// Map to closest <button>
const buttons = [];
for (const w of all) {
const btn = w.closest('button');
if (btn && isVisible(btn) && !buttons.includes(btn)) buttons.push(btn);
}
return buttons;
}
function looksSecondary(btn){
return Array.from(btn.classList).some(c => /^button_variantSecondary__/.test(c));
}
function pickTargetButton(){
const candidates = findWrapperButtons();
if (!candidates.length) return null;
// Prefer Secondary variant
const secondary = candidates.find(looksSecondary);
if (secondary) return secondary;
// Otherwise first visible
return candidates[0];
}
function clickAfterDelay() {
const start = performance.now();
return new Promise((resolve) => {
const tryClick = () => {
const btn = pickTargetButton();
if (btn) { btn.click(); resolve(true); return; }
if (performance.now() - start > TIMEOUT_MS) { resolve(false); return; }
setTimeout(tryClick, 100);
};
setTimeout(tryClick, DELAY_MS);
});
}
window.addEventListener('keydown', async (e) => {
if ((e.key || '').toLowerCase() !== HOTKEY) return;
if (e.repeat) return;
if (isTypingTarget(e.target)) return;
e.preventDefault();
e.stopPropagation();
sendEscEverywhere();
await clickAfterDelay();
}, true);
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址