您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
划词翻译
当前为
- 'use strict';
- var css = "._panel_nvbn4_1 {\n position: fixed;\n max-width: 300px;\n z-index: 10000;\n}\n ._panel_nvbn4_1 * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n._body_nvbn4_11 {\n position: relative;\n padding: 8px;\n border-radius: 4px;\n border: 1px solid #eaeaea;\n line-height: 24px;\n color: #555;\n background-color: #fff;\n font-family: monospace, consolas;\n font-size: 14px;\n text-align: left;\n word-break: break-all;\n}\n._header_nvbn4_24 {\n padding: 0 0 8px;\n border-bottom: 1px dashed #aaa;\n color: #333;\n}\n._header_nvbn4_24 > a {\n margin-left: 8px;\n color: #7cbef0;\n cursor: pointer;\n font-size: 13px;\n }\n._detail_nvbn4_35 {\n margin: 8px 0 0;\n line-height: 22px;\n list-style: none;\n font-size: 13px;\n}\n._detail_nvbn4_35 > li {\n font-size: 13px;\n line-height: 26px;\n }\n";
- var classMap = {
- "panel": "_panel_nvbn4_1",
- "body": "_body_nvbn4_11",
- "header": "_header_nvbn4_24",
- "detail": "_detail_nvbn4_35"
- };
- // ==UserScript==
- // @name translator
- // @namespace https://lufei.so
- // @supportURL https://github.com/intellilab/translator.user.js
- // @description 划词翻译
- // @version 1.5.10
- // @run-at document-start
- // @grant GM_addStyle
- // @grant GM_xmlhttpRequest
- // @include *
- // ==/UserScript==
- GM_addStyle(css);
- var translator = initialize();
- function createElement(tagName, props, attrs) {
- var el = document.createElement(tagName);
- if (props) {
- Object.keys(props).forEach(function (key) {
- el[key] = props[key];
- });
- }
- if (attrs) {
- Object.keys(attrs).forEach(function (key) {
- el.setAttribute(key, attrs[key]);
- });
- }
- return el;
- }
- function render(data) {
- var body = translator.body,
- audio = translator.audio;
- body.innerHTML = '';
- var basic = data.basic,
- query = data.query,
- translation = data.translation;
- if (basic) {
- var explains = basic.explains,
- us = basic['us-phonetic'],
- uk = basic['uk-phonetic'];
- var noPhonetic = '♥';
- var header = createElement('div', {
- className: classMap.header
- });
- header.appendChild(createElement('span', {
- textContent: query
- }));
- header.appendChild(createElement('a', {
- innerHTML: `uk: [${uk || noPhonetic}]`
- }, {
- 'data-type': 1
- }));
- header.appendChild(createElement('a', {
- innerHTML: `us: [${us || noPhonetic}]`
- }, {
- 'data-type': 2
- }));
- header.appendChild(createElement('a', {
- textContent: '详情'
- }, {
- target: '_blank',
- href: `http://dict.youdao.com/search?q=${encodeURIComponent(query)}`
- }));
- body.appendChild(header);
- header.addEventListener('click', function (e) {
- var type = e.target.dataset.type;
- if (type) {
- audio.src = `https://dict.youdao.com/dictvoice?audio=${encodeURIComponent(query)}&type=${type}`;
- }
- });
- if (explains) {
- var ul = createElement('ul', {
- className: classMap.detail
- });
- for (var i = 0; i < explains.length; i += 1) {
- var li = createElement('li', {
- innerHTML: explains[i]
- });
- ul.appendChild(li);
- }
- body.appendChild(ul);
- }
- } else if (translation) {
- var div = createElement('div', {
- innerHTML: translation[0]
- });
- body.appendChild(div);
- }
- }
- function translate(e) {
- var sel = window.getSelection();
- var text = sel.toString();
- if (/^\s*$/.test(text)) return;
- var _document = document,
- activeElement = _document.activeElement;
- if (['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) < 0 && !activeElement.contains(sel.getRangeAt(0).startContainer)) return;
- var query = {
- type: 'data',
- doctype: 'json',
- version: '1.1',
- relatedUrl: 'http://fanyi.youdao.com/',
- keyfrom: 'fanyiweb',
- key: null,
- translate: 'on',
- q: text,
- ts: Date.now()
- };
- var qs = Object.keys(query).map(function (key) {
- return `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`;
- }).join('&');
- GM_xmlhttpRequest({
- method: 'GET',
- url: `https://fanyi.youdao.com/openapi.do?${qs}`,
- onload(res) {
- var data = JSON.parse(res.responseText);
- if (!data.errorCode) {
- render(data);
- var panel = translator.panel;
- var _window = window,
- innerWidth = _window.innerWidth,
- innerHeight = _window.innerHeight;
- if (e.clientY > innerHeight * 0.5) {
- panel.style.top = 'auto';
- panel.style.bottom = `${innerHeight - e.clientY + 10}px`;
- } else {
- panel.style.top = `${e.clientY + 10}px`;
- panel.style.bottom = 'auto';
- }
- if (e.clientX > innerWidth * 0.5) {
- panel.style.left = 'auto';
- panel.style.right = `${innerWidth - e.clientX}px`;
- } else {
- panel.style.left = `${e.clientX}px`;
- panel.style.right = 'auto';
- }
- document.body.appendChild(panel);
- }
- }
- });
- }
- function debounce(func, delay) {
- var timer;
- function exec() {
- timer = null;
- func.apply(void 0, arguments);
- }
- return function () {
- if (timer) clearTimeout(timer);
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
- timer = setTimeout.apply(void 0, [exec, delay].concat(args));
- };
- }
- function initialize() {
- var audio = createElement('audio', {
- autoplay: true
- });
- var panel = createElement('div', {
- className: classMap.panel
- });
- var panelBody = createElement('div', {
- className: classMap.body
- });
- panel.appendChild(panelBody);
- var debouncedTranslate = debounce(translate);
- var isSelecting;
- document.addEventListener('mousedown', function (e) {
- isSelecting = false;
- if (panel.contains(e.target)) return;
- if (panel.parentNode) panel.parentNode.removeChild(panel);
- panelBody.innerHTML = '';
- }, true);
- document.addEventListener('mousemove', function () {
- isSelecting = true;
- }, true);
- document.addEventListener('mouseup', function (e) {
- if (panel.contains(e.target) || !isSelecting) return;
- debouncedTranslate(e);
- }, true);
- document.addEventListener('dblclick', function (e) {
- if (panel.contains(e.target)) return;
- debouncedTranslate(e);
- }, true);
- return {
- audio,
- panel,
- body: panelBody
- };
- }