V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  mirakyux  ›  全部回复第 2 页 / 共 3 页
回复总数  42
1  2  3  
@Lowlife #1 是的, 我十几个闹钟也能不准
https://i.imgur.com/nfyrjhn.png
整页翻译有点慢
```javascript
// ==UserScript==
// @name 网页翻译 + 划词翻译气泡( Translator API )
// @namespace http://tampermonkey.net/
// @version 0.3
// @description 使用浏览器内置 Translator API 翻译网页或选中文本,并缓存语言设置(默认 英→中)
// @author mirakyux
// @match *://*/*
// @grant none
// @run-at document_idle
// ==/UserScript==

(async function() {
'use strict';

// ======== 配置与缓存 ========
const cacheKey = 'translator_langs';
const saved = JSON.parse(localStorage.getItem(cacheKey) || '{}');
let sourceLang = saved.sourceLang || 'en';
let targetLang = saved.targetLang || 'zh';

function saveLang() {
localStorage.setItem(cacheKey, JSON.stringify({ sourceLang, targetLang }));
}

// ======== 样式 ========
function style(el, css) {
Object.assign(el.style, css);
}

// ======== 悬浮按钮(整页) ========
const pageBtn = document.createElement('button');
pageBtn.textContent = '🌐 翻译网页';
style(pageBtn, {
position: 'fixed',
bottom: '20px',
right: '20px',
zIndex: 9999,
padding: '10px 16px',
backgroundColor: '#007bff',
color: '#fff',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
boxShadow: '0 2px 6px rgba(0,0,0,0.3)',
fontSize: '14px',
opacity: '0.85',
transition: 'opacity 0.3s'
});
pageBtn.onmouseenter = () => (pageBtn.style.opacity = '1');
pageBtn.onmouseleave = () => (pageBtn.style.opacity = '0.85');
document.body.appendChild(pageBtn);

// ======== 检测 Translator API ========
async function isTranslatorAvailable() {
if (!('Translator' in self)) {
console.error('❌ 当前浏览器不支持 Translator API 。请启用 chrome://flags/#translation-api');
return false;
}
try {
const avail = await self.Translator.availability({
sourceLanguage: sourceLang,
targetLanguage: targetLang
});
if (avail === 'unavailable') {
console.error(`❌ 不支持语言对 ${sourceLang} → ${targetLang}`);
return false;
}
console.log(`✅ Translator API 可用 (${avail})`);
return true;
} catch (err) {
console.error('❌ Translator API 检测失败:', err);
return false;
}
}

async function createTranslator() {
return await self.Translator.create({
sourceLanguage: sourceLang,
targetLanguage: targetLang
});
}

// ======== 整页翻译逻辑 ========
async function translatePage() {
const available = await isTranslatorAvailable();
if (!available) {
alert('当前浏览器不支持内置翻译 API ,请查看控制台提示。');
return;
}
pageBtn.disabled = true;
pageBtn.textContent = '翻译中…';
const translator = await createTranslator();

const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {
acceptNode: (node) => {
if (!node.nodeValue.trim()) return NodeFilter.FILTER_REJECT;
if (node.parentElement && ['SCRIPT', 'STYLE', 'NOSCRIPT'].includes(node.parentElement.tagName))
return NodeFilter.FILTER_REJECT;
return NodeFilter.FILTER_ACCEPT;
}
});

const textNodes = [];
while (walker.nextNode()) textNodes.push(walker.currentNode);

for (const node of textNodes) {
const text = node.nodeValue.trim();
if (!text || text.length > 2000) continue;
try {
const translated = await translator.translate(text);
node.nodeValue = translated;
} catch (err) {
console.warn('跳过节点:', err);
}
}

pageBtn.textContent = '✅ 已翻译';
setTimeout(() => {
pageBtn.textContent = '🌐 翻译网页';
pageBtn.disabled = false;
}, 3000);
}

pageBtn.addEventListener('click', translatePage);

// ======== 划词翻译气泡 ========
const bubble = document.createElement('div');
style(bubble, {
position: 'absolute',
background: '#007bff',
color: '#fff',
padding: '6px 10px',
borderRadius: '6px',
fontSize: '13px',
cursor: 'pointer',
display: 'none',
zIndex: 99999,
userSelect: 'none',
whiteSpace: 'nowrap',
boxShadow: '0 2px 6px rgba(0,0,0,0.3)'
});
bubble.textContent = '翻译';
document.body.appendChild(bubble);

let currentSelection = '';
document.addEventListener('selectionchange', () => {
const sel = window.getSelection();
const text = sel.toString().trim();
if (text.length > 0) {
const range = sel.getRangeAt(0);
const rect = range.getBoundingClientRect();
bubble.style.left = `${rect.right + window.scrollX + 10}px`;
bubble.style.top = `${rect.top + window.scrollY - 10}px`;
bubble.style.display = 'block';
currentSelection = text;
} else {
bubble.style.display = 'none';
}
});

bubble.addEventListener('click', async () => {
if (!currentSelection) return;
const available = await isTranslatorAvailable();
if (!available) return alert('当前浏览器不支持 Translator API');
const translator = await createTranslator();
bubble.textContent = '翻译中…';
try {
const translated = await translator.translate(currentSelection);
alert(` [${sourceLang} → ${targetLang}] \n\n${translated}`);
} catch (e) {
alert('翻译失败:' + e.message);
} finally {
bubble.textContent = '翻译';
bubble.style.display = 'none';
}
});

// ======== 设置按钮 ========
const configBtn = document.createElement('button');
configBtn.textContent = '⚙️ 设置';
style(configBtn, {
position: 'fixed',
bottom: '60px',
right: '20px',
zIndex: 9999,
padding: '8px 12px',
backgroundColor: '#28a745',
color: '#fff',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
fontSize: '13px',
opacity: '0.85'
});
configBtn.onmouseenter = () => (configBtn.style.opacity = '1');
configBtn.onmouseleave = () => (configBtn.style.opacity = '0.85');
document.body.appendChild(configBtn);

configBtn.addEventListener('click', async () => {
const src = prompt('源语言(如 en, zh, ja ):', sourceLang);
const tgt = prompt('目标语言(如 zh, en, ko ):', targetLang);
if (src && tgt) {
sourceLang = src;
targetLang = tgt;
saveLang();
alert(`语言设置已保存:${sourceLang} → ${targetLang}`);
}
});
})();

```
猜到了哈哈
湖南的我也穿羽绒服了
@mobinf #13 声音有点小, 戴耳机开最大音量在地铁上听不清, 最大音量听歌的话能吵得耳朵疼
@mobinf #13 ok, 我今天试试
ajU0MDU0NDUyN0BnbWFpbC5jb20=
@mobinf #8 对的
感觉网页没有适配好移动端
@mobinf #55 刚还在想什么时候上线
网页版安卓版怎么样了
@mobinf #5 插个眼
参与一下
196 天前
回复了 461229187 创建的主题 推广 我上了 Github Trending
@llussy https://newsnow.busiyi.world/
256 天前
回复了 isSamle 创建的主题 程序员 有没有这样的项目啊
dify 之类的?
271 天前
回复了 SilenceLL 创建的主题 程序员 大家有推荐的滑动验证服务商吗
2024-06-18 13:36:41 +08:00
回复了 vex2018 创建的主题 程序员 火山引擎有够🌶︎🐔
@yxhzhang185 每次登都会接到电话😂
1  2  3  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   3049 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 39ms · UTC 13:10 · PVG 21:10 · LAX 05:10 · JFK 08:10
♥ Do have faith in what you're doing.