Когда-то я предложил свое решение по кастомизации виджета googleTranslate, тема оказалась действительно полезной и актуальна по сей день. Репозиторий с проектом на gitHub набрал немного звезд, а я рад тому, что мои труды не напрасны. И вот недавно мне понадобилось сделать пользовательский выпадающий список с выбором языков, но уже с виджетом яндекс переводчика. Вообще сам по себе виджет вполне устраивал заказчика, но проблема заключается в том что в нем по умолчанию находится более 90 языков и этот список нельзя никак ограничить. Нельзя выставить 2-3 или 5 необходимых вам языков, будут показаны все 90+, но проблема еще и в том, что виджет не адаптивен, он занимает 1221 пиксель в ширину и никак не подстраивается под размер экрана:
В отличии от виджета гугл переводчика, в котором вся разметка находилась в iframe, в яндекс переводчике можно переопределить стили, но это все не то чего хотелось бы...
На сайте, где генерируется виджет есть ссылка на документацию, и конечно же я её начал изучить, но документация на самом деле об API и никакой информации по работе с виджетом не имеет. Я решил написать в тех. поддержку яндекса:
Здравствуйте. Виджет переводчика, ведет на документацию в которой вообще о виджете не слова. В частности, как для виджета выбрать для перевода не весь список из 80 языков, а например 5, которые необходимы. И как используя виджет запретить переводить определенные слова в html разметке. Например гугл виджет для этого использует класс notranslate и все что в нем не будет переведено. Текст обращения
И довольно быстро получил ответ:
Текст ответа
Здравствуйте, Виталий!
Такой возможности в нашем виджете сейчас нет.
Спасибо за желание сделать Яндекс.Переводчик удобнее! Я передал ваше предложение команде разработки.
И теперь окончательно убедившись, что готового решения нет, я принялся за дело.
Как будет выглядеть пример:
Разметка демо-страницы
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Пользовательский виджет yatranslate для сайта на чистом js</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- yatranslate -->
<script src="./js/yatranslate.js"></script>
<link rel="stylesheet" href="./css/yatranslate.css">
<!-- END yatranslate -->
</head>
<body class="body">
<div class="lang lang_fixed">
<div id="ytWidget" style="display: none;"></div>
<div class="lang__link lang__link_select" data-lang-active>
<img class="lang__img lang__img_select" src="./images/lang/lang__ru.png" alt="Ru">
</div>
<div class="lang__list" data-lang-list>
<a class="lang__link lang__link_sub" data-ya-lang="ru">
<img class="lang__img" src="./images/lang/lang__ru.png" alt="ru">
</a>
<a class="lang__link lang__link_sub" data-ya-lang="en">
<img class="lang__img" src="./images/lang/lang__en.png" alt="en">
</a>
<a class="lang__link lang__link_sub" data-ya-lang="de">
<img class="lang__img" src="./images/lang/lang__de.png" alt="de">
</a>
<a class="lang__link lang__link_sub" data-ya-lang="zh">
<img class="lang__img" src="./images/lang/lang__zh.png" alt="zh">
</a>
<a class="lang__link lang__link_sub" data-ya-lang="fr">
<img class="lang__img" src="./images/lang/lang__fr.png" alt="fr">
</a>
</div>
</div>
<section class="content">
<h1 class="content__title">Автоматический перевод сайта</h1>
<div class="content__desc">
<p>Перевод сайта на другие языки при помощи виджета "Яндекс.Переводчик для сайтов"</p>
<p>Пример настраиваемого виджета</p>
<p>Hello World!!!</p>
</div>
</section>
<style>
/* Стили для демонстрации */
/* Styles for demonstration */
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 0;
font-family: tahoma;
}
.content {
text-align: center;
margin: auto;
}
</style>
</body>
</html>
Для корректной работы виджета необходимо подключить файлы:
<script src="./js/yatranslate.js"></script>
<link rel="stylesheet" href="./css/yatranslate.css">
Содержимое yatranslate.css
/* lang */
.lang {
position: relative;
z-index: 10;
text-align: center;
background: rgba(157, 157, 157, 0.3);
perspective: 700px;
}
.lang_fixed {
position: fixed;
right: 20px;
top: 20px;
}
.lang__link {
cursor: pointer;
transition: .3s all;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-shrink: 0;
box-sizing: border-box;
text-decoration: none;
border-radius: 2px;
padding: 4px;
}
.lang__img {
width: 30px;
height: 18px;
flex-shrink: 0;
font-size: 10px;
display: block;
transition: .3s all;
}
.lang__link_sub:hover {
filter: drop-shadow(0 0 3px rgb(136, 136, 136)) brightness(130%);
}
.lang__name {
color: #737b84;
font-size: 12px;
line-height: 12px;
flex-shrink: 0;
text-transform: uppercase;
}
.lang__link_sub {
width: 100%;
height: auto;
position: relative;
padding: 0;
margin-bottom: 2px;
}
.lang__list {
background: rgba(157, 157, 157, 0.3);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
opacity: 0;
visibility: hidden;
transition: .3s all;
transform: rotateX(-90deg);
position: absolute;
left: 0;
top: 100%;
z-index: 10;
line-height: 13px;
padding: 4px;
transform-origin: center top;
box-sizing: border-box;
}
.lang:hover .lang__list {
opacity: 1;
visibility: visible;
transform: rotateX(0);
}
.lang__link_select {
align-items: flex-start;
text-align: center;
font-size: 0;
}
Содержимое yatranslate.js
/*!***************************************************
* yatranslate.js v1.0.0
* author: Vitalii P.
*****************************************************/
const yatranslate = {
/* Original language */
lang: "ru",
/* The language we translate into on the first visit */
/* Язык, на который переводим при первом посещении */
// langFirstVisit: 'en',
};
document.addEventListener('DOMContentLoaded', function () {
// Start
yaTranslateInit();
})
function yaTranslateInit() {
if (yatranslate.langFirstVisit && !localStorage.getItem('yt-widget')) {
/* Если установлен язык перевода для первого посещения и в localStorage нет yt-widget */
/* If the translation language is installed for the first visit and in localStorage no yt-widget */
yaTranslateSetLang(yatranslate.langFirstVisit);
}
// Подключаем виджет yandex translate
// Connecting the yandex translate widget
let script = document.createElement('script');
script.src = `https://translate.yandex.net/website-widget/v1/widget.js?widgetId=ytWidget&pageLang=${yatranslate.lang}&widgetTheme=light&autoMode=false`;
document.getElementsByTagName('head')[0].appendChild(script);
// Получаем и записываем язык на который переводим
// We get and write down the language into which we translate
let code = yaTranslateGetCode();
// Показываем текущий язык в меню
// Show the current language in the menu
yaTranslateHtmlHandler(code);
// Вешаем событие клик на флаги
// We hang the event click on the flags
yaTranslateEventHandler('click', '[data-ya-lang]', function (el) {
yaTranslateSetLang(el.getAttribute('data-ya-lang'));
// Перезагружаем страницу
// Reloading the page
window.location.reload();
})
}
function yaTranslateSetLang(lang) {
// Записываем выбранный язык в localStorage объект yt-widget
// Writing the selected language to localStorage
localStorage.setItem('yt-widget', JSON.stringify({
"lang": lang,
"active": true
}));
}
function yaTranslateGetCode() {
// Возвращаем язык на который переводим
// Returning the language to which we are translating
return (localStorage["yt-widget"] != undefined && JSON.parse(localStorage["yt-widget"]).lang != undefined) ? JSON.parse(localStorage["yt-widget"]).lang : yatranslate.lang;
}
function yaTranslateHtmlHandler(code) {
// Получаем язык на который переводим и производим необходимые манипуляции с DOM
// We get the language to which we translate and produce the necessary manipulations with DOM
document.querySelector('[data-lang-active]').innerHTML = `<img class="lang__img lang__img_select" src="./images/lang/lang__${code}.png" alt="${code}">`;
document.querySelector(`[data-ya-lang="${code}"]`).remove();
}
function yaTranslateEventHandler(event, selector, handler) {
document.addEventListener(event, function (e) {
let el = e.target.closest(selector);
if (el) handler(el);
});
}
Используемые флаги
Логика виджета довольно простая. При выборе языка в локальное хранилище записывается объект с ключем yt-widget. В объекте хранится язык на который будет переведен сайт:
{
"lang":"en",
"active":true
}
К локальному хранилищу без проблем можно получить доступ и я применил ту же технику что и с гугл переводчиком. Виджет яндекса прячем, а кликая на свой кастоный флажок с атрибутом data-ya-lang назначаем записаный в нем язык свойству lang и перезагружаем страницу. После перезагрузки страницы язык, который мы сами установили, будет подхвачен виджетом и сайт будет на него переведен. В функции yaTranslateHtmlHandler проводим необходимые манипуляции с разметкой, в моем случае я показываю флаг текущего языка перевода и удаляю его из общего списка. В js каждый этап я разбил на функции и добавил описание, чтобы было легче доработать код под себя.
Репозиторий с проектом на GitHub
Автор: Виталий