您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Добавляет контекстное меню для перевода выделенного текста через Яндекс.Переводчик
- // ==UserScript==
- // @name Yandex Translate Selection
- // @namespace http://tampermonkey.net/
- // @version 1.0
- // @description Добавляет контекстное меню для перевода выделенного текста через Яндекс.Переводчик
- // @author motorrin
- // @match *://*/*
- // @grant GM_registerMenuCommand
- // ==/UserScript==
- (function() {
- 'use strict';
- // Создаем и добавляем стили
- const style = document.createElement('style');
- style.textContent = `
- .translate-menu-item {
- padding: 8px 12px;
- cursor: pointer;
- background: #292C2F;
- color: #fffff0;
- border: 1px solid #fffff0;
- border-radius: 4px;
- text-decoration: none;
- white-space: nowrap;
- font-size: 13px;
- }
- .translate-menu-item .ya-letter {
- color: #ff3333;
- }
- .translate-menu {
- position: fixed;
- background: transparent;
- z-index: 10000;
- }
- .translate-menu-item:hover {
- opacity: 0.9;
- }
- `;
- document.head.appendChild(style);
- let currentMenu = null;
- let menuTimeout = null;
- let translatorWindow = null;
- let lastScrollPosition = window.scrollY;
- let scrollTimeout = null;
- // Функция открытия переводчика в новом окне
- function openTranslator(text) {
- // Закрываем предыдущее окно переводчика, если оно существует
- if (translatorWindow && !translatorWindow.closed) {
- translatorWindow.close();
- }
- // Вычисляем размеры и позицию для нового окна
- const width = 800;
- const height = 600;
- const left = (window.screen.width - width) / 2;
- const top = (window.screen.height - height) / 2;
- // Открываем новое окно с заданными параметрами
- translatorWindow = window.open(
- `https://translate.yandex.ru/?text=${encodeURIComponent(text)}`,
- 'YandexTranslate',
- `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,status=no,menubar=no,toolbar=no`
- );
- // Фокусируем новое окно
- if (translatorWindow) {
- translatorWindow.focus();
- }
- }
- // Функция закрытия меню
- function closeMenu() {
- if (currentMenu) {
- currentMenu.remove();
- currentMenu = null;
- }
- }
- // Отслеживаем прокрутку страницы
- document.addEventListener('scroll', function() {
- // Используем throttling для оптимизации производительности
- if (!scrollTimeout) {
- scrollTimeout = setTimeout(() => {
- if (Math.abs(window.scrollY - lastScrollPosition) > 5) { // Минимальный порог прокрутки
- closeMenu();
- }
- lastScrollPosition = window.scrollY;
- scrollTimeout = null;
- }, 50);
- }
- }, { passive: true }); // Оптимизация производительности
- // Отслеживаем отпускание кнопки мыши
- document.addEventListener('mouseup', function(e) {
- // Очищаем предыдущий таймер, если он есть
- if (menuTimeout) {
- clearTimeout(menuTimeout);
- }
- // Устанавливаем новый таймер
- menuTimeout = setTimeout(() => {
- const selectedText = window.getSelection().toString().trim();
- // Удаляем предыдущее меню
- closeMenu();
- if (selectedText) {
- const selection = window.getSelection();
- const range = selection.getRangeAt(0);
- const rect = range.getBoundingClientRect();
- const menu = document.createElement('div');
- menu.className = 'translate-menu';
- const menuItem = document.createElement('div');
- menuItem.className = 'translate-menu-item';
- menuItem.innerHTML = 'Перевести в <span class="ya-letter">Я</span>ндекс';
- menuItem.onclick = (e) => {
- e.preventDefault();
- openTranslator(selectedText);
- closeMenu();
- };
- menu.appendChild(menuItem);
- // Позиционируем меню выше выделенного текста
- const menuVerticalOffset = 35;
- menu.style.left = `${rect.left}px`;
- menu.style.top = `${rect.top - menuVerticalOffset}px`;
- document.body.appendChild(menu);
- currentMenu = menu;
- // Корректируем позицию, если меню выходит за пределы экрана
- const menuRect = menu.getBoundingClientRect();
- if (menuRect.top < 0) {
- menu.style.top = `${rect.bottom + 10}px`;
- }
- if (menuRect.right > window.innerWidth) {
- menu.style.left = `${window.innerWidth - menuRect.width - 10}px`;
- }
- }
- }, 200);
- });
- // Закрываем меню при клике вне его
- document.addEventListener('mousedown', function(e) {
- if (currentMenu && !currentMenu.contains(e.target)) {
- closeMenu();
- }
- });
- // Очищаем таймер при отмене выделения
- document.addEventListener('selectionchange', function() {
- if (!window.getSelection().toString().trim() && menuTimeout) {
- clearTimeout(menuTimeout);
- }
- });
- })();