自动化LeetCode题解发布扩展开发疑难求助:DOM操作、Monaco编辑器等问题
自动化LeetCode题解发布扩展开发疑难求助:DOM操作、Monaco编辑器等问题
我正在开发一款Chrome扩展(基于Manifest V3和Plasmo框架),目的是在LeetCode题解通过后自动发布题解。核心需求很明确:打开「发布题解」页面、自动填充标题输入框、给Monaco编辑器填入格式化的题解模板。但开发过程中遇到了几个棘手的问题,折腾了好久还是没完全解决,想请教各位大佬支招!
我的开发环境与实现思路
- 环境:基于Manifest V3的Chrome扩展,采用Plasmo框架开发
- 核心组件:
- 后台脚本:负责标签页创建和跨脚本消息通信
- 内容脚本:专门处理「发布题解」页面的DOM交互逻辑
- 实现逻辑:后台脚本先打开题解发布页,等页面加载完成后,给对应标签的内容脚本发送模板消息,由内容脚本完成标题填充和编辑器内容注入
遇到的问题与已尝试方案
1. 标题输入框填充不稳定
问题:有时候输入框只显示部分内容(比如“Automated Title”变成“tomated Title”),甚至完全没反应,偶尔还会被页面的监听事件重置内容。
已尝试的方法:
- 直接设置value并触发事件:
结果:偶尔有效,但经常要么不生效,要么触发页面的重置逻辑。inputElement.value = "Automated Title"; inputElement.dispatchEvent(new Event("input", { bubbles: true })); inputElement.dispatchEvent(new Event("change", { bubbles: true })); - 模拟逐字符按键事件:
结果:比直接设置好一些,但还是偶尔出现内容不全的情况,看起来是页面的外部监听或者DOM更新干扰了输入过程。for (const char of text) { inputElement.value += char; inputElement.dispatchEvent(new KeyboardEvent("keydown", { key: char })); inputElement.dispatchEvent(new KeyboardEvent("keypress", { key: char })); inputElement.dispatchEvent(new KeyboardEvent("keyup", { key: char })); } - 剪贴板粘贴:
结果:除非有用户交互(比如点击按钮),否则会抛出NotAllowedError,没法正常使用。await navigator.clipboard.writeText("Automated Title"); const pasteEvent = new ClipboardEvent("paste", { bubbles: true }); inputElement.dispatchEvent(pasteEvent);
2. 无法访问Monaco编辑器API
问题:LeetCode的题解编辑器是Monaco Editor,它的monaco.editor.getModels()[0] API在内容脚本里访问不到,因为内容脚本和页面主执行上下文是隔离的。
已尝试的方法:
- 直接调用Monaco API:
结果:在浏览器控制台里完全正常,但内容脚本里报错const model = monaco.editor.getModels()[0]; model.setValue(template);monaco is undefined。 - 注入代码到主上下文:
结果:主上下文里也找不到chrome.scripting.executeScript({ target: { tabId: tab.id }, world: "MAIN", func: pasteTemplateIntoPage, args: [template], });monaco,应该是LeetCode的CSP限制导致的。
3. 触发429请求限流
问题:填充标题的时候偶尔会触发LeetCode的后端请求,导致返回429 Too Many Requests错误。
已尝试的方法:
- 在操作之间加延迟
- 减少不必要的事件触发
- 使用防抖函数避免频繁交互
结果:操作太频繁的话还是会触发限流。
我的代码片段
后台脚本
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.action === "openSubmissionPage") { chrome.tabs.create({ url: message.url, active: true }, (tab) => { if (tab?.id) { chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo) { if (tabId === tab.id && changeInfo.status === "complete") { chrome.tabs.onUpdated.removeListener(listener); chrome.tabs.sendMessage(tab.id, { action: "pasteTemplate", template: message.template }); } }); } }); } });
内容脚本(标题填充函数)
async function typeIntoInputField(selector, text) { const inputElement = document.querySelector(selector); if (!inputElement) return; inputElement.value = ""; for (const char of text) { inputElement.value += char; inputElement.dispatchEvent(new KeyboardEvent("keydown", { key: char })); inputElement.dispatchEvent(new KeyboardEvent("keypress", { key: char })); inputElement.dispatchEvent(new KeyboardEvent("keyup", { key: char })); await new Promise((r) => setTimeout(r, 100)); } }
急需大佬帮忙解决的问题
- 怎么才能稳定可靠地设置标题输入框的内容,避免部分更新或者被重置?
- 在Chrome扩展里,操作Monaco Editor的最优方案是什么?
- 如何避免DOM操作触发LeetCode的429限流?
- 还有哪些更健壮的模拟用户交互(打字、粘贴)的方法?
我已经试过直接DOM操作、模拟按键、剪贴板粘贴、注入主上下文代码这些方法,但还是存在兼容性和可靠性问题,希望各位能给点思路或者替代方案,万分感谢!
备注:内容来源于stack exchange,提问作者Shivansh Jaiswal
相关产品推荐
相关产品推荐

