实战:开发一个网页划词翻译插件(调用第三方API)——​Chrome插件开发从入门到精通系列教程​04

#『AI先锋杯·14天征文挑战第5期』#

监听鼠标事件与获取选中文本

在内容脚本中监听鼠标释放事件,获取用户选中的文本。使用window.getSelection()方法获取选中内容,并过滤空值或过短文本。

document.addEventListener('mouseup', (e) => {
  const selectedText = window.getSelection().toString().trim();
  if (selectedText.length > 0 && selectedText.length < 500) {
    chrome.runtime.sendMessage({ type: 'TRANSLATE', text: selectedText });
  }
});

后台脚本通信与API调用

后台脚本接收内容脚本消息,调用翻译API。需要提前申请有道或百度翻译的API密钥(免费版足够测试)。

// 示例:有道翻译API调用
async function fetchYoudao(text) {
  const appKey = 'YOUR_APP_KEY';
  const key = 'YOUR_SECRET_KEY';
  const salt = Date.now();
  const sign = md5(appKey + text + salt + key);
  
  const res = await fetch(`https://openapi.youdao.com/api?q=${encodeURIComponent(text)}&appKey=${appKey}&salt=${salt}&sign=${sign}`);
  return res.json();
}

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.type === 'TRANSLATE') {
    fetchYoudao(request.text).then(data => {
      sendResponse({ result: data.translation[0] });
    });
    return true; // 保持消息端口开放
  }
});

翻译结果展示样式设计

在内容脚本中动态创建悬浮框,采用固定定位避免干扰页面布局。CSS建议使用position: absolute配合z-index: 9999确保悬浮在最上层。

.translation-box {
  position: absolute;
  background: white;
  border: 1px solid #ddd;
  padding: 8px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  max-width: 300px;
  z-index: 9999;
}

悬浮框位置计算与渲染

根据鼠标事件坐标计算悬浮框位置,避免超出视窗边界。动态插入DOM元素并注入翻译结果。

function showTranslation(text, x, y) {
  const box = document.createElement('div');
  box.className = 'translation-box';
  box.textContent = text;
  
  // 视窗边界检测
  const adjustedX = Math.min(x, window.innerWidth - 310);
  const adjustedY = Math.min(y, window.innerHeight - 100);
  
  box.style.left = `${adjustedX}px`;
  box.style.top = `${adjustedY}px`;
  document.body.appendChild(box);
  
  // 点击外部关闭
  setTimeout(() => {
    document.addEventListener('click', (e) => {
      if (!box.contains(e.target)) box.remove();
    }, { once: true });
  }, 100);
}

错误处理与性能优化

添加API调用失败的回退方案,如切换备用翻译服务或显示错误提示。使用防抖技术避免高频触发。

// 防抖处理(300ms间隔)
let lastCall = 0;
document.addEventListener('mouseup', (e) => {
  const now = Date.now();
  if (now - lastCall < 300) return;
  lastCall = now;
  // ...原有逻辑
});

// 错误处理示例
chrome.runtime.sendMessage({ type: 'TRANSLATE', text }, (response) => {
  if (chrome.runtime.lastError || !response) {
    showTranslation('翻译服务暂不可用', e.clientX, e.clientY);
  } else {
    showTranslation(response.result, e.clientX, e.clientY);
  }
});

扩展打包与发布

manifest.json中配置必要权限,包括API域名访问权限和内容脚本注入规则。

{
  "permissions": ["https://openapi.youdao.com/"],
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"]
  }]
}

完整项目需包含图标、多语言支持等细节,可通过Chrome开发者模式加载未打包的扩展进行测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anson Jiang

感谢客官老爷打赏的咖啡钱:-)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值