// ==UserScript== // @name 点云标注·最终兼容完整版 // @namespace http://tampermonkey.net/ // @version 5.4 // @description 手动弹出【指定标签批注】弹窗,按F2;点击下拉、选属性错误、点确定。不再依赖role=combobox // @author You // @match *://*/* // @grant none // ==/UserScript== (function () { 'use strict'; const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); async function waitElement(selector, timeout = 5000) { const start = Date.now(); while (Date.now() - start < timeout) { const el = document.querySelector(selector); if (el) return el; await sleep(150); } return null; } // 文本查找 function findElByText(text) { const all = document.querySelectorAll('*'); for (const el of all) { const txt = el.textContent?.trim(); if (txt === text) return el; } return null; } // 完整鼠标事件模拟 async function realClick(el) { if (!el) return; const rect = el.getBoundingClientRect(); const opts = { clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, bubbles: true, cancelable: true }; el.dispatchEvent(new MouseEvent('mouseover', opts)); await sleep(50); el.dispatchEvent(new MouseEvent('mousedown', opts)); await sleep(50); el.dispatchEvent(new MouseEvent('mouseup', opts)); await sleep(50); el.dispatchEvent(new MouseEvent('click', opts)); } // 派发键盘事件 function keyDownEv(el, key) { el.dispatchEvent(new KeyboardEvent('keydown', { key: key, bubbles: true })); } async function runTask() { console.log("\n========== F2任务开始 =========="); // 检测弹窗 const dialog = await waitElement('div[role="dialog"]'); if (!dialog) { console.error("❌没有找到弹窗,请手动打开【指定标签批注】弹窗后再按F2"); return; } console.log("✅已识别批注弹窗"); // 弹窗内找select下拉容器:找包含“请选择”文本的父容器 let selectWrap = null; const nodes = dialog.querySelectorAll('*'); for (const n of nodes) { if (n.textContent?.includes('请选择')) { selectWrap = n; break; } } if (!selectWrap) { console.error("❌弹窗内找不到下拉容器(包含请选择的DOM)"); return; } console.log("✅定位下拉容器,点击展开"); await realClick(selectWrap); await sleep(900); keyDownEv(selectWrap, 'ArrowDown'); await sleep(1300); // 选中属性错误 const opt = findElByText("属性错误"); if (!opt) { console.error("❌找不到【属性错误】下拉选项"); return; } console.log("✅找到属性错误,执行点击"); await realClick(opt); await sleep(1000); // 点击确定 const okBtn = findElByText("确定"); if (!okBtn) { console.error("❌找不到【确定】按钮"); return; } await realClick(okBtn); console.log("✅全部流程执行完毕"); } // F2热键 document.addEventListener('keydown', async e => { if (e.key === 'F2') { e.preventDefault(); await runTask(); } }); console.log("✅脚本加载完毕:手动打开批注弹窗,弹窗出来后按F2"); })();