如何通过UserScript获取DeepL翻译结果?已尝试change事件与MutationObserver
解决DeepL翻译结果获取问题的可行方案
一、修复模拟输入的触发逻辑
你当前直接修改source textarea的value并触发keyup事件,大概率无法触发DeepL内部的输入检测机制(DeepL用了React这类框架,直接改DOM值不会同步框架内部状态)。可以用以下两种更贴近真实用户输入的方式:
方法1:使用document.execCommand插入文本
这种方式能完整触发框架的输入监听:
document.addEventListener('click', (event) => { const sourceTextarea = document.querySelector(".lmt__source_textarea"); sourceTextarea.focus(); document.execCommand('selectAll'); // 选中原有内容 document.execCommand('insertText', false, '测试一下在线翻译服务'); // 插入新文本 });
方法2:触发标准input事件
如果execCommand失效,手动构造并触发input事件同步状态:
document.addEventListener('click', (event) => { const sourceTextarea = document.querySelector(".lmt__source_textarea"); sourceTextarea.value = '测试一下在线翻译服务'; const inputEvent = new Event('input', { bubbles: true, cancelable: true }); sourceTextarea.dispatchEvent(inputEvent); });
二、优化翻译结果的监听逻辑
方法1:确保元素加载完成后绑定input事件
避免因DOM未加载完成导致事件绑定失败:
// 等待目标元素加载的工具函数 function waitForElement(selector) { return new Promise(resolve => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); } const observer = new MutationObserver(() => { if (document.querySelector(selector)) { observer.disconnect(); resolve(document.querySelector(selector)); } }); observer.observe(document.body, { childList: true, subtree: true }); }); } // 绑定input事件监听结果 waitForElement('.lmt__target_textarea').then(targetTextarea => { targetTextarea.addEventListener('input', () => { const result = targetTextarea.value.trim(); if (result) { console.log('翻译结果:', result); // 这里添加你的处理逻辑,比如发送到WebSocket } }); });
方法2:扩大MutationObserver的监听范围
有时候DeepL会通过子元素更新内容,监听目标textarea的完整内容变化:
waitForElement('.lmt__target_textarea').then(targetTextarea => { const observer = new MutationObserver(() => { const result = targetTextarea.value.trim(); if (result) { console.log('翻译结果:', result); } }); observer.observe(targetTextarea, { characterData: true, childList: true, subtree: true, attributes: true }); });
方法3:拦截DeepL的API请求(最稳定)
直接监听翻译接口的请求响应,不受DOM结构变化影响:
const originalFetch = window.fetch; window.fetch = async (...args) => { const response = await originalFetch(...args); if (args[0].includes('translate')) { const clone = response.clone(); clone.json().then(data => { const translation = data.translations?.[0]?.text; if (translation) { console.log('API直接获取翻译结果:', translation); } }); } return response; };
三、完整的UserScript示例
// ==UserScript== // @name DeepL翻译结果获取脚本 // @namespace Violentmonkey Scripts // @match https://www.deepl.com/* // @grant none // @version 1.0 // @author - // @description 获取DeepL翻译结果 // ==/UserScript== // 等待元素加载工具函数 function waitForElement(selector) { return new Promise(resolve => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); } const observer = new MutationObserver(() => { if (document.querySelector(selector)) { observer.disconnect(); resolve(document.querySelector(selector)); } }); observer.observe(document.body, { childList: true, subtree: true }); }); } // 模拟真实输入 document.addEventListener('click', async (event) => { const sourceTextarea = await waitForElement(".lmt__source_textarea"); sourceTextarea.focus(); document.execCommand('selectAll'); document.execCommand('insertText', false, '测试一下在线翻译服务'); }); // 监听翻译结果 waitForElement('.lmt__target_textarea').then(targetTextarea => { targetTextarea.addEventListener('input', () => { const result = targetTextarea.value.trim(); if (result) { console.log('翻译结果:', result); // 这里添加你的处理逻辑,比如发送到WebSocket // const socket = new WebSocket('ws://127.0.0.1:8522'); // socket.onopen = () => socket.send(result); } }); }); // 可选:拦截API请求获取结果 const originalFetch = window.fetch; window.fetch = async (...args) => { const response = await originalFetch(...args); if (args[0].includes('translate')) { const clone = response.clone(); clone.json().then(data => { const translation = data.translations?.[0]?.text; if (translation) { console.log('API获取翻译结果:', translation); } }).catch(err => console.log('解析API结果失败:', err)); } return response; };
内容的提问来源于stack exchange,提问作者iMath
相关产品推荐
相关产品推荐

