Темы



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

Когда-то я предложил свое решение по кастомизации виджета googleTranslate, тема оказалась действительно полезной и актуальна по сей день. Репозиторий с проектом на gitHub набрал немного звезд, а я рад тому, что мои труды не напрасны. И вот недавно мне понадобилось сделать пользовательский выпадающий список с выбором языков, но уже с виджетом яндекс переводчика. Вообще сам по себе виджет вполне устраивал заказчика, но проблема заключается в том что в нем по умолчанию находится более 90 языков и этот список нельзя никак ограничить. Нельзя выставить 2–3 или 5 необходимых вам языков, будут показаны все 90+, но проблема еще и в том, что виджет не адаптивен, он занимает 1221 пиксель в ширину и никак не подстраивается под размер экрана:

be8c1c462f3e1c90330c2280fe2612fe.gif

В отличии от виджета гугл переводчика, в котором вся разметка находилась в iframe, в яндекс переводчике можно переопределить стили, но это все не то чего хотелось бы…

На сайте, где генерируется виджет есть ссылка на документацию, и конечно же я её начал изучить, но документация на самом деле об API и никакой информации по работе с виджетом не имеет. Я решил написать в тех. поддержку яндекса:

dd426806d2cb368b86de56efe7b03ab7.jpgТекст обращения

Здравствуйте. Виджет переводчика, ведет на документацию в которой вообще о виджете не слова. В частности, как для виджета выбрать для перевода не весь список из 80 языков, а например 5, которые необходимы. И как используя виджет запретить переводить определенные слова в html разметке. Например гугл виджет для этого использует класс notranslate и все что в нем не будет переведено.

И довольно быстро получил ответ:

dadb081624052030530daea8c0947bac.jpgТекст ответа

Здравствуйте, Виталий!

Такой возможности в нашем виджете сейчас нет.

Спасибо за желание сделать Яндекс.Переводчик удобнее! Я передал ваше предложение команде разработки.

И теперь окончательно убедившись, что готового решения нет, я принялся за дело.

Как будет выглядеть пример:

9af5f6e56b7c1c57db2dbeec9e93744b.gifРазметка демо-страницы



    
        
        Пользовательский виджет yatranslate для сайта на чистом js
        

        
        <script src="./js/yatranslate.js"></script>
        
        

    

    

        

        

Автоматический перевод сайта

Перевод сайта на другие языки при помощи виджета "Яндекс.Переводчик для сайтов"

Пример настраиваемого виджета

Hello World!!!

Для корректной работы виджета необходимо подключить файлы:

<script src="./js/yatranslate.js"></script>
Содержимое 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 = `${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

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

© Habrahabr.ru