Pseudo-lightbox

Todo empezó cuando tenía que actualizar mi página de caricaturista. Al querer que validara de forma estricta, decidí en implementar el efecto lo más simple posible (incluso sin transiciones).

Las primeras pruebas

Como es natural, las primeras líneas del código las fui probando en mi navegador habitual, en donde normalmente no tengo problemas con mis códigos, pero al ir chequeándolo el los otros, he notado que algunas declaraciones tenía que cambiarlas. Por ejemplo, para ocultar la pantalla me bastaba con una capa bien posicionada, y con el estilo...

 height: 100%;

... Pero al no tener contenido, esa capa no cubría la pantalla en al menos un navegador. También, para simplificar aún más el código, pensaba poner la imágen a mostrar como fondo de una capa; al usar estilos me hubiera ahorrado el código para posicionar la imágen.

Ayudado por la vieja herramienta "Destripador", la intención se convirtió en un código de pocas líneas:

ie = (document.all) ? true:false;
function mostrar(que)	{
	var x, y, an, al;
	x = (ie) ? document.documentElement.scrollTop + "px" : window.scrollY + "px";
	y = (ie) ? document.documentElement.scrollLeft + "px" : window.scrollX + "px";
	al = window.document.documentElement.clientHeight + "px";
	an = window.document.documentElement.clientWidth + "px";
	pop = document.createElement("div");
	with(pop.style)	{
		top = x;
		left = y;
		height = al;
		width = an;
		position = "absolute";
	}
	pop2 = pop.cloneNode(true);
	with(pop.style)	{
		(ie)	?	filter = "alpha(opacity=80)" : opacity = ".8";
		backgroundColor = "#eeeeee";
	}
	with(pop2.style)	{
		background = "transparent url(../dibujos/reloj.gif) no-repeat center center";
	}
	im = document.createElement("img");
	with(im.style)	{
		visibility = "hidden";
		position  = "absolute";
		border = "3px inset gray";
		cursor = "pointer";
	}
	im.onload = function()	{
		this.style.backgroundColor = "white";
		xx = (parseInt(an) -  this.width) / 2;
		yy = (parseInt(al) - this.height) / 2;
		this.style.top = yy + "px";
		this.style.left = xx + "px";
		this.style.visibility = "visible";
	}
	im.src = que;
	pop2.appendChild(im);
	document.body.style.overflow = "hidden";
	document.body.appendChild(pop);
	document.body.appendChild(pop2);
	im.onclick = function()	{
		document.body.removeChild(pop2);
		document.body.removeChild(pop);
		document.body.style.overflow = "auto";
	}
}

Después de este primer código, inicié un mensaje en los forosdelweb, con la intención de recibir comentarios y sugerencias; además, con el nivel de conocimientos de sus participantes, pensé que sería muy fácil su mejora y/u optimización.

Añadiendo transiciones

Antes de recibir respuesta alguna, me rondaba por la cabeza, la manera de conseguir un opacamiento gradual de las capas, de fácil implementación, simplemente se trataba de modificar el estilo opacity, y en el otro navegador el filtro de mismo nombre.

Para poder temporizar la transición, también decidí asignarle un identificador a las nuevas capas, y de paso añadí la posibilidad de cambiar el color de fondo de la capa que oculta la página, podiéndo usar colores poco habituales como el "pink", "magenta" u otros (¡hay gente para todo!).

function tag(id)	{return document.getElementById(id);}
function opacar(capa, _n)	{
	__n = _n / 10
	with(tag(capa).style)	{
		(ie)	?	filter = "alpha(opacity=" + _n + "0)" : opacity = __n;
	}
}

Con estos "añadidos" tuve que modificar la línea de opacamiento de la imagen con un sistema "gradual":

for (opacando = 1; opacando <= 10; opacando ++)
	setTimeout("opacar('pop2', " + opacando + ")", opacando * 50 + 500);

Y usando el mismo concepto, hemos cambiado la restauración de la visibilidad de la página al clickear sobre la imagen:

im.onclick = function()	{
	for (opacando = 1; opacando < 10; opacando ++)
		setTimeout("opacar('pop', " + (10 - opacando) + ")", opacando * 50);
	for (opacando = 0; opacando < 10; opacando ++)
		setTimeout("opacar('pop2', " + (10 - opacando) + ")", opacando * 50 + 500);
	setTimeout("document.body.removeChild(tag('pop2'))", 1000);
	setTimeout("document.body.removeChild(tag('pop'))", 1000);
	document.body.style.overflow = "auto";
}

Véase el resultado completo en el siguiente mensaje de la pregunta del foro.

El mensaje iba evolucionando, y aparecieron nuevos retos, como evitar el scroll al usar las flechas del teclado, y que se puede resolver (siempre considerando los navegadores usados... los más comunes) con este código:

function nada() {return false;}
// Y llamándolo así:
for (i in keys = ["onkeypress", "onkeydown", "onkeyup"])
	document[keys[i]] = nada;

Pero aún seguía el problema en opera, y buscando en Internet, encontré un evento que desconocía: "mousewheel", que añadí al array de claves "keys".

Desde otro mensaje de los foros: Pop uP, Plantearon implementar el típico juego de controles para moverse adelante y atrás, y a pesar de que este proyecto no era tan ambicioso, me ha parecido una buena idea.

Pseudo-estructurado

Un consejo que siempre doy con respecto a las imágenes, es evitar recargar las mismas imágenes más de una vez... no se consumen muchos recursos y se evitan esperas innecesarias. Así que dentro de esta nueva estructura crearemos un objeto para guardar las imágenes "visitadas", que tendrán un identificador que se pasará como segundo parámetro del nuevo método.

var pseudo = new Object();
pseudo.espera = 25;
pseudo.fondo = "gray";
pseudo.visitadas = new Object();
pseudo.mostrar = function()	{
	// aquí el código
}

Usaremos miniaturas de las imágenes que se ven en esta otra página: Andalucía, y las propias imágenes serán las que se mustren con sus respectivos mensajes.

Las miniaturas:

No se pudo ejecutar la consulta