划词翻译(谷歌有道)

支持在移动端设备上单击自动翻译功能,点击文本后自动显示翻译结果、音标、例句、释义并朗读文本,点击页面隐藏翻译框

// ==UserScript==
// @name         划词翻译(谷歌有道)
// @namespace    http://tampermonkey.net/
// @version      6.4
// @description  支持在移动端设备上单击自动翻译功能,点击文本后自动显示翻译结果、音标、例句、释义并朗读文本,点击页面隐藏翻译框
// @author       YourName
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // 创建翻译结果的显示框
    const translationBox = document.createElement('div');
    translationBox.style.position = 'absolute';
    translationBox.style.backgroundColor = '#e6ffe6';
    translationBox.style.border = '1px solid #ccc';
    translationBox.style.padding = '10px';
    translationBox.style.zIndex = '1000';
    translationBox.style.display = 'none';
    translationBox.style.boxSizing = 'border-box';
    translationBox.style.fontSize = '14px';
    translationBox.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)';
    translationBox.style.borderRadius = '8px';
    translationBox.style.width = '100%';
    translationBox.style.left = '0';
    document.body.appendChild(translationBox);

    document.addEventListener('click', (event) => {
        if (event.target.classList.contains('translation-close')) {
            translationBox.style.display = 'none';
            return;
        }
        const selectedText = getWordUnderCursor(event);
        if (selectedText) {
            fetchTranslation(selectedText, event);
            playTTSWithYoudao(selectedText); // 调用有道 TTS 播放功能
        } else {
            translationBox.style.display = 'none';
        }
    });

    function getWordUnderCursor(event) {
        const range = document.caretRangeFromPoint(event.clientX, event.clientY);
        if (!range || !range.startContainer || range.startContainer.nodeType !== Node.TEXT_NODE) {
            return '';
        }
        const textContent = range.startContainer.textContent;
        const offset = range.startOffset;
        const before = textContent.slice(0, offset).split(/\s+/).pop();
        const after = textContent.slice(offset).split(/\s+/).shift();
        return (before + after).trim();
    }

    function fetchTranslation(text, event) {
        fetch(`https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=zh-CN&dt=t&dt=bd&dt=rm&dt=ss&dt=md&q=${encodeURIComponent(text)}`)
            .then(response => response.json())
            .then(data => {
                const translation = data[0][0][0];
                showTranslation(text, translation, event);
            })
            .catch(err => console.error('翻译错误:', err));
    }

    function showTranslation(word, translation, event) {
        const top = event.clientY + window.scrollY;
        translationBox.style.top = `${top + 20}px`;
        const closeButton = document.createElement('button');
        closeButton.textContent = '×';
        closeButton.classList.add('translation-close');
        closeButton.style.position = 'absolute';
        closeButton.style.top = '5px';
        closeButton.style.right = '5px';
        closeButton.style.fontSize = '18px';
        closeButton.style.backgroundColor = 'transparent';
        closeButton.style.border = 'none';
        closeButton.style.color = '#333';
        closeButton.style.cursor = 'pointer';
        closeButton.style.fontWeight = 'bold';
        translationBox.innerHTML = `
            <strong>单词:</strong> ${word} <br>
            <strong>翻译:</strong> ${translation}
        `;
        translationBox.appendChild(closeButton);
        translationBox.style.display = 'block';
    }

    function playTTSWithYoudao(selectedText) {
        if (!selectedText) {
            return;
        }
        const ttsUrl = `https://dict.youdao.com/dictvoice?audio=${encodeURIComponent(selectedText)}&type=2`;

        let existingAudio = document.getElementById('hiddenAudioExample');
        if (existingAudio) {
            existingAudio.remove();
        }

        const audio = document.createElement('audio');
        audio.id = 'hiddenAudioExample';
        audio.style.display = 'none';
        audio.src = ttsUrl;

        document.body.append(audio);

        audio.play().catch(error => console.error('TTS播放错误:', error));
    }
})();