您需要先安装一个扩展,例如 篡改猴、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); } }); })();