Tabla de contenido
Una vez más aquí. Hoy vengo a dejar un pequeño artículo relacionado con JavaScript , con el que crearemos un servicio online. Se trata de una aplicación de traducción de idiomas que se puede realizar con HTML, CSS, JavaScript y la API del servicio MyMemory. Sé que esto no ofrece nada nuevo si lo comparas con el servicio de Google, pero creo que es una buena práctica para trabajar con una API.
Con este traductor de idiomas podremos traducir texto a varios idiomas como son el español, inglés, gallego, alemán, y un largo etc. Gracias a esta aplicación los usuarios podrán traducir fácilmente texto a diferentes idiomas, copiar texto traducido al portapapeles del equipo y convertir texto a voz (más o menos, ya que la calidad de la voz no es muy agradable de escuchar).
Como decía líneas más arriba, el servicio que se utiliza para traducir es MyMemory. Según indican en su página web, esta es la memoria de traducciones más grande del mundo, que además es 100% gratis.
Traductor online
Esta aplicación se crea utilizando un poco de HTML, CSS y JavaScript. Además se utiliza una API gratuita (la de MyMemory) para convertir el texto ingresado por el usuario a diferentes idiomas. Esta API se usa solo para convertir texto a otros idiomas. Las otras cosas que realiza, como copiar texto traducido y convertir texto a voz, se realizan con JavaScript.

