翻译

try to take over the world!

目前為 2019-08-26 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         翻译
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  try to take over the world!
// @author       su
// @match        http://*/*
// @include      https://*/*
// @grant        GM_xmlhttpRequest
// @connect      cn.bing.com
// @connect      fy.iciba.com
// @connect      api.ai.qq.com
// @require      http://cdn.bootcss.com/blueimp-md5/1.1.0/js/md5.min.js
// ==/UserScript==
(function() {
    //金山词霸翻译接口
    const cibaUrl = "http://fy.iciba.com/ajax.php?a=fy";
    //css样式
    const style = {
            'ballStyle': 'position: fixed;top: 100px;right: 0;width: 40px;height: 40px;border-radius: 50%;border: 1px solid #ececec;text-align: center;line-height: 40px;font-size: 24px;ont-weight: 900;color: rgb(103, 192, 192);cursor: pointer;',
            'traStyle': 'z-index:101;position: fixed;top: 100px;right: 0;width: 30%;border-radius: 6px;font: 13px/normal Arial, Helvetica;box-shadow: 0 0 0 1px rgba(0, 0, 0, .05), 0 2px 3px 0 rgba(0, 0, 0, .1);transform: translate(100%, 0);transition: transform .3s linear;',
            'selectStyle': 'width: 60%;margin-top: 3px;border: 1px solid #ececec;height: 28px;border-radius: 2px;color: #666;',
            'textareaStyle': 'height: 96px;top: 40px;width: 100%;font-weight: normal;font-family: "Roboto", Sans-Serif;outline: none;-webkit-appearance: none;white-space: pre-wrap;word-wrap: break-word;z-index: 2;background: transparent;border-width: 0;',
            'dTextStyle': 'height: auto;min-height: 120px;padding: 30px 20px 12px 20px;overflow: hidden;'
        }
        //下拉框
    const select = '<option value="en" selected>英语</option><option value="zh-Hans">简体中文</option><option value="ar">阿拉伯语</option><option value="et">爱沙尼亚语</option><option value="bg">保加利亚语</option><option value="is">冰岛语</option><option value="pl">波兰语</option><option value="bs-Latn">波斯尼亚语(拉丁语)</option><option value="fa">波斯语</option><option value="da">丹麦语</option><option value="de">德语</option><option value="ru">俄语</option><option value="fr">法语</option><option value="zh-Hant">繁体中文</option><option value="fil">菲律宾语</option><option value="fj">斐济语</option><option value="fi">芬兰语</option><option value="ht">海地克里奥尔语</option><option value="ko">韩语</option><option value="nl">荷兰语</option><option value="ca">加泰罗尼亚语</option><option value="cs">捷克语</option><option value="otq">克雷塔罗奥托米语</option><option value="tlh">克林贡语</option><option value="hr">克罗地亚语</option><option value="lv">拉脱维亚语</option><option value="lt">立陶宛语</option><option value="ro">罗马尼亚语</option><option value="mg">马达加斯加语</option><option value="mt">马耳他语</option><option value="ms">马来语(拉丁语)</option><option value="bn-BD">孟加拉语</option><option value="mww">苗语</option><option value="af">南非荷兰语</option><option value="pt">葡萄牙语</option><option value="ja">日语</option><option value="sv">瑞典语</option><option value="sm">萨摩亚语</option><option value="sr-Latn">塞尔维亚语(拉丁语)</option><option value="sr-Cyrl">塞尔维亚语(西里尔文)</option><option value="no">书面挪威语</option><option value="sk">斯洛伐克语</option><option value="sl">斯洛文尼亚语</option><option value="sw">斯瓦希里语</option><option value="ty">塔希提语</option><option value="te">泰卢固语</option><option value="ta">泰米尔语</option><option value="th">泰语</option><option value="to">汤加语</option><option value="tr">土耳其语</option><option value="cy">威尔士语</option><option value="ur">乌尔都语</option><option value="uk">乌克兰语</option><option value="es">西班牙语</option><option value="he">希伯来语</option><option value="el">希腊语</option><option value="hu">匈牙利语</option><option value="it">意大利语</option><option value="hi">印地语</option><option value="id">印度尼西亚语</option><option value="yua">尤卡坦玛雅语</option><option value="vi">越南语</option><option value="yue">粤语(繁体)</option>';

    function Main_Su() {
        this.main_s = null;
        this.ball = null;
        this.tra = null;
        this.ori_select = null;
        this.tra_select = null;
        this.ori_text = null;
        this.tra_text = null;
    }
    /**
     * 设置下拉框选中
     */
    Main_Su.prototype.setSelectChecked = function(select, checkValue) {
        for (var i = 0; i < select.options.length; i++) {
            if (select.options[i].value == checkValue) {
                select.options[i].selected = true;
                break;
            }
        }
    };
    /**
     * 创建小球
     */
    Main_Su.prototype.createBall = function() {
            this.ball = document.createElement('div');
            this.ball.setAttribute('id', 'ball');
            this.ball.setAttribute('style', style.ballStyle);
            this.ball.innerHTML = '译';
            return this.ball;
        }
        /**
         * 翻译结果的语言选择下拉框
         */
    Main_Su.prototype.createOriSelect = function() {
            this.ori_select = document.createElement('select');
            this.ori_select.setAttribute('id', "ori_select");
            this.ori_select.setAttribute('style', style.selectStyle);
            this.ori_select.innerHTML = select;
            //设置默认选择
            this.setSelectChecked(this.ori_select, 'zh-Hans');
            return this.ori_select;
        }
        /**
         * 需要翻译文本的语言选择下拉框
         */
    Main_Su.prototype.createTraSelect = function() {
            this.tra_select = document.createElement('select');
            this.tra_select.setAttribute('id', "tra_select");
            this.tra_select.setAttribute('style', style.selectStyle);
            this.tra_select.innerHTML = select;
            //设置默认选择
            this.setSelectChecked(this.tra_select, 'en');
            return this.tra_select;
        }
        /**
         * 需要翻译文本的语言输入框
         */
    Main_Su.prototype.createOriText = function() {
            this.ori_text = document.createElement('textarea');
            this.ori_text.setAttribute('id', 'ori_text');
            this.ori_text.setAttribute('style', style.textareaStyle);
            this.ori_text.setAttribute('placeholder', '输入文本');
            return this.ori_text;
        }
        /**
         * 翻译结果的语言输入框
         */
    Main_Su.prototype.createTraText = function() {
            this.tra_text = document.createElement('textarea');
            this.tra_text.setAttribute('id', 'tra_text');
            this.tra_text.setAttribute('style', style.textareaStyle);
            this.tra_text.setAttribute('placeholder', '输入文本');
            return this.tra_text;
        }
        /**
         * 控制翻译面板的隐藏
         */
    Main_Su.prototype.hideTra = function() {
            tra.style.height = 0;
            tra.style.transform = 'translate(100%,0)';
            ball.style.visibility = 'visible'
        }
        /**
         * 创建列
         */
    Main_Su.prototype.createOriTd = function() {
            var oriTd = document.createElement('td');
            oriTd.setAttribute('id', 'oriTd');
            oriTd.setAttribute('style', 'border-right: 1px solid #ececec;background-color: #fff;width: 50%;');
            var div = document.createElement('div');
            var div_s = document.createElement('div');
            var div_t = document.createElement('div');
            div_s.setAttribute('style', 'margin: 10px 8px 0 16px;height: 40px;');
            div_t.setAttribute('style', style.dTextStyle);
            //创建添加下拉框跟输入框
            this.createOriSelect();
            div_s.appendChild(this.ori_select);
            this.createOriText();
            div_t.appendChild(this.ori_text);
            div.appendChild(div_s);
            div.appendChild(div_t);
            oriTd.appendChild(div);
            return oriTd;
        }
        /**
         * 创建列
         */
    Main_Su.prototype.createTraTd = function() {
            var traTd = document.createElement('td');
            traTd.setAttribute('id', 'traTd');
            traTd.setAttribute('style', 'width: 50%;background: #f9f9f9;');
            var div = document.createElement('div');
            var div_s = document.createElement('div');
            var div_t = document.createElement('div');
            div_s.setAttribute('style', 'margin: 10px 8px 0 16px;height: 40px;');
            div_t.setAttribute('style', style.dTextStyle);
            this.createTraSelect();
            div_s.appendChild(this.tra_select);
            this.createTraText();
            div_t.appendChild(this.tra_text);
            div.appendChild(div_s);
            div.appendChild(div_t);
            traTd.appendChild(div);
            return traTd;
        }
        /**
         * 创建翻译框
         */
    Main_Su.prototype.createTra = function() {
            this.tra = document.createElement('div');
            this.tra.setAttribute('id', 'tra');
            this.tra.setAttribute('style', style.traStyle)
            var table = document.createElement('table');
            table.setAttribute('style', "width: 100%");
            var tr = document.createElement('tr');
            tr.appendChild(this.createOriTd());
            tr.appendChild(this.createTraTd());
            table.appendChild(tr);
            this.tra.appendChild(table);
            return this.tra;
        }
        /**
         * 创建翻译主面板
         */
    Main_Su.prototype.createMain = function() {
            this.main_s = document.createElement('div');
            this.createBall();
            this.createTra();

            this.main_s.setAttribute('id', 'main_s');
            this.main_s.setAttribute('style', 'z-index:101');
            this.main_s.appendChild(this.ball);
            this.main_s.appendChild(this.tra);
            return this.main_s;
        }
        /**
         * ajax 跨域访问公共方法
         * @param {*} url
         * @param {*} method
         * @param {*} data
         */
    Main_Su.prototype.ajaxFun = function(url, method, data) {
            if (!!!method)
                method = 'GET';
            GM_xmlhttpRequest({
                method: method,
                url: url,
                data: data,
                onload: function(res) {
                    console.log(res.responseText);
                    tra_text.value = JSON.parse(res.responseText).content.out;
                    tra_text.style.color = 'black'
                },
                onloadstart: function(res) {
                    tra_text.value = "正在翻译..."
                    tra_text.style.color = 'grey'
                },
                onerror: function(res) {
                    console.log("连接失败:" + res);
                }
            });
        }
        /**
         * 判断语种:只能判断中英韩日语
         * @param {} text 
         */
    Main_Su.prototype.judgeLanguage = function(text) {
            if (new RegExp('[\\u4e00-\\u9fa5]').test(text)) {
                return 'zh-Hans'
            } else if (new RegExp('[\\x3130-\\x318F]').test(text)) {
                return 'ko'
            } else if (new RegExp('[\\u0800-\\u4e00]').test(text)) {
                return 'ja'
            } else if (new RegExp('[A-Za-z]').test(text)) {
                return 'en'
            } else {
                return 'default'
            }
        }
        /**
         * 翻译
         *  @param {是否关闭自动检测语种} isAuto 
         */
    Main_Su.prototype.translate = function(closeAuto) {
        var from = this.ori_select.value;
        //判断翻译文本的语种
        if (!closeAuto) {
            from = this.judgeLanguage(this.ori_text.value) == 'default' ? from : this.judgeLanguage(this.ori_text.value);
            this.setSelectChecked(this.ori_select, from);
        }
        var to = this.tra_select.value;
        this.ajaxFun(Translations.cibaFun(from, to, this.ori_text.value));
    }

    /** 
     * 添加绑定事件
     */
    Main_Su.prototype.rigisterEvent = function() {
        this.ball.addEventListener('click', function() {
            this.tra.style.transform = 'translate(0,0)';
            this.tra.style.height = 'auto';
            this.ball.style.visibility = 'hidden'
        }.bind(this))
        this.ori_text.addEventListener('input', function() {
            this.translate(false);
        }.bind(this));
        this.ori_select.addEventListener('change',
            function() {
                this.translate(true);
            }.bind(this));
        this.tra_select.addEventListener('change', this.translate.bind(this));
        var timeout;
        this.main_s.addEventListener('mouseleave', function() {
            timeout = setTimeout(this.hideTra, 1000);
        }.bind(this))
        this.main_s.addEventListener('mouseenter', function() {
            clearTimeout(timeout);
        })
    }
    const Translations = {
            /**
             * 金山词霸翻译
             * @param {需要翻译文本的语言} f
             * @param {翻译结果的语言} t
             * @param {翻译原文} w
             */
            cibaFun: function(f, t, w) {
                var url = cibaUrl + "&f=" + f + "&t=" + t + "&w=" + w;
                return url;
            }
        }
        //判断当前窗口是否为最顶层窗口,是则创建
    if (window.top == window.self) {
        var main = new Main_Su();
        main.createMain();
        main.rigisterEvent();
        document.body.appendChild(main.main_s);
    }
})()