domingo, 18 de septiembre de 2011

Cómo crear una ventana modal propia (2)

Si bien JavaScript nos da los valores del ancho y el alto de la pantalla del monitor, ese dato no nos sirve de mucho a la hora de tratar de crear una ventana modal porque este tipo de ventanas se deben mostrar centradas en el navegador y este puede ser redimensionado. Pero, aún más, aunque no sea redimensionado, el tipo de navegador que usamos nos mostrará un espacio distinto ya que algunos tienen bordes, otros tienen varias barras de herramienta, menús, barras de estado, etc, etc, etc.

Obviamente, el dato del monitor o sea, la resolución de la pantalla, será siempre el mismo pero el espacio disponible para nuestra pagina web, variará sustancialmente. La resolución del monitor es la devuelta por screen.width y screen.height y el tamaño de la ventana del navegador por estos dos datos:

document.documentElement.clientWidth nos indica el valor del ancho
document.documentElement.clientHeight nos indica el valor del alto

ANCHOALTO
monitormostrar
navegador

Pero, saber esa dimensión no es suficiente porque, como decía en al entrada anterior, el ancho del BODY es igual al ancho de la ventana pero, la altura de la página es variable y suele ser bastante mayor que el área visible así que para ubicar nuestra ventana modal, debemos saber en qué parte de la página estamos ya que para posicionar la ventana con la propiedad top, debemos colocar un valor absoluto cuyo cero inicial es la parte superior de la página.

Ese dato también es accesible pero, no es el mismo en todos los navegadores.

window.pageYOffset no es leido por Internet Explorer
document.body.scrollTop sólo funciona en Chrome
document.documentElement.scrollTop lo leen todos excepto Chrome

Así que hay que hacer malabares y suele usarse algo así:
if(typeof(window.pageYOffset) == 'number') {
posicion = window.pageYOffset;
} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
posicion = document.body.scrollTop;
} else if(document.documentElement) {
posicion = document.documentElement.scrollTop;
}
IExplorerFirefoxChromeOpera
posicionmostrar

Con ese dato, ya podemos usar la aritmética para calcular la posición de nuestra ventana.

el valor de left será: ( ancho_navegador / 2) - ( ancho_ventana / 2 )
y el valor de top será: posicion_offset + ( alto_ventana / 2 )

Y esta es una función simple que combian todo lo dicho y nos muestra esas ventanas modales:
function showMVM(ancho,alto) {

var sW, sH, x, y, posicion;
var MVM = document.getElementById("MVM");
var MVMCONTENIDO = document.getElementById("MVM-contenido");

// si es visible, la cierro
if(MVM.style.visibility == "visible") { MVM.style.visibility = "hidden"; }

// guardo el tamaño de la ventana del navegador
sW = document.documentElement.clientWidth; // ancho navegador
sH = document.documentElement.clientHeight; // alto navegador

// guardo el offset, la distancia que hay entre el inicio de la página y donde estoy
if(typeof(window.pageYOffset) == 'number') {
posicion = window.pageYOffset;
} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
posicion = document.body.scrollTop;
} else if(document.documentElement) {
posicion = document.documentElement.scrollTop;
}

// calculo la posición horizontal que irá en left
x = ( sW / 2) - ( ancho / 2 );

// calculo la posición vertical que irá en top
y = posicion + ( sH - alto ) / 2;

// dimensiono el contenido
MVMCONTENIDO.style.width = ancho + "px";
MVMCONTENIDO.style.height = alto + "px";

// ubico la ventana
MVM.style.left = x + "px";
MVM.style.top = y + "px";

// la hago visible
MVM.style.visibility = "visible";
}
Un enlace de este tipo, la mostraría de 300x200:
<a href="javascript:demoMVMshow(300,200);"> ventana modal 300x200 </a>


Lo que varía, lo que hace que la ventana modal sea más grande o más pequeña es básicamente su contenido y es sencillo establecer su tamaño si lo conocemos previamente; las complicaciones surgen cuando desconocemos ese tamaño

Por ejemplo, si queremos mostrar una imagen y desconocemos su tamaño ¿es posible saberlo antes de mostrarla? Evidentemente si porque hay algunos scripts de ventanas modales que lo hacen pero, lo cierto es que eso no es nada sencillo en absoluto. Por ejemplo, en teoría, una función así nos dirá el tamaño de cualquier imagen aún cuando no la estemos mostrando:
function getIMGsize(url){
var newImg = new Image();
newImg.src = url;
var height = newImg.height;
var width = newImg.width;
alert (width+'x'+height);
}
url

Pero eso, es teoría porque tal vez, no nos de ese dato y diga que mide cero aunque si hacemos click por segunda o tercera vez, el resultado será correcto ¿Por qué? Porque hacemos click y el script se ejecuta instantánemanete pero la imagen debe ser cargada de alguna manera y, evidentemente, eso llevará tiempo. Si funciona la segunda vez que lo intentamos es porque el navegador ya la cargó y la tiene en la caché así que, simplemente, la busca ahí y nos dice su tamaño.

En la web, hay decenas y decenas de preguntas y explicaciones al respecto con infinidad de variantes pero difícilmente haya una sencilla que se pueda aplciar en todos los casos y en todos los navegadores por lo tanto, como esto de una ventana modal propia sólo apunta a aprender un poco, me voy a olvidar del asunto y establezco ese límite: puedo mostrar cualquier cosa pero debo saber el tamaño de lo que voy a mostrar. Si alguien encuentra una solución práctica, que avise.
Mientras tanto, acepto la limitación y sigo adelante mostrando la misma imagen pero cargándola con tres tamaños distintos:

600x375

800x500

350x219

No hay comentarios:

Publicar un comentario