NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name 翻译 // @namespace www.akmdc.com // @version 0.1.0 // @description 阅读各文档时直接翻译!仅支持英译中! // @require https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js // @require http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js // @license MIT // @connect api.fanyi.baidu.com // @grant GM_setValue // @grant GM_getValue // @grant GM_setClipboard // @grant GM_log // @grant GM_xmlhttpRequest // @grant unsafeWindow // @grant window.close // @grant window.focus // @author akmdmc // @match https://*/* // @icon https://edu-wenku.bdimg.com/v1/pc/2020%E6%96%B0%E9%A6%96%E9%A1%B5/wenku-header-icon.ico // ==/UserScript== ( function(){ const body = document.querySelector('body') let nowTanslateBtn = null; //当前翻译按钮 let nowTranslateContent = null; //当前翻译内容 let curRregion = ""; //当前选中的文字 // 一下需要自己去百度翻译申请appid和key const baiduAppId = ""; // 百度翻译appid const baiduKey = ""; // 百度翻译key // 流程 createStartBtn() -> translateBtn() -> translateContent() -> baiduTranslate() //创建启动按钮 createStartBtn(); //获取选中的文字 body.addEventListener('mouseup', (e) => { const selection = getSelection(); curRregion = selection.toString(); }) //翻译按钮 function translateBtn(x, y) { if (nowTanslateBtn) { nowTanslateBtn.remove(); } if (!curRregion) return; body.appendChild(createTanslateBtn(x, y)); } //翻译内容 function translateContent(x, y) { if (nowTranslateContent) { nowTranslateContent.remove(); } nowTranslateContent = createTanslateContent(x, y); body.appendChild(nowTranslateContent); baiduTranslate(curRregion);//翻译 } //百度翻译 async function baiduTranslate(string) { const salt = Math.random().toString(36).substr(3); let q = string; const str1 = baiduAppId + q + salt + baiduKey; let sign = md5(str1); const url = `http://api.fanyi.baidu.com/api/trans/vip/translate?q=${q}&from=en&to=zh&appid=${baiduAppId}&salt=${salt}&sign=${sign}`; await GM_xmlhttpRequest({ method: 'GET', url: url, onload: async (r) => { try { nowTranslateContent.innerText = JSON.parse(r.responseText).trans_result[0].dst; } catch { nowTranslateContent.innerText = "翻译失败(少选点试试?)"; } //关闭按钮 nowTranslateContent.appendChild(createCloseBtn()); } }) } //创建翻译按钮 function createTanslateBtn(x, y) { const div = document.createElement('button'); div.style.position = 'fixed'; div.style.left = x + 5 + 'px'; div.style.top = y - 20 + 'px'; div.style.backgroundColor = 'rgba(255,255,255,1)'; div.style.width = '40px'; div.style.height = '20px'; div.style.textAlign = 'center'; div.style.fontSize = 6 + 'px'; div.style.border = "none"; div.style.zIndex = 999999; div.innerText = "翻译" nowTanslateBtn = div; div.addEventListener("click", async (e) => { e.stopPropagation(); await translateContent(x, y); if (nowTanslateBtn) { nowTanslateBtn.remove(); } }) return div; } //创建翻译内容 function createTanslateContent(x, y) { const div = document.createElement('div'); div.style.position = 'fixed'; div.style.left = x + 5 + 'px'; div.style.top = y + 5 + 'px'; div.style.maxWidth = '200px'; div.style.backgroundColor = 'rgba(255,255,255,1)'; div.style.padding = '20px'; div.style.textAlign = 'center'; div.style.fontSize = 12 + 'px'; div.style.border = "1px solid rgb(0,0,0,0)"; div.style.borderRadius = "5px"; div.style.boxShadow = "0 0 5px 2px rgba(0,0,0,0.2)"; div.style.userSelect = "none"; let chaX = 0; let chaY = 0; let start = false; div.addEventListener("mousedown", (e) => { e.stopPropagation(); start = true; chaX = e.clientX - div.style.left.slice(0, div.style.left.length - 2) chaY = e.clientY - div.style.top.slice(0, div.style.top.length - 2) }) window.addEventListener("mousemove", (e) => { if (!start) return; e.stopPropagation(); div.style.left = e.clientX - chaX + 'px'; div.style.top = e.clientY - chaY + 'px' }) window.addEventListener("mouseup", (e) => { e.stopPropagation(); start = false; }) return div; } //创建关闭按钮 function createCloseBtn() { const close = document.createElement('button'); close.innerText = "X"; close.style.position = 'absolute'; close.style.right = 0; close.style.top = 0; close.style.width = '20px'; close.style.padding = '2px'; close.style.backgroundColor = 'rgba(255,255,255,1)'; close.style.border = "none"; close.style.fontSize = 10 + 'px'; close.style.textAlign = 'center'; close.style.borderRadius = "5px"; close.addEventListener("mouseover", (e) => { e.stopPropagation(); close.style.backgroundColor = 'rgba(255,0,0,1)'; close.style.color = 'white'; }) close.addEventListener("mouseout", (e) => { e.stopPropagation(); close.style.backgroundColor = 'rgba(255,255,255,1)'; close.style.color = 'black'; }) close.addEventListener("click", (e) => { e.stopPropagation(); if (nowTranslateContent) { nowTranslateContent.remove(); nowTranslateContent = null; } }) return close; } //创建启动按钮 function createStartBtn() { let isStart = false; const div = document.createElement('button'); div.style.position = 'fixed'; div.style.left = -52 + 'px'; div.style.top = '30%'; div.style.backgroundColor = 'rgba(34, 24, 219,1)'; div.style.color = 'white'; div.style.width = '60px'; div.style.height = '20px'; div.style.textAlign = 'center'; div.style.fontSize = 6 + 'px'; div.style.border = "none" div.style.transition = "left 0.5s"; div.innerText = "启动" div.classList.add("startBtn"); div.addEventListener("mouseover", (e) => { e.stopPropagation(); div.style.left = 0; }) div.addEventListener("mouseout", (e) => { e.stopPropagation(); div.style.left = -52 + 'px'; }) div.addEventListener("click", (e) => { e.stopPropagation(); if (isStart) { window.removeEventListener('click', windowClick); div.innerText = "启动"; div.style.backgroundColor = 'rgba(34, 24, 219,1)'; isStart = false; return; } else { window.addEventListener('click', windowClick); div.innerText = "关闭"; div.style.backgroundColor = 'rgba(219, 24, 24,1)'; isStart = true; return; } }) body.appendChild(div); return { isStart, } } //点击事件 const windowClick = (e) => { if (nowTranslateContent) return; translateBtn(e.clientX, e.clientY) } } )();