// ==UserScript== // @name 点云标注-终极完整版 // @namespace http://tampermonkey.net/ // @version 5.0 // @description F2快捷键:打开批注弹窗 → 点击combobox下拉容器展开下拉列表 → 选中属性错误 → 点击确定提交 // @author You // @match *://*/* // @grant none // ==/UserScript== (function() { 'use strict'; const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); // 获取工具栏第5个批注按钮 function getTargetCommentBtn() { const toolBtns = document.querySelectorAll('div[role="toolbar"] button,.toolbar button'); const btnArr = Array.from(toolBtns); const targetBtn = btnArr[4]; if (targetBtn) { const rect = targetBtn.getBoundingClientRect(); if (rect.width > 15 && rect.height > 15) { return targetBtn; } } return null; } // 等待元素 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; } // 全局文本查找DOM function findElByText(text) { const all = document.querySelectorAll('*'); for (let 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 x = rect.left + rect.width / 2; const y = rect.top + rect.height / 2; const opts = { clientX: x, clientY: y, bubbles: true, cancelable: true }; el.dispatchEvent(new MouseEvent('mouseover', opts)); await sleep(60); el.dispatchEvent(new MouseEvent('mousedown', opts)); await sleep(60); el.dispatchEvent(new MouseEvent('mouseup', opts)); await sleep(60); el.dispatchEvent(new MouseEvent('click', opts)); if (typeof el.click === "function") el.click(); } async function runTask() { console.log("\n==========【批注任务开始】=========="); // 1、打开批注弹窗 const triggerBtn = getTargetCommentBtn(); if (!triggerBtn) { console.error("❌找不到工具栏第5个批注按钮"); return; } await realClick(triggerBtn); await sleep(1400); const dialog = await waitElement('div[role="dialog"]'); if (!dialog) { console.error("❌批注弹窗没有出现"); return; } console.log("✅批注弹窗已打开"); // 2、点击下拉容器展开下拉浮层(不再依赖“请选择”文字) const combobox = dialog.querySelector('[role="combobox"]'); if (!combobox) { console.error("❌弹窗内找不到 [role=combobox] 下拉组件"); return; } console.log("✅找到下拉容器,执行点击展开下拉"); await realClick(combobox); await sleep(1500); // 3、下拉浮层挂在body,全局查找属性错误 const optionNode = findElByText("属性错误"); if (!optionNode) { console.error("❌页面全局找不到【属性错误】下拉选项"); return; } console.log("✅找到【属性错误】选项,执行点击"); await realClick(optionNode); await sleep(1000); //4、点击确定按钮提交 const confirmBtn = findElByText("确定"); if (!confirmBtn) { console.error("❌找不到【确定】按钮"); return; } await realClick(confirmBtn); console.log("✅全部流程执行完毕"); } // F2热键绑定 document.addEventListener('keydown', async function (e) { if (e.key === 'F2') { e.preventDefault(); await runTask(); } }); console.log("✅脚本加载完毕,选中标注框按下F2运行"); })();