写了个划词翻译TamperMonkey脚本
发现自己用的翻译插件莫名其妙相当吃CPU, 又找不到好用的, 正好前段时间申请了一个百度翻译的api, 就决定自己搓一个.
大致思路是, 监听点击事件, 提取选中的文字, 如果有效就发送到百度请求翻译, 将响应解析后扔进创建的泡泡中.
期间遇到了Allow-Origin的问题, 找到的解决方案是用cors-anywhere做一次代理, 问题是减慢了速度(但是也能用)
完成品:
// ==UserScript==
// @name Inline Translater
// @namespace http://tampermonkey.net/
// @version 1.5
// @description 在网页上弹出气泡实现划词翻译(基于百度翻译)
// @author Leohearts
// @match http://*/*
// @match https://*/*
// @grant none
// @require http://cdn.bootcss.com/blueimp-md5/1.1.0/js/md5.min.js
// ==/UserScript==
var appid = "";
var key = "thisistheapikey";
var globalpageX;
var globalpageY;
var translatecancel = false;
// This function is from https://stackoverflow.com/questions/7790725/javascript-track-mouse-position
function handleMouseMove(event) {
var eventDoc, doc, body;
event = event || window.event; // IE-ism
// If pageX/Y aren't available and clientX/Y are,
// calculate pageX/Y - logic taken from jQuery.
// (This is to support old IE)
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0 );
}
globalpageX = event.pageX;
globalpageY = event.pageY;
}
document.onmousemove = handleMouseMove;
function closetranslater(){
translatecancel = true;
try{
bdtranslateimg.style.visibility='hidden'
document.getElementById("bdtranslateimg").innerHTML = ""
document.getElementById("bdtranslateimg").outerHTML = ""
}
catch(error) {}
}
function displaytext(text){
if (translatecancel){
return 1;
}
//console.log(text)
var newdiv = document.createElement("div");
newdiv.id="bdtranslateimg";
newdiv.style="position: absolute; left: 311; top: 815;visibility :hidden;max-width:40%;z-index:9999999999;";
newdiv.align="right";
newdiv.onmouseover=function(){bdtranslateimg.style.opacity=1};
newdiv.onmouseout=function(){bdtranslateimg.style.opacity=.6};
var newa = document.createElement("a");
newa.style="CURSOR:hand;font-size:12px;color:black;border: 1px solid #c0c0c0;text-decoration: none;";
newa.href="javascript:";
newa.onclick=function(event){
event.stopPropagation();
bdtranslateimg.style.visibility='hidden'
document.getElementById("bdtranslateimg").innerHTML = "";
document.getElementById("bdtranslateimg").outerHTML = "";
translatecancel = true;
};
newa.innerText="X";
var newdiv2 = document.createElement("div");
newdiv2.style="border: 1px solid #c0c0c0;margin: 0 auto;padding: 5px;background: #f0f0f0;border-radius: 10px;font-size:12px;text-align:left;";
newdiv2.innerText=text;
newdiv2.onclick = function(event){event.stopPropagation();};
newdiv.append(newa);
newdiv.append(newdiv2);
document.querySelector("body").append(newdiv);
var xPos = globalpageX - 30;
var yPos = globalpageY - 0;
bdtranslateimg.style.top = yPos+"px";
bdtranslateimg.style.left = xPos+"px";
bdtranslateimg.style.visibility = "visible";
}
function bdtranslate(txt){
var salt = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
var apisign = md5(''+appid+txt+salt+key);
var url = "https://api.fanyi.baidu.com/api/trans/vip/translate?q="+encodeURI(txt)+"&from=auto&to=zh&appid="+appid+"&salt="+salt+"&sign="+apisign;
fetch("https://cors-anywhere.herokuapp.com/" + url, {
"credentials": "omit",
"method": "GET",
"headers": {
"x-requested-with": "XMLHttpRequest"
},
"mode": "cors"
}).then(function(response){
return response.json();
}).then(function(resp){
try{
if (resp.error_code){
closetranslater();
translatecancel = false;
displaytext("error");
return 1;
}
}
catch(error){}
var st = "";
for (var i = 0;i<resp.trans_result.length;i++){
st += resp.trans_result[i].dst;
}
closetranslater();
translatecancel = false;
displaytext(st);
});
}
document.onclick = function(){
closetranslater();
var selecttext=window.getSelection().toString();
if(selecttext!=null && selecttext.trim()!=""){
translatecancel = false;
displaytext("Translating..");
bdtranslate(selecttext.trim());
//console.log(selecttext.trim());
}
}
发现自己用的翻译插件莫名其妙相当吃CPU, 又找不到好用的, 正好前段时间申请了一个百度翻译的api, 就决定自己搓一个.
大致思路是, 监听点击事件, 提取选中的文字, 如果有效就发送到百度请求翻译, 将响应解析后扔进创建的泡泡中.
期间遇到了Allow-Origin的问题, 找到的解决方案是用cors-anywhere做一次代理, 问题是减慢了速度(但是也能用)
完成品:
// ==UserScript==
// @name Inline Translater
// @namespace http://tampermonkey.net/
// @version 1.5
// @description 在网页上弹出气泡实现划词翻译(基于百度翻译)
// @author Leohearts
// @match http://*/*
// @match https://*/*
// @grant none
// @require http://cdn.bootcss.com/blueimp-md5/1.1.0/js/md5.min.js
// ==/UserScript==
var appid = "";
var key = "thisistheapikey";
var globalpageX;
var globalpageY;
var translatecancel = false;
// This function is from https://stackoverflow.com/questions/7790725/javascript-track-mouse-position
function handleMouseMove(event) {
var eventDoc, doc, body;
event = event || window.event; // IE-ism
// If pageX/Y aren't available and clientX/Y are,
// calculate pageX/Y - logic taken from jQuery.
// (This is to support old IE)
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0 );
}
globalpageX = event.pageX;
globalpageY = event.pageY;
}
document.onmousemove = handleMouseMove;
function closetranslater(){
translatecancel = true;
try{
bdtranslateimg.style.visibility='hidden'
document.getElementById("bdtranslateimg").innerHTML = ""
document.getElementById("bdtranslateimg").outerHTML = ""
}
catch(error) {}
}
function displaytext(text){
if (translatecancel){
return 1;
}
//console.log(text)
var newdiv = document.createElement("div");
newdiv.id="bdtranslateimg";
newdiv.style="position: absolute; left: 311; top: 815;visibility :hidden;max-width:40%;z-index:9999999999;";
newdiv.align="right";
newdiv.onmouseover=function(){bdtranslateimg.style.opacity=1};
newdiv.onmouseout=function(){bdtranslateimg.style.opacity=.6};
var newa = document.createElement("a");
newa.style="CURSOR:hand;font-size:12px;color:black;border: 1px solid #c0c0c0;text-decoration: none;";
newa.href="javascript:";
newa.onclick=function(event){
event.stopPropagation();
bdtranslateimg.style.visibility='hidden'
document.getElementById("bdtranslateimg").innerHTML = "";
document.getElementById("bdtranslateimg").outerHTML = "";
translatecancel = true;
};
newa.innerText="X";
var newdiv2 = document.createElement("div");
newdiv2.style="border: 1px solid #c0c0c0;margin: 0 auto;padding: 5px;background: #f0f0f0;border-radius: 10px;font-size:12px;text-align:left;";
newdiv2.innerText=text;
newdiv2.onclick = function(event){event.stopPropagation();};
newdiv.append(newa);
newdiv.append(newdiv2);
document.querySelector("body").append(newdiv);
var xPos = globalpageX - 30;
var yPos = globalpageY - 0;
bdtranslateimg.style.top = yPos+"px";
bdtranslateimg.style.left = xPos+"px";
bdtranslateimg.style.visibility = "visible";
}
function bdtranslate(txt){
var salt = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
var apisign = md5(''+appid+txt+salt+key);
var url = "https://api.fanyi.baidu.com/api/trans/vip/translate?q="+encodeURI(txt)+"&from=auto&to=zh&appid="+appid+"&salt="+salt+"&sign="+apisign;
fetch("https://cors-anywhere.herokuapp.com/" + url, {
"credentials": "omit",
"method": "GET",
"headers": {
"x-requested-with": "XMLHttpRequest"
},
"mode": "cors"
}).then(function(response){
return response.json();
}).then(function(resp){
try{
if (resp.error_code){
closetranslater();
translatecancel = false;
displaytext("error");
return 1;
}
}
catch(error){}
var st = "";
for (var i = 0;i<resp.trans_result.length;i++){
st += resp.trans_result[i].dst;
}
closetranslater();
translatecancel = false;
displaytext(st);
});
}
document.onclick = function(){
closetranslater();
var selecttext=window.getSelection().toString();
if(selecttext!=null && selecttext.trim()!=""){
translatecancel = false;
displaytext("Translating..");
bdtranslate(selecttext.trim());
//console.log(selecttext.trim());
}
}