El archivo util.js
que utiliza el ejercicio se incluye en el archivo ZIP de la solución completa.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Ejercicio 18 - Teclado virtual</title> <style type="text/css" media="screen"> body, html { padding:0; margin:0; } p { font-family:verdana,tahoma,arial,helvetica,sans-serif; font-size:13px; margin-left:10px; } #keyboard { padding:30px 8px 8px 8px; margin:5px 0 0 0; height:300px; width:1000px; background-color:#eee; border-top:3px solid #ccc; border-right:3px solid #aaa; border-bottom:5px solid #888; border-left:3px solid #bbb; } kbd, .tecla { font-family:verdana,tahoma,arial,helvetica,sans-serif; font-size:13px; border-top:2px solid #ccc; border-right:5px solid #aaa; border-bottom:9px solid #888; border-left:5px solid #bbb; padding:3px 6px 3px 6px; white-space:nowrap; color:#000; background:#eee; width:22px; height:30px; float:left; overflow:hidden; cursor: pointer; cursor: hand; } .delete { padding:3px 8px 3px 4px; } img { margin-top:2px; } .narrow, .lock { font-family:arial,helvetica,sans-serif; font-size:9px; } #keyboard div, .clear { clear:both; margin:0; } .fontgap { margin-left:10px; } .rightgap { margin-right:12px; } #esc, #f4, #f8 { margin-right:30px; } #row1 { margin-bottom:12px; width:990px; height:50px; } .tab { width:48px; } .capslock { width:62px; } .shift-right { width:98px; margin-right:56px; } .backspace { width:68px; } .spacebar { width:234px; } .numpad-0 { width:66px; } .shift-left, #ctrl-left, #ctrl-right, #windows-left, #windows-right, #alt-left, .alt-right, #application { width:36px; } .enter-top { border-bottom:0; height:39px; width:42px; } #enter-bottom { border-top:0; height:32px; width:28px; margin-right:156px; } .numpad-top { border-bottom:0; height:10px; padding-top:32px;} .numpad-bottom { border-top:0; height:32px; } #arrow-up {margin-right:56px;} #sysreq, #break { font-family:'arial narrow'; font-size:10px; position:absolute; top:72px; left:696px; z-index:2; } #break {left:785px;} .lock { margin-left:30px; margin-top:25px; float:left;} #enter-edge { position:absolute; top:183px; left:609px; z-index:2; } #led-active, #led2, #led3 { position:absolute; top:40px; left:850px; width:6px; height:6px; margin-left:5px; border-top:2px solid #888; border-right:2px solid #bbb; border-bottom:2px solid #ccc; border-left:2px solid #aaa; background-color:#6f0; } #led2 {left:900px; background-color:#060;} #led3 {left:950px; background-color:#060;} .pulsada { background: #FFFF99; border-top-width:5px; border-bottom-width: 6px;} .enter-top.pulsada {border-bottom: none; border-top-width:2px;} #contenido, #contenidoGuardado { margin: 10px; background-color: #ededed; border: 2px solid #a0a0a0; padding: 1em;} </style> <script src="util.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> var teclados = {}; var tecladoActivo = null; var teclasPulsadas = []; var teclasEspeciales = ["borrado", "tabulador", "enter", "espaciadora", "mayusculas", "shift_izquierdo", "shift_derecho", "altgr"]; var tecladoIdioma = null; var tecladoVariante = null; var estado = {mayusculas: false, shift: false, altgr: false}; function descargaTeclado(idioma) { var cargador = new net.CargadorContenidosCompleto("http://localhost/RUTA_HASTA_EL_ARCHIVO/tecladoVirtual.php?nocache="+Math.random(), function() { teclados[idioma] = eval('('+this.req.responseText+')'); }, null, "POST", "accion=cargaTeclado&idioma="+idioma, "application/x-www-form-urlencoded", false); } function cargaTeclado() { // Obtener o descargar el teclado requerido if(teclados[tecladoIdioma] == null) { descargaTeclado(tecladoIdioma); } var teclado = teclados[tecladoIdioma][tecladoVariante]; // Cargar teclas normales y añadir el evento a cada una for(var i=0; i<teclado.length; i++) { if(teclado[i] != undefined) { document.getElementById('tecla_'+i).innerHTML = teclado[i]; document.getElementById('tecla_'+i).onclick = pulsaTecla; } else { document.getElementById('tecla_'+i).innerHTML = ''; } } // Añadir eventos a las teclas especiales for(var i=0; i<teclasEspeciales.length; i++) { document.getElementById('tecla_especial_'+teclasEspeciales[i]).onclick = pulsaTeclaEspecial; } tecladoActivo = teclado; } function pulsaTecla() { var teclaPulsada = this.id.replace(/tecla_/gi, ""); var caracter = tecladoActivo[teclaPulsada]; teclasPulsadas.push(caracter); // Iluminar la tecla pulsada this.className+=" pulsada"; setTimeout(apagaTecla, 100); mostrarContenidos(); } function apagaTecla() { for(var i in tecladoActivo) { if(tecladoActivo[i]) { document.getElementById('tecla_'+i).className = document.getElementById('tecla_'+i).className.replace(/pulsada/ig, ""); } } for(var i in teclasEspeciales) { if(teclasEspeciales[i]) { document.getElementById('tecla_especial_'+teclasEspeciales[i]).className = document.getElementById('tecla_especial_'+teclasEspeciales[i]).className.replace(/pulsada/ig, ""); } } } function pulsaTeclaEspecial() { var teclaPulsada = this.id.replace(/tecla_especial_/gi, ""); // Iluminar la tecla pulsada this.className+=" pulsada"; setTimeout(apagaTecla, 100); switch(teclaPulsada) { case 'borrado': teclasPulsadas.pop(); break; case 'tabulador': teclasPulsadas.push('\t'); break; case 'enter': teclasPulsadas.push('\n'); break; case 'espaciadora': teclasPulsadas.push(' '); break; case 'mayusculas': cargaVarianteTeclado('mayusculas'); break; case 'shift_izquierdo': cargaVarianteTeclado('shift_izquierdo'); break; case 'shift_derecho': cargaVarianteTeclado('shift_derecho'); break; case 'altgr': cargaVarianteTeclado('altgr'); break; } mostrarContenidos(); } function cargaVarianteTeclado(variante) { var nombreVariante = {mayusculas: 'caps', shift_izquierdo: 'shift', shift_derecho: 'shift', altgr: 'altgr'}; if(estado[variante] == true) { estado[variante] = false; tecladoVariante = 'normal'; } else { estado[variante] = true; tecladoVariante = nombreVariante[variante]; } cargaTeclado(); } function mostrarContenidos(texto, zona) { var elemento = zona || "contenido"; var contenido = texto || teclasPulsadas.join(""); contenido = contenido.replace(/\n/gi, '<br/>'); contenido = contenido.replace(/\t/gi, ' '); contenido = contenido.replace(/ /gi, ' '); document.getElementById(elemento).innerHTML = contenido; } function muestraIdiomas() { var respuesta = eval('('+this.req.responseText+')'); var lista = document.getElementById("idiomas"); var i=0; for(var codigo in respuesta.idiomas) { // Añadir idiomas a la lista desplegable lista.options[i] = new Option(respuesta.idiomas[codigo], codigo); i++; // Crear los objetos que almacenan los teclados de cada idioma teclados[codigo] = null; } // Cargar el teclado del idioma por defecto (la variante normal) tecladoIdioma = respuesta.defecto; tecladoVariante = 'normal'; cargaTeclado(); } function cambiaIdioma() { var lista = document.getElementById("idiomas"); tecladoIdioma = lista.options[lista.selectedIndex].value; cargaTeclado(); } function guarda() { var cargador = new net.CargadorContenidosCompleto("http://localhost/RUTA_HASTA_EL_ARCHIVO/tecladoVirtual.php?nocache="+Math.random(), function() { mostrarContenidos(unescape(this.req.responseText), "contenidoGuardado"); }, null, "POST", "accion=guardar&contenido="+escape(teclasPulsadas.join("")), "application/x-www-form-urlencoded"); } window.onload = function() { var cargador = new net.CargadorContenidosCompleto("http://localhost/RUTA_HASTA_EL_ARCHIVO/tecladoVirtual.php?nocache="+Math.random(), muestraIdiomas, null, "POST", "accion=listaIdiomas", "application/x-www-form-urlencoded"); // Evento necesario para cambiar el idioma del teclado document.getElementById("idiomas").onchange = cambiaIdioma; setInterval(guarda, 30 * 1000); } /* Los teclados de cada idioma y algunas ideas de implementación son originales del JavaScript Virtual Keyboard, cuya nota de copyright se incluye a continuación: */ /* * JavaScript Virtual Keyboard, version 2.2 * * Copyright (C) 2006-2007 Dmitriy Khudorozhkov * * This software is provided "as-is", without any express or implied warranty. * In no event will the author be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. * * - Dmitriy Khudorozhkov, kh_dmitry2001@mail.ru */ /* El diseño del teclado es obra de Chris Hester y se puede descargar desde http://www.designdetector.com/archives/05/03/KeyboardDemo.php */ </script> </head> <body> <div id="led-active"> </div> <div id="led2"> </div> <div id="led3"> </div> <div id="keyboard"> <div id="row1"> <kbd id="esc">Esc</kbd><kbd>F1</kbd><kbd>F2</kbd><kbd>F3</kbd><kbd id="f4">F4</kbd> <kbd>F5</kbd><kbd>F6</kbd><kbd>F7</kbd><kbd id="f8">F8</kbd><kbd>F9</kbd><kbd>F10</kbd> <kbd>F11</kbd><kbd class="rightgap">F12</kbd><kbd class="narrow">Impr<br>Pant</kbd> <kbd class="narrow">Bloq<br>Des</kbd><kbd class="narrow">Pausa</kbd> <span class="lock">Bloq<br>Num</span><span class="lock">Bloq<br>Mayus</span> <span class="lock">Bloq<br>Des</span> </div> <div id="row2"> <kbd id="tecla_0"></kbd><kbd id="tecla_1"></kbd><kbd id="tecla_2"></kbd> <kbd id="tecla_3"></kbd><kbd id="tecla_4"></kbd><kbd id="tecla_5"></kbd> <kbd id="tecla_6"></kbd><kbd id="tecla_7"></kbd><kbd id="tecla_8"></kbd> <kbd id="tecla_9"></kbd><kbd id="tecla_10"></kbd><kbd id="tecla_11"></kbd> <kbd id="tecla_12"></kbd> <kbd id="tecla_especial_borrado" class="rightgap backspace"><img src="imagenes/backspace.gif" alt="" height="19" width="52"></kbd> <kbd class="narrow">Insert</kbd><kbd class="narrow">Inicio</kbd><kbd class="narrow rightgap">Re<br>Pag</kbd> <kbd class="narrow">Bloq<br>Num</kbd><kbd>/</kbd><kbd>*</kbd><kbd>-</kbd> </div> <div> <kbd id="tecla_especial_tabulador" class="tab"><img src="imagenes/tab.gif" alt="" height="27" width="23"></kbd> <kbd id="tecla_13"></kbd><kbd id="tecla_14"></kbd><kbd id="tecla_15"></kbd><kbd id="tecla_16"></kbd> <kbd id="tecla_17"></kbd><kbd id="tecla_18"></kbd><kbd id="tecla_19"></kbd><kbd id="tecla_20"></kbd> <kbd id="tecla_21"></kbd><kbd id="tecla_22"></kbd><kbd id="tecla_23"></kbd><kbd id="tecla_24"></kbd> <kbd id="tecla_especial_enter" class="rightgap enter-top"><img src="imagenes/enter.gif" alt="" height="24" width="24"></kbd> <kbd class="narrow delete">Supr</kbd><kbd class="narrow">Fin</kbd><kbd class="narrow rightgap">Av<br>Pag</kbd> <kbd>7<br><span class="narrow">Inicio</span></kbd><kbd>8<br><img src="imagenes/arrow-up-small.gif" alt="" height="13" width="21"></kbd> <kbd>9<br><span class="narrow">RePag</span></kbd><kbd class="numpad-top">+</kbd> </div> <div> <kbd id="tecla_especial_mayusculas" class="narrow capslock">Bloq Mayus</kbd> <kbd id="tecla_25"></kbd><kbd id="tecla_26"></kbd><kbd id="tecla_27"></kbd><kbd id="tecla_28"></kbd> <kbd id="tecla_29"></kbd><kbd id="tecla_30"></kbd><kbd id="tecla_31"></kbd><kbd id="tecla_32"></kbd> <kbd id="tecla_33"></kbd><kbd id="tecla_34"></kbd><kbd id="tecla_35"></kbd><kbd id="tecla_36"></kbd> <kbd id="enter-bottom"> </kbd><kbd>4<br><img src="imagenes/arrow-left-small.gif" alt="" height="7" width="13"></kbd> <kbd>5</kbd><kbd>6<br><img src="imagenes/arrow-right-small.gif" alt="" height="7" width="13"></kbd> <kbd class="numpad-bottom"> </kbd> </div> <div> <kbd id="tecla_especial_shift_izquierdo" class="narrow shift-left"><img src="imagenes/shift.gif" alt="" height="20" width="17"></kbd> <kbd>><br><</kbd><kbd id="tecla_37"></kbd><kbd id="tecla_38"></kbd><kbd id="tecla_39"></kbd> <kbd id="tecla_40"></kbd><kbd id="tecla_41"></kbd><kbd id="tecla_42"></kbd><kbd id="tecla_43"></kbd> <kbd id="tecla_44"></kbd><kbd id="tecla_45"></kbd><kbd id="tecla_46"></kbd> <kbd id="tecla_especial_shift_derecho" class="shift-right"><img src="imagenes/shift.gif" alt="" height="20" width="17"></kbd> <kbd id="arrow-up"><img src="imagenes/arrow-up.gif" alt="" height="22" width="21"></kbd> <kbd>1<br><span class="narrow">Fin</span></kbd> <kbd>2<br><img src="imagenes/arrow-down-small.gif" alt="" height="13" width="21"></kbd> <kbd>3<br><span class="narrow">AvPag</span></kbd> <kbd class="numpad-top narrow">Enter</kbd> </div> <div> <kbd id="ctrl-left" class="narrow">Ctrl</kbd> <kbd id="windows-left"><img src="imagenes/windows-key.gif" alt="Windows Key" height="13" width="16"></kbd> <kbd id="alt-left" class="narrow">Alt</kbd> <kbd id="tecla_especial_espaciadora" class="spacebar"> </kbd> <kbd id="tecla_especial_altgr" class="narrow alt-right">Alt Gr</kbd> <kbd id="windows-right"><img src="imagenes/windows-key.gif" alt="" height="13" width="16"></kbd> <kbd id="application"><img src="imagenes/windows-application-key.gif" alt="" height="13" width="12"></kbd> <kbd id="ctrl-right" class="narrow rightgap">Ctrl</kbd> <kbd><img src="imagenes/arrow-left.gif" alt="" height="19" width="21"></kbd> <kbd><img src="imagenes/arrow-down.gif" alt="" height="22" width="21"></kbd> <kbd class="rightgap"><img src="imagenes/arrow-right.gif" alt="" height="19" width="21"></kbd> <kbd class="numpad-0" id="_0">0<br><span class="narrow">Ins</span></kbd> <kbd>.<br><span class="narrow">Supr</span></kbd> <kbd class="numpad-bottom"> </kbd> </div> </div> <select id="idiomas"><option>Cargando...</option></select> <div id="contenido"></div> <p>Contenido en el servidor [se actualiza automáticamente]</p> <div id="contenidoGuardado"></div> <p style="font-size:.9em;color:#888;margin-top:2em;">© El diseño del teclado es obra de Chris Hester y se puede descargar desde http://www.designdetector.com/archives/05/03/KeyboardDemo.php</p> </body> </html>