// ==UserScript== // @name 点云标注-指定标签批注完整版 // @namespace http://tampermonkey.net/ // @version 3.8 // @description F2快捷键:打开弹窗→点开下拉→选中属性错误→直接点击确定,不操作备注框 // @author You // @match *://*/* // @grant none // ==/UserScript== (function() { 'use strict'; const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); // 获取工具栏第5个按钮(下标4) 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=4000){ 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 findByText(text){ const all = document.querySelectorAll('*'); for(let el of all){ if(el.textContent && el.textContent.trim() === text){ return el; } } return null; } // 模拟hover+完整鼠标事件,适配ant‑select下拉组件 async function realClickWithHover(el){ if(!el) return; const rect = el.getBoundingClientRect(); const x = rect.left + rect.width / 2; const y = rect.top + rect.height / 2; el.dispatchEvent(new MouseEvent('mouseover', {clientX:x, clientY:y, bubbles:true})); await sleep(120); el.dispatchEvent(new MouseEvent('mousedown', {clientX:x, clientY:y, bubbles:true})); await sleep(80); el.dispatchEvent(new MouseEvent('mouseup', {clientX:x, clientY:y, bubbles:true})); await sleep(80); el.dispatchEvent(new MouseEvent('click', {clientX:x, clientY:y, bubbles:true})); el.click(); } async function runTask(){ console.log("\n=====【开始整套批注】====="); // 1、点击工具栏批注按钮,弹出弹窗 const triggerBtn = getTargetCommentBtn(); if(!triggerBtn){ console.error("❌找不到工具栏第5个批注按钮"); return; } console.log("✅1.点击工具栏批注按钮"); await realClickWithHover(triggerBtn); await sleep(900); const dialog = await waitElement('div[role="dialog"]'); if(!dialog){ console.error("❌批注弹窗未打开"); return; } console.log("✅弹窗已打开"); // 2、点开类型下拉框 const selectTrigger = dialog.querySelector('div[role="combobox"]'); if(!selectTrigger){ console.error("❌找不到下拉触发器 combobox"); return; } console.log("✅2.点击下拉框展开菜单"); await realClickWithHover(selectTrigger); await sleep(1000); const listBox = await waitElement('div[role="listbox"]'); if(!listBox){ console.error("❌下拉浮层listbox未弹出"); return; } // 3、选中属性错误选项 const attrErrItem = findByText("属性错误"); if(!attrErrItem){ console.error("❌下拉列表找不到【属性错误】"); return; } console.log("✅3.hover并点击【属性错误】"); await realClickWithHover(attrErrItem); await sleep(800); // 4、直接点击确定,跳过备注 const okBtn = findByText("确定"); if(!okBtn){ console.error("❌找不到【确定】按钮"); return; } console.log("✅4.点击确定提交"); await realClickWithHover(okBtn); console.log("=====✅全部流程执行完毕====="); } // F2快捷键触发 document.addEventListener('keydown', async function(e){ if(e.key === 'F2'){ e.preventDefault(); await runTask(); } }); console.log("✅脚本加载完成!选中物体按F2运行"); })();