多语言翻译

将网页按指定语言翻译

// ==UserScript==
// @name         多语言翻译
// @namespace    https://orthogonalandparallel.github.io/
// @version      0.2
// @description  将网页按指定语言翻译
// @author       JinChen
// @match        *://*/*
// @grant        translate
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 创建样式
    const style = document.createElement('style');
    style.textContent = `
        /* 毛玻璃拖动框 */
        .custom-glass {
            position: fixed;
            top: -150px;
            left: 100px;
            transform: translate(-50%, -50%);
            height: 300px;
            width: 200px;
            backdrop-filter: blur(10px);
            -webkit-backdrop-filter: blur(10px);
            box-shadow:
                inset -0.75px -0.5px rgba(255, 255, 255, 0.1),
                inset +0.75px +0.5px rgba(255, 255, 255, 0.025),
                3px 2px 10px rgba(0, 0, 0, 0.25),
                inset 0px 0px 10px 5px rgba(255, 255, 255, 0.025),
                inset 0px 0px 40px 5px rgba(255, 255, 255, 0.025);
            position: relative;
            border-radius: 5px;
            overflow: hidden;
            z-index: 9999;
        }

        .custom-drag-me {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 44px;
            background-color: rgba(12, 13, 14, 0.75);
            color: rgba(255, 255, 255, 1);
            cursor: move;
        }

        /* 列表 */
        .custom-glass ul {
            list-style: none;
            padding: 15px;
            margin: 0;
            max-height: calc(100% - 30px);
            overflow-y: auto;
        }

        .custom-glass ul::-webkit-scrollbar {
            width: 6px;
        }

        .custom-glass ul::-webkit-scrollbar-thumb {
            border-radius: 3px;
        }

        .custom-glass ul li {
            padding: 12px 15px;
            margin: 8px 0;
            border-radius: 6px;
            transition: all 0.3s ease;
        }

        .custom-glass ul li:hover {
            background-color: rgba(12, 13, 14, 0.75);
            color: rgba(255, 255, 255, 1);
            transform: translateX(5px);
        }

        .custom-glass ul li a {
            color: rgba(0, 0, 0, 0.8);
            text-decoration: none;
            display: block;
            font-size: 14px;
            font-weight: 500;
        }

        .custom-glass ul li:hover a {
            color: rgba(255, 255, 255, 1);
        }

    `;
    document.head.appendChild(style);

    // ------- 页面元素 begin -------

    // 创建毛玻璃窗口
    const glass = document.createElement('div');
    glass.className = 'custom-glass ignore';

    const dragMe = document.createElement('div');
    dragMe.className = 'custom-drag-me';
    dragMe.textContent = '多语言翻译';

    // 创建列表
    const ul = document.createElement('ul');
    const items = [
        { text: 'English', lang: 'english' },
        { text: '简体中文', lang: 'chinese_simplified' },
        { text: '繁體中文', lang: 'chinese_traditional' }
    ];

    items.forEach(item => {
        const li = document.createElement('li');
        const a = document.createElement('a');
        a.href = `javascript:translate.changeLanguage('${item.lang}');`;
        a.textContent = item.text;
        li.appendChild(a);
        ul.appendChild(li);
    });

    glass.appendChild(dragMe);
    glass.appendChild(ul);

    const topBody = window.top.document.body;
    topBody.appendChild(glass);

    // ------- 页面元素 end -------

    // ------- 拖拽功能 begin -------
    let isDragging = false;
    let currentX;
    let currentY;
    let initialX;
    let initialY;
    let xOffset = 0;
    let yOffset = 0;

    dragMe.addEventListener('mousedown', dragStart);
    document.addEventListener('mousemove', drag);
    document.addEventListener('mouseup', dragEnd);

    function dragStart(e) {
        initialX = e.clientX - xOffset;
        initialY = e.clientY - yOffset;

        if (e.target === dragMe) {
            isDragging = true;
        }
    }

    function drag(e) {
        if (isDragging) {
            e.preventDefault();
            currentX = e.clientX - initialX;
            currentY = e.clientY - initialY;

            xOffset = currentX;
            yOffset = currentY;

            setTranslate(currentX, currentY, glass);
        }
    }

    function dragEnd() {
        isDragging = false;
    }

    function setTranslate(xPos, yPos, el) {
        el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
    }
    // ------- 拖拽功能 end -------

    // ------- 翻译功能 begin -------

    // 注入 translate.js 脚本
    const translateScript = document.createElement('script');
    translateScript.src = 'https://cdn.staticfile.net/translate.js/3.12.0/translate.js';
    document.head.appendChild(translateScript);

    // 初始化 translate.js 脚本加载完成后
    translateScript.onload = function() {
        const initScript = document.createElement('script');
        initScript.textContent = `
            translate.selectLanguageTag.show = false; //不出现的select的选择语言
            translate.service.use('client.edge'); //设置机器翻译服务通道
            translate.execute();
        `;
        document.body.appendChild(initScript);
    };

    // ------- 翻译功能 end -------

})();