// ==UserScript== // @name 点云标注-请选择点击展开完整版 // @namespace http://tampermonkey.net/ // @version 4.8 // @description F2热键:唤起弹窗→点击“请选择”展开下拉→选中属性错误→点击确定;控制台看每一步日志 // @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, root = document) { const all = root.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 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("==========开始批注流程=========="); // 1.打开批注弹窗 const triggerBtn = getTargetCommentBtn(); if (!triggerBtn) { console.error("❌找不到工具栏批注按钮"); return; } await realClick(triggerBtn); await sleep(1300); const dialog = await waitElement('div[role="dialog"]'); if (!dialog) { console.error("❌批注弹窗未加载出来"); return; } console.log("✅弹窗已经打开"); // 2.点击弹窗内“请选择”展开下拉列表 const selectTrigger = findElByText("请选择", dialog); if (!selectTrigger) { console.error("❌弹窗内找不到【请选择】"); return; } console.log("✅找到【请选择】,点击展开下拉"); await realClick(selectTrigger); await sleep(1300); // 3.全局查找“属性错误”选项(下拉浮层挂载在body) const optionNode = findElByText("属性错误"); if (!optionNode) { console.error("❌全局找不到【属性错误】选项"); return; } console.log("✅找到【属性错误】选项,执行点击"); await realClick(optionNode); await sleep(900); // 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执行;注意:Electron‑React环境JS模拟点击可能被组件拦截,看控制台日志判断卡点"); })();