Greasy Fork

Greasy Fork is available in English.

悬停翻译句子

鼠标悬停自动翻译句子

当前为 2024-08-13 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         悬停翻译句子
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  鼠标悬停自动翻译句子
// @author       pipizhu
// @match        http*://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @license 		 MIT
// ==/UserScript==
// Function to segment the text into sentences and wrap them in span tags with a green hover border color
function wrapTextNodes(parent) {
  // Create a document fragment to hold the new structure
  const fragment = document.createDocumentFragment();
  const content = parent.innerHTML;
  function splitSentences(text) {
    if (!text) return [];
    const segmenter = new Intl.Segmenter("en", { granularity: "sentence" });
    return Array.from(segmenter.segment(text), (segment) => segment.segment);
    const regex =
      /(?=[^])(?:\P{Sentence_Terminal}|\p{Sentence_Terminal}(?!['"`\p{Close_Punctuation}\p{Final_Punctuation}\s]))*(?:\p{Sentence_Terminal}+['"`\p{Close_Punctuation}\p{Final_Punctuation}]*|$)/guy;
    return text.match(regex);
  }
  const sentences = splitSentences(content);

  sentences.forEach((sentence) => {
    const span = document.createElement("span");
    span.className = "sentence";
    span.innerHTML = sentence;
    parent.innerHTML = "";
    fragment.appendChild(span);
    fragment.appendChild(document.createTextNode(" ")); // Add space between sentences
  });

  return fragment;
}

// Get all <p> tags on the page
const paragraphs = document.querySelectorAll("p, h1, h2, h3, h4");

// Iterate through each <p> tag
paragraphs.forEach((paragraph) => {
  if (document.documentElement.lang.includes("en")) {
    paragraph.appendChild(wrapTextNodes(paragraph));
  }
});

// Add a style element to the document head for the hover effect
const style = document.createElement("style");
style.innerHTML = `
    .sentence {
        position: relative;
        transition: border-bottom-color 0.3s ease;
        cursor: pointer;
    }
    .sentence:hover {
        border-bottom: 2px solid #32CD32; /* Beautiful green */
    }
    .t-popover {
        position: absolute;
        color: black;
        top: 100%;
        width: 100%;
        left: 0;
        min-width: 300px;
        background-color: #fff;
        padding: 5px 10px;
        border: 1px solid #ccc;
        border-radius: 3px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
        z-index: 1000;
        transform: translateY(10px);
        display: none;
    }
    .sentence:hover .t-popover {
        display: block;
    }
`;
document.head.appendChild(style);

// Apply the hover effect and translation using JavaScript
document.querySelectorAll(".sentence").forEach((span) => {
  const greenColor = "#32CD32"; // Beautiful green color

  // Create a popover element
  const popover = document.createElement("div");
  popover.className = "t-popover";
  span.appendChild(popover);

  span.addEventListener("mouseover", function () {
    this.style.borderBottomColor = greenColor;
    // Check if the popover already contains translated text
    if (popover.innerText.trim() !== "") {
      return; // If it does, do nothing
    }

    // Get the original text
    const originalText = this.innerText;
    console.log("span", this.innerText);
    translateText(originalText, "zh")
      .then((data) => {
        console.log("result ", data);
        // Show the translated text in the popover
        popover.innerHTML = data;
      })
      .catch((error) => {
        popover.innerText = "Translation failed";
        console.error("Error:", error);
      });
  });

  span.addEventListener("mouseout", function () {
    this.style.borderBottomColor = "transparent";
  });
});

const translateText = async (text, targetLanguage) => {
  return googleTranslate(text, targetLanguage);
  const url = `https://api.mymemory.translated.net/get?q=${encodeURIComponent(
    text,
  )}&langpair=en|${targetLanguage}&[email protected]`;

  try {
    const response = await fetch(url);

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    const result = await response.json();
    const responseData = result.responseData;
    console.log("Translated Text:", result.responseData.translatedText);

    return responseData.translatedText;
  } catch (error) {
    console.error("There was a problem with the fetch operation:", error);
  }
};

const googleTranslate = async (text, targetLanguage) => {
  try {
    const url = `https://translate.googleapis.com/translate_a/t?client=gtx&sl=en&tl=${targetLanguage}&dt=t&q=${encodeURIComponent(text)}&format=html`;
    const response = await fetch(url, {
      method: "POST",
    });
    const data = await response.json();
    return data[0];
  } catch (error) {
    console.error("There was a problem with the fetch operation:", error);
  }
};