Aplicación de traductor de idiomas en JavaScript
Para construir esta aplicación de traducción de idiomas, necesitaremos crear cuatro archivos. Después de crear estos archivos, simplemente será necesario pegar los códigos dados en su archivo correspondiente.
Archivo HTML
El primero de los archivos que vamos a crear es el HTML. A este le vamos a dar el nombre de index.html. Dentro solo será necesario pegar el siguiente código.
<!DOCTYPE html> <html lang="es"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Traductor en Online</title> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" /> </head> <body> <div class="container"> <div id="titulo"> <h1>Traductor</h1> </div> <div class="wrapper"> <div class="text-input"> <textarea id="from" spellcheck="false" class="from-text" placeholder="Escribe el texto"></textarea> <textarea id="to" spellcheck="false" readonly disabled class="to-text" placeholder="Traducción"></textarea> </div> <ul class="controls"> <li class="row from"> <div class="icons"> <i id="from" class="fas fa-volume-up" title="Escuchar"></i> <i id="from" class="fas fa-copy" title="Copiar al portapapeles"></i> </div> <select></select> </li> <li class="exchange"><i class="fas fa-exchange-alt"></i></li> <li class="row to"> <select></select> <div class="icons"> <i id="to" class="fas fa-volume-up" title="Escuchar"></i> <i id="to" class="fas fa-copy" title="Copiar al portapapeles"></i> </div> </li> </ul> </div> <button>Traducir texto</button> <input id="reset" type="button" value="Borrar" onclick="borrarTexto();"> </div> <script src="js/countries.js"></script> <script src="js/script.js"></script> </body> </html>
Archivo CSS
En segundo lugar, vamos a crear un archivo CSS con el nombre de style.css. Dentro de este, pegaremos las siguientes reglas CSS con la que le daremos un bonito estilo a nuestra aplicación. Además vamos a añadir algunas reglas para que la aplicación se vea bien también en dispositivos móviles.
* { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Comic Sans', sans-serif; } body { display: flex; align-items: center; justify-content: center; padding: 0 10px; min-height: 100vh; background: linear-gradient(20deg, #340b42, #870eb3); } #titulo { text-align: center; margin-bottom: 20px; } .fa-volume-up::before, .fa-copy::before { color: #000; } .container { max-width: 700px; width: 100%; padding: 30px; background: #fff; border-radius: 10px; box-shadow: 0 20px 20px rgba(0, 0, 0, 0.01); } .wrapper { border-radius: 5px; border: 1px solid #ccc; } .wrapper .text-input { display: flex; border-bottom: 1px solid #ccc; } .text-input .to-text { border-radius: 0px; border-left: 1px solid #ccc; } .text-input textarea { height: 300px; width: 100%; border: none; outline: none; resize: none; font-size: 18px; padding: 10px 15px; border-radius: 5px; } .text-input textarea::placeholder { color: #b7b6b6; } .controls, li, .icons, .icons i { display: flex; align-items: center; justify-content: space-between; } .controls { list-style: none; padding: 15px 15px; } .controls .row .icons { width: 38%; } .controls .row .icons i { width: 50px; color: #adadad; font-size: 14px; cursor: pointer; transition: transform 0.2s ease; justify-content: center; } .controls .row.from .icons { padding-right: 15px; border-right: 1px solid #ccc; } .controls .row.to .icons { padding-left: 15px; border-left: 1px solid #ccc; } .controls .row select { color: #333; border: none; outline: none; font-size: 20px; background: none; padding-left: 5px; } .text-input textarea::-webkit-scrollbar { width: 4px; } .controls .row select::-webkit-scrollbar { width: 8px; } .text-input textarea::-webkit-scrollbar-track, .controls .row select::-webkit-scrollbar-track { background: #fff; } .text-input textarea::-webkit-scrollbar-thumb { background: #ddd; border-radius: 8px; } .controls .row select::-webkit-scrollbar-thumb { background: #999; border-radius: 8px; border-right: 2px solid #ffffff; } .controls .exchange { color: #adadad; cursor: pointer; font-size: 16px; transition: transform 0.2s ease; } .controls i:active { transform: scale(0.9); } .container button, #reset { width: 100%; padding: 14px; outline: none; border: none; color: #fff; cursor: pointer; margin-top: 20px; font-size: 17px; border-radius: 5px; background: #500e68; } button:hover, #reset:hover { background: #a11dd1; } @media (max-width: 660px) { .container { padding: 20px; } .wrapper .text-input { flex-direction: column; } .text-input .to-text { border-left: 0px; border-top: 1px solid #ccc; } .text-input textarea { height: 200px; } .controls .row .icons { display: none; } .container button { padding: 13px; font-size: 16px; } .controls .row select { font-size: 16px; } .controls .exchange { font-size: 14px; } }
Archivos JavaScript
En tercer lugar, vamos a crear dos archivos JavaScript. El primero de ellos tendrá el nombre de countries.js y pega los siguientes códigos en el archivo. En este archivo vamos a almacenar los países admitidos para la traduccción como un objeto.
const lenguas = { "am-ET": "Amharic", "ar-SA": "Arabic", "be-BY": "Bielarus", "bem-ZM": "Bemba", "bi-VU": "Bislama", "bjs-BB": "Bajan", "bn-IN": "Bengali", "bo-CN": "Tibetan", "br-FR": "Breton", "bs-BA": "Bosnian", "ca-ES": "Catalan", "cop-EG": "Coptic", "cs-CZ": "Czech", "cy-GB": "Welsh", "da-DK": "Danish", "dz-BT": "Dzongkha", "de-DE": "German", "dv-MV": "Maldivian", "el-GR": "Greek", "en-GB": "English", "es-ES": "Español", "et-EE": "Estonian", "eu-ES": "Basque", "fa-IR": "Persian", "fi-FI": "Finnish", "fn-FNG": "Fanagalo", "fo-FO": "Faroese", "fr-FR": "French", "gl-ES": "Gallego", "gu-IN": "Gujarati", "ha-NE": "Hausa", "he-IL": "Hebrew", "hi-IN": "Hindi", "hr-HR": "Croatian", "hu-HU": "Hungarian", "id-ID": "Indonesian", "is-IS": "Icelandic", "it-IT": "Italian", "ja-JP": "Japanese", "kk-KZ": "Kazakh", "km-KM": "Khmer", "kn-IN": "Kannada", "ko-KR": "Korean", "ku-TR": "Kurdish", "ky-KG": "Kyrgyz", "la-VA": "Latin", "lo-LA": "Lao", "lv-LV": "Latvian", "men-SL": "Mende", "mg-MG": "Malagasy", "mi-NZ": "Maori", "ms-MY": "Malay", "mt-MT": "Maltese", "my-MM": "Burmese", "ne-NP": "Nepali", "niu-NU": "Niuean", "nl-NL": "Dutch", "no-NO": "Norwegian", "ny-MW": "Nyanja", "ur-PK": "Pakistani", "pau-PW": "Palauan", "pa-IN": "Panjabi", "ps-PK": "Pashto", "pis-SB": "Pijin", "pl-PL": "Polish", "pt-PT": "Portuguese", "rn-BI": "Kirundi", "ro-RO": "Romanian", "ru-RU": "Russian", "sg-CF": "Sango", "si-LK": "Sinhala", "sk-SK": "Slovak", "sm-WS": "Samoan", "sn-ZW": "Shona", "so-SO": "Somali", "sq-AL": "Albanian", "sr-RS": "Serbian", "sv-SE": "Swedish", "sw-SZ": "Swahili", "ta-LK": "Tamil", "te-IN": "Telugu", "tet-TL": "Tetum", "tg-TJ": "Tajik", "th-TH": "Thai", "ti-TI": "Tigrinya", "tk-TM": "Turkmen", "tl-PH": "Tagalog", "tn-BW": "Tswana", "to-TO": "Tongan", "tr-TR": "Turkish", "uk-UA": "Ukrainian", "uz-UZ": "Uzbek", "vi-VN": "Vietnamese", "wo-SN": "Wolof", "xh-ZA": "Xhosa", "yi-YD": "Yiddish", "zu-ZA": "Zulu" }
El otro archivo JavaScript que vamos a crear tendrá el nombre de script.js. Dentro pegaremos el siguiente código, con el que dotaremos de funcionalidades nuestra aplicación de traductor online.
const fromText = document.querySelector(".from-text"), toText = document.querySelector(".to-text"), exchageIcon = document.querySelector(".exchange"), selectTag = document.querySelectorAll("select"), iconos = document.querySelectorAll(".row i"); BtnTraducir = document.querySelector("button") /**************************Selección idiomas*************************************/ selectTag.forEach((tag, id) => { for (let country_code in lenguas) { let selected = id == 0 ? country_code == "es-ES" ? "selected" : "" : country_code == "en-GB" ? "selected" : ""; let option = `<option ${selected} value="${country_code}">${lenguas[country_code]}</option>`; tag.insertAdjacentHTML("beforeend", option); } }); exchageIcon.addEventListener("click", () => { let tempText = fromText.value, tempLang = selectTag[0].value; fromText.value = toText.value; toText.value = tempText; selectTag[0].value = selectTag[1].value; selectTag[1].value = tempLang; }); fromText.addEventListener("keyup", () => { if(!fromText.value) { toText.value = ""; } }); /***********************Iconos********************************/ iconos.forEach(icon => { icon.addEventListener("click", ({target}) => { if(!fromText.value || !toText.value) return; if(target.classList.contains("fa-copy")) { if(target.id == "from") { navigator.clipboard.writeText(fromText.value); } else { navigator.clipboard.writeText(toText.value); } } else { let utterance; if(target.id == "from") { utterance = new SpeechSynthesisUtterance(fromText.value); utterance.lang = selectTag[0].value; } else { utterance = new SpeechSynthesisUtterance(toText.value); utterance.lang = selectTag[1].value; } speechSynthesis.speak(utterance); } }); }); /***********************Traducción**********************************/ BtnTraducir.addEventListener("click", () => { let text = fromText.value.trim(), translateFrom = selectTag[0].value, translateTo = selectTag[1].value; if(!text) return; toText.setAttribute("placeholder", "Traduciendo..."); /*URL de la API para traducir*/ let apiUrl = `https://api.mymemory.translated.net/get?q=${text}&langpair=${translateFrom}|${translateTo}`; fetch(apiUrl).then(res => res.json()).then(data => { toText.value = data.responseData.translatedText; data.matches.forEach(data => { if(data.id === 0) { toText.value = data.translation; } }); toText.setAttribute("placeholder", "Traducción"); }); }); /*****************Borrar campos***************************/ function borrarTexto() { document.getElementById("from").value = ""; document.getElementById("to").value = ""; }
Si quieres ver esta aplicación para la traducción de idiomas, puedes verla funcionando en la sección de ejemplos de esta web.