花了点时间做了个 Chrome 扩展(Github),用的是有道翻译 api。
Manifest
manifest.json
1 | { |
icons
在 chrome://extensions/ 的图标
browser_action
在扩展栏的图标和点击后弹出的页面,没有设置这个值则不会出现在扩展栏中。
permissions
有权限访问哪些地址。
content_scripts
在特定页面下可以进行操作,操作时使用的 js 文件和 css 文件,可以使用正则表达式。
all_frames 表示是否在所有框架上生效,默认为 false,只在顶级框架生效。
Popup
js/popup.js
1 | function translate(query, callback, errCallback) { |
只解释重要部分。
异步请求翻译结果。需要对输入做 encodeURIComponent 处理,这里我指定返回的是 json,成功则触发 onload 并对 response 进行处理,失败则触发 onerror。
translate(query, callback, errCarllback)
1 | function translate(query, callback, errCallback) { |
绑定 keyup 动作,并在 keyup 触发后 700 毫秒之内再无另一个 keyup 动作后开始执行相关函数,不过得判断下是否按下的键为 Enter,是则直接结束,否则就和上面绑定 Submit 重复了,没必要。
实现如下:
1 | queryInput.addEventListener('keyup', function (ev) { |
Popover
这是双击翻译或 Ctrl 翻译选择区域功能。
popover.js
1 | function translate(query, callback, errCallback) { |
这里的异步请求得注意当前页面是否 https 协议,如果是那么异步请求地址也得是 https 协议,如下:
1 | if (window.location.protocol.indexOf('https') < 0) { |
有两种方法可以获取当前坐标,不过一个是相对页面的坐标,一个是相对浏览器的坐标,由于按 Ctrl 时不能通过 Event 获取坐标,所以统一通过 Selection 获取。
通过 Event 获取:
1 | function getPosition(event) { |
通过 Selection Range 获取:
1 | function getPositionByRange() { |
将一个节点删除,可以通过 parentNode 获取其父节点再通过其父节点使用 removeChild(childNode) 删除该节点:
1 | if (document.getElementById('cardWrapper')) { |
需要往 body 添加节点时用 document.body.innerHTML 会使已经选择的区域失去,解决 trick:
1 | var dummy = document.createElement('DIV'); |
阻止冒泡:
1 | var cardWrapper = document.getElementById('cardWrapper'); |
取得选择的区域文字,并判断是否为空,是则结束函数:
1 | document.addEventListener('dblclick', function (ev) { |
判断按下的是否 Ctrl:
1 | if (ev.ctrlKey) {} |