// ==UserScript==
// @name 鼠标坐标记录器
// @namespace https://www.0755tt.com/
// @version 9.0
// @description 在屏幕右上角输入坐标,实时解析为 clickX 和 clickY,带确认按钮,默认921,409
// @author reese
// @match https://www.0755tt.com/*
// @grant none
// ==/UserScript==
(function() {
//输入框(预填默认值)
const DEFAULT_X = 921;
const DEFAULT_Y = 409;
// 创建容器
const container = document.createElement('div');
container.id = 'coord-recorder';
container.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
z-index: 999999;
background: rgba(30, 30, 30, 0.9);
border: 1px solid #555;
border-radius: 6px;
padding: 10px 14px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-size: 13px;
color: #fff;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
display: flex;
flex-direction: column;
gap: 6px;
min-width: 180px;
`;
// 标题
const title = document.createElement('div');
title.textContent = '坐标输入';
title.style.cssText = `
font-weight: 600;
color: #4fc3f7;
margin-bottom: 2px;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
`;
// 输入框(预填默认值)
const input = document.createElement('input');
input.type = 'text';
input.value = `${DEFAULT_X}, ${DEFAULT_Y}`;
input.style.cssText = `
background: #2a2a2a;
border: 1px solid #81c784;
border-radius: 4px;
padding: 6px 8px;
color: #fff;
font-size: 13px;
outline: none;
width: 100%;
box-sizing: border-box;
`;
input.addEventListener('focus', () => {
if (input.style.borderColor !== '#e57373') {
input.style.borderColor = '#4fc3f7';
}
});
input.addEventListener('blur', () => {
if (input.style.borderColor !== '#e57373') {
input.style.borderColor = '#81c784';
}
});
// 显示区域
const display = document.createElement('div');
display.style.cssText = `
font-size: 12px;
color: #aaa;
margin-top: 2px;
line-height: 1.5;
min-height: 36px;
`;
// 按钮区域
const btnRow = document.createElement('div');
btnRow.style.cssText = `
display: flex;
justify-content: flex-end;
margin-top: 2px;
`;
// 确认按钮
const confirmBtn = document.createElement('button');
confirmBtn.textContent = '确认';
confirmBtn.style.cssText = `
background: #4fc3f7;
border: none;
border-radius: 4px;
padding: 5px 14px;
color: #1a1a1a;
font-size: 12px;
font-weight: 600;
cursor: pointer;
transition: background 0.2s, transform 0.1s;
`;
confirmBtn.addEventListener('mouseenter', () => {
confirmBtn.style.background = '#29b6f6';
});
confirmBtn.addEventListener('mouseleave', () => {
confirmBtn.style.background = '#4fc3f7';
});
confirmBtn.addEventListener('mousedown', () => {
confirmBtn.style.transform = 'scale(0.96)';
});
confirmBtn.addEventListener('mouseup', () => {
confirmBtn.style.transform = 'scale(1)';
});
function updateDisplay() {
if (typeof window.clickX === 'number' && typeof window.clickY === 'number') {
display.innerHTML = `
clickX: ${window.clickX}
clickY: ${window.clickY}
`;
} else {
display.innerHTML = '等待输入...';
}
}
function parseCoords(value) {
const cleaned = value.replace(/[xyXY]:/g, '').replace(/[^\d\s,.-]/g, '');
const parts = cleaned.split(/[,\s]+/).filter(p => p.trim() !== '');
if (parts.length >= 2) {
const x = parseInt(parts[0], 10);
const y = parseInt(parts[1], 10);
if (!isNaN(x) && !isNaN(y)) {
return { x, y };
}
}
return null;
}
function applyCoords() {
const coords = parseCoords(input.value);
if (coords) {
window.clickX = coords.x;
window.clickY = coords.y;
input.style.borderColor = '#81c784';
updateDisplay();
console.log(`[坐标] 已更新。 ${window.clickX}, ${window.clickY}`);
return true;
} else {
input.style.borderColor = '#e57373';
if (input.value.trim() === '') {
window.clickX = undefined;
window.clickY = undefined;
}
updateDisplay();
console.log(`[坐标] 更新失败。`);
return false;
}
}
// 实时输入
input.addEventListener('input', applyCoords);
// 回车确认
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
if (applyCoords()) {
input.style.background = '#1b3a1b';
setTimeout(() => input.style.background = '#2a2a2a', 300);
}
}
});
// 按钮确认
confirmBtn.addEventListener('click', () => {
if (applyCoords()) {
input.style.background = '#1b3a1b';
setTimeout(() => input.style.background = '#2a2a2a', 300);
}
});
// 组装
btnRow.appendChild(confirmBtn);
container.appendChild(title);
container.appendChild(input);
container.appendChild(display);
container.appendChild(btnRow);
document.body.appendChild(container);
// 初始化默认值
window.clickX = DEFAULT_X;
window.clickY = DEFAULT_Y;
updateDisplay();
console.log(`[坐标记录器] 已加载。默认坐标: ${DEFAULT_X}, ${DEFAULT_Y}`);
// ==UserScript==
const tooltip = document.createElement('div');
tooltip.id = 'mouse-screen-coord-tooltip';
tooltip.style.cssText = `
position: fixed;
pointer-events: none;
z-index: 999999;
background: rgba(0, 0, 0, 0.75);
color: #00ff88;
font-family: 'Courier New', monospace;
font-size: 12px;
padding: 4px 8px;
border-radius: 4px;
white-space: nowrap;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
border: 1px solid rgba(0, 255, 136, 0.3);
user-select: none;
transition: opacity 0.15s;
opacity: 0;
`;
document.body.appendChild(tooltip);
let mouseX = 0, mouseY = 0;
let ticking = false;
document.addEventListener('mousemove', (e) => {
// tooltip 定位仍用 clientX/clientY(基于视口)
mouseX = e.clientX;
mouseY = e.clientY;
if (!ticking) {
window.requestAnimationFrame(() => {
// 屏幕坐标:相对于整个显示器屏幕左上角
const sx = e.clientX;
const sy = e.clientY;
tooltip.textContent = `${sx},${sy}`;
tooltip.style.opacity = '1';
const offset = 15;
let left = mouseX + offset;
let top = mouseY + offset;
const rect = tooltip.getBoundingClientRect();
if (left + rect.width > window.innerWidth) {
left = mouseX - rect.width - offset;
}
if (top + rect.height > window.innerHeight) {
top = mouseY - rect.height - offset;
}
tooltip.style.left = left + 'px';
tooltip.style.top = top + 'px';
ticking = false;
});
ticking = true;
}
});
document.addEventListener('mouseleave', () => {
tooltip.style.opacity = '0';
});
console.log('[鼠标屏幕坐标] 脚本已加载');
//输入框结尾
let isProcessing = false;
let lastDialogCloseTime = 0; // 记录上次弹窗关闭时间,避免残留误判
function isDialogVisible() {
// 检查选项是否存在且可见
const radios = document.querySelectorAll('.el-radio');
if (radios.length < 2) return false;
// 检查第一个 radio 是否在视觉上可见(宽高大于0且未被隐藏)
const firstRadio = radios[0];
if (firstRadio.offsetParent === null) return false;
// 额外检查弹窗容器是否可见
const dialog = document.querySelector('.el-dialog');
return dialog !== null;
}
function selectRadio(index) {
const radios = document.querySelectorAll('.el-radio');
if (!radios.length) return false;
const target = radios[index];
target.click();
const input = target.querySelector('input[type="radio"]');
if (input) {
input.checked = true;
input.dispatchEvent(new Event('input', { bubbles: true }));
input.dispatchEvent(new Event('change', { bubbles: true }));
}
console.log(`✅ 已选择选项 ${index + 1}: ${target.textContent.trim()}`);
return true;
}
function simulateClick(x, y) {
console.log(`🖱️ 在坐标 (${x}, ${y}) 模拟鼠标点击`);
// 获取该坐标下的顶层元素
const target = document.elementFromPoint(x, y);
if (!target) {
console.warn('坐标处无元素');
return false;
}
console.log(` 目标元素: ${target.tagName}.${target.className}`);
// 派发完整鼠标事件序列
const events = [
new PointerEvent('pointerdown', { bubbles: true, cancelable: true, clientX: x, clientY: y }),
new MouseEvent('mousedown', { bubbles: true, cancelable: true, clientX: x, clientY: y }),
new PointerEvent('pointerup', { bubbles: true, cancelable: true, clientX: x, clientY: y }),
new MouseEvent('mouseup', { bubbles: true, cancelable: true, clientX: x, clientY: y }),
new MouseEvent('click', { bubbles: true, cancelable: true, clientX: x, clientY: y })
];
const element = document.elementFromPoint(x, y);
if (element) {
const clickEvent = new MouseEvent('click', {view: window,bubbles: true,cancelable: true,clientX: x,clientY: y});
element.dispatchEvent(clickEvent);
} else {
console.log("未找到对应坐标的元素");
}
events.forEach(event => target.dispatchEvent(event));
return true;
}
function doSequence() {
if (isProcessing) return;
isProcessing = true;
// 第一步:选正确并确认
selectRadio(0);
setTimeout(() => simulateClick(window.clickX, window.clickY), 100);
// 1秒后第二步
setTimeout(() => {
// 重新检查弹窗是否还在(可能已关闭)
if (!isDialogVisible()) {
console.warn('弹窗已提前关闭,跳过第二步');
isProcessing = false;
return;
}
selectRadio(1);
setTimeout(() => simulateClick(window.clickX, window.clickY), 100);
// 完成标记
setTimeout(() => {
isProcessing = false;
lastDialogCloseTime = Date.now();
console.log('✅ 流程完成,等待下一次弹窗');
}, 2000);
}, 1000);
}
// 主循环:每 500ms 检查一次弹窗
setInterval(() => {
if (isProcessing) return;
// 弹窗关闭后 3 秒内不触发(防止弹窗关闭动画导致的误判)
if (Date.now() - lastDialogCloseTime < 3000) return;
if (isDialogVisible()) {
console.log('🔔 检测到弹窗');
doSequence();
}
}, 500);
// 同时保留 MutationObserver 作为补充(处理弹窗通过插入新节点出现的情况)
const observer = new MutationObserver(mutations => {
for (const m of mutations) {
if (!m.addedNodes.length) continue;
for (const node of m.addedNodes) {
if (node.nodeType !== 1) continue;
if (node.querySelectorAll('.el-radio').length >= 2) {
if (!isProcessing && Date.now() - lastDialogCloseTime >= 3000) {
console.log('🔔 DOM 新增弹窗');
doSequence();
}
return;
}
}
}
});
const tooltip1 = document.createElement('div');
tooltip1.id = 'mouse-screen-coord-tooltip1';
tooltip1.style.cssText = `
position: fixed;
pointer-events: none;
z-index: 999999;
background: rgba(0, 0, 0, 0.75);
color: #00ff88;
font-family: 'Courier New', monospace;
font-size: 12px;
padding: 4px 8px;
border-radius: 4px;
white-space: nowrap;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
border: 1px solid rgba(0, 255, 136, 0.3);
user-select: none;
transition: opacity 0.15s;
opacity: 0;
`;
document.body.appendChild(tooltip1);
document.addEventListener('mousemove', (e) => {
// tooltip 定位仍用 clientX/clientY(基于视口)
mouseX = e.clientX;
mouseY = e.clientY;
if (!ticking) {
window.requestAnimationFrame(() => {
// 屏幕坐标:相对于整个显示器屏幕左上角
const sx = e.clientX;
const sy = e.clientY;
tooltip.textContent = `${sx},${sy}`;
tooltip.style.opacity = '1';
const offset = 15;
let left = mouseX + offset;
let top = mouseY + offset;
const rect = tooltip.getBoundingClientRect();
if (left + rect.width > window.innerWidth) {
left = mouseX - rect.width - offset;
}
if (top + rect.height > window.innerHeight) {
top = mouseY - rect.height - offset;
}
tooltip.style.left = left + 'px';
tooltip.style.top = top + 'px';
ticking = false;
});
ticking = true;
}
});
document.addEventListener('mouseleave', () => {
tooltip1.style.opacity = '0';
});
console.log('[鼠标屏幕坐标] 脚本已加载');
})();