Greasy Fork

Greasy Fork is available in English.

划词翻译

选中文字按住左键一会儿后放开,自动翻译。

当前为 2017-03-27 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        划词翻译
// @namespace   http://www.icycat.com
// @description 选中文字按住左键一会儿后放开,自动翻译。
// @author      冻猫
// @include     *
// @version     1.0
// @grant 		GM_xmlhttpRequest
// @grant 		GM_addStyle
// @run-at      document-end
// ==/UserScript==

(function() {

	GM_addStyle([
		'#catTipBox {text-align: left;position: absolute;z-index: 2147483647;top: 22px;left: -35px;background: #fff;border: 1px solid #dcdcdc;border: 1px solid rgba(0,0,0,.2);-webkit-transition: opacity .218s;transition: opacity .218s;-webkit-box-shadow: 0 2px 4px rgba(0,0,0,.2);box-shadow: 0 2px 4px rgba(0,0,0,.2);padding: 5px 0;display: none;font-size: 12px;line-height: 20px;}',
		'#catTipBox p{margin:0;padding: 0;list-style: none;color: #333;}',
		'#catContentBox {margin:0 8px;color:#333;}',
		'#catContentBox h2{font-size:14px;margin: 3px 0 3px;font-weight: bold;color:#333;}',
		'#catContentBox span{margin-left: 5px;color:#333;font-weight: normal;font-size:12px;}',
		'#catPlaySound {cursor:pointer;display: inline-block;vertical-align: middle;width: 14px;height: 11px;overflow: hidden;background: url("data:image/gif;base64,R0lGODlhDgAZAIAAABy3/f///yH5BAAAAAAALAAAAAAOABkAAAI1jA+nC7ncXmg0RlTvndnt7jlcxkmjqWzotLbui4qxqBpUmoDl2Nk5GOKRSsCfDyer7ZYMSQEAOw==") no-repeat;text-decoration: none;}',
		'#catPlaySound.catPlaySoundClick {background-position:0 -14px;}',
		'.catTipArrow {width: 0;height: 0;font-size: 0;line-height: 0;display: block;position: absolute;top: -16px;left: 10px;}',
		'.catTipArrow em, .catTipArrow ins {width: 0;height: 0;font-size: 0;line-height: 0;display: block;position: absolute;border: 8px solid transparent;border-style: dashed dashed solid;}',
		'.catTipArrow em {border-bottom-color: #d8d8d8;font-style: normal;color: #c00;}',
		'.catTipArrow ins {border-bottom-color: #fff;top: 2px;text-decoration: underline;}'
	].join('\n'));

	function init() {
		var timer, holdTime, isBox, word;
		document.addEventListener('mousedown', mouseStart, false);
		document.addEventListener('mouseup', mouseEnd, false);
		function mouseStart(e) {
			if (!isBox) {
				createTipBox();
				isBox = true;
			}
			if (e.target.className != 'catTranslate') {
				document.getElementById('catTipBox').style.display = '';
			}
			if (e.target.id == 'catPlaySound') {
				document.getElementById('catPlaySound').classList.add('catPlaySoundClick');
				playSound(word);
			}
			document.addEventListener('mousemove', moveCheck, false);
		}

		function moveCheck() {
			clearTimeout(timer);
			timer = setTimeout(function() {
				holdTime = true;
			}, 500);
		}

		function mouseEnd() {
			document.removeEventListener('mousemove', moveCheck, false);
			if (document.getElementById('catPlaySound')) {
				document.getElementById('catPlaySound').classList.remove('catPlaySoundClick');
			}
			clearTimeout(timer);
			if (holdTime && window.getSelection().toString()) {
				holdTime = false;
				console.log('开始翻译');
				word = window.getSelection().toString();
				getTranslate(word, new Date().getTime());
			}
		}
	}

	function createTipBox() {
		var catTipBox = document.createElement('div');
		catTipBox.id = 'catTipBox';
		catTipBox.className = 'catTranslate';
		var catContentBox = document.createElement('div');
		catContentBox.id = 'catContentBox';
		catContentBox.className = 'catTranslate';
		var catTipArrow = document.createElement('div');
		catTipArrow.className = 'catTipArrow';
		catTipArrow.appendChild(document.createElement('em'));
		catTipArrow.appendChild(document.createElement('ins'));
		catTipBox.appendChild(catContentBox);
		catTipBox.appendChild(catTipArrow);
		document.body.appendChild(catTipBox);
	}

	function parseRes(jsonRes) {
		var content = '';
		var obj = JSON.parse(jsonRes);
		if (obj.basic) {
			content = '<h2 class="catTranslate">' + obj.query;
			if (obj.basic.phonetic) {
				content = content + '<span class="catTranslate">[' + obj.basic.phonetic + ']</span>';
				if (/^[a-zA-Z]*$/.test(obj.query)) {
					content = content + '<span id="catPlaySound" class="catTranslate"></span>';
				}
			}
			content = content + '</h2>';
			for (var i = 0; i < obj.basic.explains.length; i++) {
				if (i > 0) {
					content = content + '<br />';
				}
				content = content + obj.basic.explains[i];
			}
		} else {
			content = obj.translation[0];
		}
		var catContentBox = document.getElementById('catContentBox');
		catContentBox.innerHTML = content;
		showTipBox();
	}

	function showTipBox() {
		var catTipBox = document.getElementById('catTipBox');
		var selectedRect = window.getSelection().getRangeAt(0).getBoundingClientRect();
		var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
		if (/Firefox/i.test(navigator.userAgent)) {
			catTipBox.style.top = scrollTop + selectedRect.y + selectedRect.height + 8 + 'px';
			catTipBox.style.left = selectedRect.x + selectedRect.width / 2 - 18 + 'px';
		} else {
			catTipBox.style.top = scrollTop + selectedRect.top + selectedRect.height + 8 + 'px';
			catTipBox.style.left = selectedRect.left + selectedRect.width / 2 - 18 + 'px';
		}
		catTipBox.style.display = 'block';
	}

	function playSound(word) {
		var audio = document.createElement('audio');
		var source = document.createElement('source');
		source.type = "audio/mpeg";
		source.src = 'https://dict.youdao.com/dictvoice?type=2&audio=' + word;
		source.autoplay = "autoplay";
		source.controls = "controls";
		audio.appendChild(source);
		audio.play();
	}

	function getTranslate(word, time) {
		GM_xmlhttpRequest({
			method: "GET",
			url: 'http://fanyi.youdao.com/openapi.do?type=data&doctype=json&version=1.1&relatedUrl=http%3A%2F%2Ffanyi.youdao.com%2F&keyfrom=fanyiweb&key=null&translate=on&q=' + word + '&ts=' + time,
			headers: {
				"Accept": "application/json"
			},
			onload: function(response) {
				parseRes(response.responseText);
			},
		});
	}

	init();

})();