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, [email protected]
*/
/*
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>
Descargar ZIP con la solución completa