Una forma de mover capas en DHTML es a través de pulsaciones de teclas. Para ello necesitaremos primero detectar (capturar) cuál es la tecla que se ha pulsado para después poder programar la acción que queremos que se realice al pulsar esa tecla. Para variar, nos encontraremos con que los dos principales navegadores (Netscape 4 y Explorer 4), se comportan de forma diferente.
Capturando pulsaciones de tecla
El primer paso será inicializar los eventos de pulsación de teclas, es decir, que el navegador verifique cualquier pulsación de tecla:
document.onkeydown = pulsarTecla
Este código hará que cada vez que se pulse una tecla se ejecute la función pulsarTecla()
Para capturar qué tecla ha sido pulsada habrá que introducir órdenes diferentes según los navegadores.
Netscape
Netscape exige una línea más que Explorer para inicializar el que compruebe si pulsamos cualquier tecla, si no queremos que las cosas funcionen mal cuando ejecutemos otros eventos.
document.onkeydown = pulsarTecla
if (document.all) document.captureEvents(Event.KEYDOWN)
En Netscape para definir la función pulsarTecla debemos usar una variable oculta, que en nuestro caso será la letra "e", la cual representa la tecla pulsada. Para saber de qué tecla se trata, usaremos:
e.which //esto nos da el código de índice de la tecla pulsada
String.fromCharCode(e.which) //convierte el código de índice al carácter real pulsado
A continuación un ejemplo de función que usaría éstas órdenes para mostranos un mensaje de alerta diciéndonos qué tecla hemos pulsado y cuál es su código de índice:
function pulsarTecla(e) {
var teclaN = e.which
var teclaReal = String.fromCharCode(teclaN)
alert("Número: "+ teclaN + "\nReal: " + teclaReal)
}
document.onkeydown = pulsarTecla
document.captureEvents(Event.KEYDOWN)
Internet Explorer
Explorer trabaja de forma similar excepto que no necesita la línea extra de inicialización, ni usar una variable como la "e".
En lugar de usar e.which
, usaremos window.event.keyCode
.
La función quedaría:
function pulsarTecla() {
var teclaIE = event.keyCode
var teclaReal = String.fromCharCode(teclaIE)
alert("Número: "+ teclaIE + "\nReal: " + teclaReal)
}
document.onkeydown = pulsarTecla
Capturar teclas en ambos navegadores
A continuación crearemos una función compatible con ambos navegadores. No obstante los códigos de índice de tecla en cada navegador serán diferentes ya que ambos utilizan diferentes juegos de caracteres. Esto obligará a que cuando queramos usar las teclas para ejecutar cualquier función debamos usar ambos códigos de índice.
Una posible función para ver los códigos de índice de cada tecla en ambos navegadores sería:
ns4 = (document.layers)? true:false
ie4 = (document.all)? true:false
function pulsarTecla(e) {
if (ns4) {var TeclaN=e.which; var teclaReal = String.fromCharCode(TeclaN)
alert("Número: "+ TeclaN + "\nReal: " + teclaReal)}
if (ie4) {var TeclaIE=event.keyCode; var teclaReal = String.fromCharCode(TeclaIE)
alert("Número: "+ TeclaIE + "\nReal: " + teclaReal)}
}
document.onkeydown = pulsarTecla
if (ns4) document.captureEvents(Event.KEYDOWN)
Para ver un ejemplo. No dejas de verlo en ambos navegadores y comprobarás cómo los códigos de índices para una misma tecla varían de uno a otro.
Moviendo elementos con el teclado
Una vez que sabemos cuál es el código de índice en cada navegador para un carácter del teclado, los podemos usar para activar cualquier función de movimiento de las que hemos usado hasta ahora.
Empezaremos usando nuestro código de compatibilidad de siempre y la función de inicialización de capturas de teclado. A continuación definiremos la función Pular para que comprueba cuál es la tecla pulsada y en el caso de que sea la que definamos que activa la función movercapa.
ns4 = (document.layers)? true:false // si se trata de Netscape 4
ie4 = (document.all)? true:false // si se trata de Internet Explorer 4
if(ns4){
Refcapa='document.'
Refestilo=''
Reftop='.top'
Refleft='.left'
}
if(ie4){
Refcapa=''
Refestilo='.style'
Reftop='.pixelTop'
Refleft='.pixelLeft'
}
function init() {
document.onkeydown = Pulsar
if (ns4) document.captureEvents(Event.KEYDOWN)
}
function Pulsar(e) {
if (ns4) {var TeclaN=e.which}
if (ie4) {var TeclaIE=event.keyCode}
if (TeclaN==97 || TeclaIE==65) { // si se aprieta la tecla "A"
movercapa('capaamover',document.forms[0].Num.value)
}
}
function movercapa(capa,x) {
eval(Refcapa+capa+Refestilo+Refleft+'+='+x)
}
Aquí puedes ver el ejemplo funcionando. En este caso los pixels que se moverá la capa cada vez se podrá definir a través de una caja de texto.
Variables de "activación"
En el ejemplo anterior si a la función movercapa le añadimos un control de movimiento setTimeout("movercapa()",30)
nos encontraremos con la sorpresa de que al pulsar la tecla asignada el movimiento comenzará y no parará. Por el contrario, cada vez que pulsemos la tecla, se incrementará la velocidad más y más, al sumarse las órdenes.
Dan Steinman ha desarrollado una técnica a la que llama algo así como variables de "activación" que permiten saber el estado de movimiento de ese momento, de esa manera podemos tener el control para pararlo y/o moverlo.
Insertando un condicional dentro de la función movercapa podemos evitar que la función se repita si el elemento ya está moviéndose:
function movercapa() {
if (mielemento.active) {
mielemento.xpos += 5
mielemento.left = mielemento.xpos
setTimeout("movercapa()",30)
}
}
En este caso, la función movercapa() sólo operará si el valor de la variabe mielemento.active
es verdadero (true). Cuando definamos mielemento.active
como falso (false) la función de movimiento se parará. Sabiendo esto, podemos insertar códigos en nuestro script que nos den más control sobre lo que ocurre.
Usando onKeyUp y variables de "activación"
El evento onkeyup
trabaja exactamente igual que el onkeydown
. Podemos inicializar ambos con las siguientes líneas:
document.onkeydown = pulsarTecla
document.onkeyup = soltarTecla
if (ns4) document.captureEvents(Event.KEYDOWN | Event.KEYUP)
La función soltarTecla() también será igual, pero la usaremos para detener el movimiento, para lo cual, lo que hará será definir la variable de "activación" como 0:
function soltarTecla(e) {
if (ns4) var teclaN = e.which
if (ie4) var teclaIE = window.event.keyCode
if (teclaN==97 || teclaIE ==65) mielemento.active = false
}
Para que el código no de posibles errores vamos a colocar algunos controles en las otras funciones. En la función pulsarTecla() la orden && !mielemento.active
hará que esta función sólo sea llamada si el bloque no está en movimiento, en cuyo caso el valor de "actividad" pasara a ser cierto (true) y el bloque se moverá. La función movercapa tiene la condición if (mielemento.active)
por lo que sólo funcionará cuando el valor de mielemento.active sea verdadero (true). De esa manera cuando soltemos la tecla el movimiento se detendrá.
function init() {
if (ns4) mielemento = document.capaamover
if (ie4) mielemento = capaamover.style
mielemento.xpos = parseInt(mielemento.left)
mielemento.active = false
document.onkeydown = pulsarTecla
document.onkeyup = soltarTecla
if (ns4) document.captureEvents(Event.KEYDOWN | Event.KEYUP)
}
function pulsarTecla(e) {
if (ns4) {var teclaN=e.which; var teclaIE=0}
if (ie4) {var teclaIE=event.keyCode; var teclaN=0}
if ((teclaN==97 || teclaIE==65) && !mielemento.active) { // si pulsamos la tecla "A"
mielemento.active = true
movercapa()
}
}
function soltarTecla(e) {
if (ns4) {var teclaN=e.which; var teclaIE=0}
if (ie4) {var teclaIE=event.keyCode; var teclaN=0}
if (teclaN==97 || teclaIE==65) {
mielemento.active = false // si pulsamos la tecla "A"
}
}
function movercapa() {
if (mielemento.active) {
mielemento.xpos += 5
mielemento.left = mielemento.xpos
setTimeout("slide()",30)
}
}
A continuación un ejemplo de Dan Steinman que usa estas funciones y que nos permite jugar un poco a movernos por toda la ventana con las teclas.