基础版:数字键触发单个标签 click
(function () {
const labels = ["路中障碍物", "施工区域", "基本可见", "部分可见", "运动", "静上"];
// 防止重复注入
const old = document.getElementById("label-hotkey-panel");
if (old) old.remove();
const panel = document.createElement("div");
panel.id = "label-hotkey-panel";
panel.style.cssText =
"position:fixed;top:20px;right:20px;z-index:999999;background:rgba(0,0,0,.85);" +
"color:#fff;padding:12px;border-radius:10px;font-size:14px;min-width:220px;";
function getEl(name) {
return document.querySelector(`span.label[title="${name}"]`);
}
labels.forEach((name, idx) => {
const row = document.createElement("div");
row.style.cssText = "display:flex;align-items:center;justify-content:space-between;margin:6px 0;";
const info = document.createElement("span");
info.textContent = `[${idx + 1}] ${name}`;
const btn = document.createElement("button");
btn.textContent = getEl(name) ? "点击" : "不存在";
btn.style.cssText = `cursor:pointer;border:none;padding:4px 8px;border-radius:6px;
background:${getEl(name) ? "#409eff" : "#666"};color:white;`;
btn.onclick = () => {
const el = getEl(name);
el ? el.click() : console.warn("未找到:", name);
};
row.append(info, btn);
panel.appendChild(row);
});
document.body.appendChild(panel);
document.addEventListener("keydown", (e) => {
const n = parseInt(e.key);
if (!isNaN(n) && n >= 1 && n <= labels.length) {
const el = getEl(labels[n - 1]);
el ? el.click() : console.warn("未找到:", labels[n - 1]);
}
});
})();
数据驱动 radio 分组版(推荐维护方式)
多个分组各自单选,按反引号 ` 执行当前选择:
(function () {
if (document.getElementById("label-panel")) return;
// 只改这里就能增减标签
const groups = {
g1: { title: "第一组", options: ["路中障碍物", "施工区域"] },
g2: { title: "第二组", options: ["基本可见", "部分可见", "基本不可见"] },
g3: { title: "���三组", options: ["运动", "禁止"] }
};
const panel = document.createElement("div");
panel.id = "label-panel";
panel.style.cssText =
"position:fixed;top:20px;right:20px;z-index:999999;background:#fff;" +
"border:1px solid #ccc;border-radius:8px;padding:12px;" +
"box-shadow:0 0 10px rgba(0,0,0,.2);font-size:14px;width:240px;";
// 动态渲染 HTML
const html = Object.entries(groups)
.map(([key, group]) => {
const radios = group.options
.map((opt, idx) => `
<label style="display:block;margin:2px 0;">
<input type="radio" name="${key}" value="${opt}" ${idx === 0 ? "checked" : ""}>${opt}
</label>`)
.join("");
return `<div style="margin-bottom:8px;"><b>${group.title}</b><div>${radios}</div></div>`;
})
.join("");
panel.innerHTML = `
<div style="font-weight:bold;margin-bottom:10px;">标签快捷选择</div>
${html}
<hr>
<div style="font-size:12px;color:#666;">反引号 = 执行</div>
`;
document.body.appendChild(panel);
function clickLabel(title) {
const el = document.querySelector(`span.label[title="${title}"]`);
el ? el.click() : console.warn("未找到:", title);
}
function execute() {
Object.keys(groups).forEach(key => {
const selected = document.querySelector(`input[name="${key}"]:checked`);
if (selected) clickLabel(selected.value);
});
}
document.addEventListener("keydown", e => {
if (["INPUT", "TEXTAREA"].includes(e.target.tagName)) return;
if (e.key === "`") { e.preventDefault(); execute(); }
if (e.key === "Tab") {
e.preventDefault();
document.querySelector('input[type="checkbox"][value="开启高层过滤"]')?.click();
}
});
})();
添加拖拽与折叠
// 拖动
let dragging = false, ox = 0, oy = 0;
panel.addEventListener("mousedown", e => {
if (e.target.tagName === "INPUT") return;
dragging = true;
ox = e.clientX - panel.offsetLeft;
oy = e.clientY - panel.offsetTop;
});
document.addEventListener("mousemove", e => {
if (!dragging) return;
panel.style.left = (e.clientX - ox) + "px";
panel.style.top = (e.clientY - oy) + "px";
panel.style.right = "auto";
});
document.addEventListener("mouseup", () => dragging = false);
// 折叠
let collapsed = false;
panel.querySelector("#toggle-btn").onclick = () => {
collapsed = !collapsed;
panel.querySelector(".body").style.display = collapsed ? "none" : "block";
};
面板头部加折叠按钮:
<div style="display:flex;justify-content:space-between;align-items:center;cursor:pointer">
<b>label</b>
<span id="toggle-btn">[-]</span>
</div>
<div class="body">...</div>
Python 批量转义 JS 中的汉字
把 JS 文件里的中文字符替换成 \uXXXX,代码仍然可以在浏���器运行:
import re
def encode_chinese(js):
def repl(m):
return ''.join(f'\\u{ord(c):04x}' for c in m.group(0))
return re.sub(r'[一-鿿]+', repl, js)
js_code = '''
const title = "路中障碍���";
document.querySelector('span.label[title="施工区域"]');
'''
print(encode_chinese(js_code))
# const title = "路中障碍物";
# document.querySelector('span.label[title="施工区域"]');
只替换汉字,JS 语法和 ASCII 字符保持不变,浏览器完全等价执行。
