Кастомный виджет Яндекс.Переводчик для сайтов

от автора

Когда-то я предложил свое решение по кастомизации виджета 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

Демонстрация

ссылка на оригинал статьи https://habr.com/ru/post/554982/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *