JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Utilizando la API de pantalla completa en todos los navegadores

Nota: He estado un poco “missing” desde hace un tiempo, casi un mes, entre otras muchas cosas por que he estado muy involucrado en el lanzamiento de nuestra zona de recursos para programadores en campusMVP.es. En ella encontrarás muchas cosas interesantes para programadores, sobre todo los que se inician, y podrás encontrar trucos, conceptos de base, vídeos prácticos, noticias, y mucho más. Añádelo a favoritos :-) Ahora, para compensar, un artículo bastante a fondo sobre un tema muy interesante... ;-)

Full_ScreenDe toda la vida estamos acostumbrados a que, cuando visualizamos un vídeo, tengamos la opción de verlo a pantalla completa, para poder apreciar todos los detalles y verlo en alta definición. En lo que no se fijaba casi nadie es en que, hasta hace relativamente poco, todos esos visores de vídeo estaban basados en Flash y en menor medida en Silverlight, y esa capacidad de verse a toda pantalla estaba reservada para estas tecnologías de plugins, ajenas al propio navegador.

Por suerte en los estándares de HTML5 se ha tenido en cuenta esta posibilidad para poder aplicarla, no solo a los vídeos, sino también a cualquier otro tipo de elemento que tengamos en una página web. Así, podemos hacer que una imagen se muestre reducida en una página, pero que los visitantes puedan verla a pantalla completa si lo necesitan, estirándola además lo que consideremos necesario. Lo mismo podemos hacer por ejemplo con un <div> o un <iframe>, de modo que su contenido se vea a toda pantalla. Hay muchas aplicaciones prácticas de esta técnica.

El mayor problema existente hoy en día es el soporte irregular por parte de los diferentes navegadores. Pero es algo bastante fácil de solucionar. En este artículo, aparte de explicar el funcionamiento de la API y sus particularidades en los diferentes navegadores, proporcionaré una sencilla biblioteca JavaScript para descarga que podrás usar de manera transparente en cualquier navegador.

Vamos a ello...

Detectar el soporte para la API de Pantalla Completa

Antes de nada ¿qué navegadores soportan esta API? Pues todos los modernos, aunque con diferencias y prefijos propios en su mayor parte. En concreto la API está soportada por Chrome 20 o posterior, Firefox 10+, Internet Explorer 11, Opera 12 y Safari 5.1.

De todos modos, esto no importa demasiado. Lo que necesitamos es detectar en código que la característica está soportada. Para ello, la API estándar nos ofrece el método fullscreenEnabled del documento actual. El problema es que de momento ningún navegador implementa el estándar pero ofrecen sus propias variantes (básicamente con los prefijos “webit”, “moz” y “ms” delante, según el navegador). Lo que tenemos que hacer es probar con todos ellos, empezando por el estándar, de modo que a medida que lo vayan incorporando ya no sea necesario comprobar los anteriores (gracias al cortocircuito de expresiones lógicas).

En definitiva, podemos escribir una función como esta:

function FullScreenSupportEnabled() {
    return (document.fullscreenEnabled || 
            document.webkitFullscreenEnabled || 
            document.mozFullScreenEnabled ||
            document.msFullscreenEnabled);
}

De este modo podemos llamar a esta función en cualquier momento para saber si el navegador actual soporta la API de pantalla completa o no.

Podemos usarla para ocultar los elementos que sirvan para lanzar zonas a pantalla completa, en caso de que no esté soportada la API.

Colocar un elemento a pantalla completa

Una vez que ya sabemos si el navegador actual soporta o no la API, lo siguiente que querremos hacer es lanzar un elemento a pantalla completa. Para ello disponemos de una función estándar llamada requestFullscreen y, al igual que antes, de todas las variantes según el navegador. Esta función está disponible en todos los elementos, por lo que se aplica directamente al elemento que queremos poner a pantalla completa, así:

document.getElementById("MiImagen").requestFullscreen();

Para poder hacerlo de manera más genérica y que funcione en todos los navegadores podemos escribir una función como la siguiente:

function SetFullScreen(elto) {
    //Si no se soporta la API, ya ni lo intentamos
    if (!FullScreenSupportEnabled()) return;
    //Se prueba la variante apropiada según el navegador
    try {
        if (elto.requestFullscreen) {    //Empezando por la estándar
            elto.requestFullscreen();
        } else if (elto.webkitRequestFullscreen) {    //Webkit (Safari, Chrome y Opera 15+)
            elto.webkitRequestFullscreen();
        } else if (elto.mozRequestFullScreen) {    //Firefox
            elto.mozRequestFullScreen();
        } else if (elto.msRequestFullscreen) {    //Internet Explorer 11+
            elto.msRequestFullscreen();
        }
    }
    catch(ex) {
        return false;
    }
    return true;
}

De este modo, para poner un elemento a pantalla completa, solo tenemos que escribir:

SetFullScreen( document.getElementById("MiImagen") );

Es decir, le pasamos el elemento que queremos poner a pantalla completa y ya se encarga de todo. Muy fácil.

Detectar qué elemento está actualmente a pantalla completa

Ahora vamos a hacer justo lo contrario, es decir, averiguar qué elemento está a pantalla completa mediante código. Para ello el método estándar se llama fullscreenElement. Éste devuelve una referencia al elemento que está actualmente puesto a pantalla completa, en caso de haberlo, sino devuelve un nulo.

Nuevamente existen tantas variantes con prefijo como motores de renderizado de navegadores existen, por lo que podemos escribir una función que encapsule la funcionalidad de manera que trabaje bien en cualquier navegador. Sería una cosa así:

function getCurrentElementInFullScreen(){
    if (document.fullscreenElement)
        return document.fullscreenElement;
    if (document.webkitFullscreenElement)
        return document.webkitFullscreenElement;
    if (document.mozFullScreenElement)
        return document.mozFullScreenElement;
    if (document.msFullscreenElement)
        return document.msFullscreenElement;
 
    return null;
}

Lo que hace es ir comprobando qué función es la que existe en el navegador actual y la llama. En caso de que ninguna funcione, devuelve un nulo.

¿Para qué necesitamos saber cuál es el elemento que está a pantalla completa? Pues para poder manipularlo por JavaScript, cambiar sus propiedades, su posición, etc... Aunque como veremos luego es bastante fácil aplicar estilos CSS directamente a los elementos que están a toda pantalla.

También podemos hacer uso de este método para una cosa más simple, como es averiguar si actualmente hay algún elemento mostrándose a pantalla completa o no. Sería algo tan sencillo como esta variante de lo anterior:

function CurrentlyInFullScreen() {
    return (document.fullscreenElement ||
    document.webkitFullscreenElement ||
    document.mozFullScreenElement ||
    document.msFullscreenElement);
}

Salir del modo a pantalla completa

Una vez que tengamos un elemento a pantalla completa, podemos pasar al modo normal con una llamada a la función estándar exitFullscreen. Nuevamente con sus variantes, que podemos encapsular en una sola función de este modo:

function ExitFullScreenMode(){
    if (document.exitFullscreen) {
        document.exitFullscreen();
    } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
    } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
    }
}

Así no tenemos que llevar control de cuál es el elemento que está a toda pantalla, cerrándolo en cualquier caso.

Eventos

También es posible enterarnos de manera automática de cuando un elemento ha pasado a mostrarse a pantalla completa. En lugar de tener que comprobar en un temporizador si hay algo visualizándose en este modo, podemos simplemente suscribirnos a un evento que será llamado de manera automática cuando se cambie a modo pantalla completa y cuando se retorne a modo de vista normal.

El evento estándar se llama fullscreenchange pero tiene variantes por cada navegador. En lugar de tener que acordarnos del nombre para cada navegador, es más fácil crear una función a la que le pasemos un manejador de una función y que se encargue de suscribir a todos los métodos según el navegador, así:

function AddFullScreenChangeEventHandler(handler){
    document.addEventListener("fullscreenchange", handler);
    document.addEventListener("webkitfullscreenchange", handler);
    document.addEventListener("mozfullscreenchange", handler);
    document.addEventListener("MSFullscreenChange", handler);
}

El manejador es una función cualquiera que no toma parámetros y desde la que podemos averiguar el elemento actual que cambia de estado si lo necesitamos usando la función que vimos antes. Por ejemplo este manejador:

function cambioPantallaCompleta() {
    if (CurrentlyInFullScreen())
        alert("Se ha cambiado a pantalla completa");
    else
        alert("Se ha cambiado a pantalla normal");
}

y en este caso lo asignamos un poco “a las bravas” para mostrar que funciona:

<body onload="AddFullScreenChangeEventHandler(cambioPantallaCompleta);">

De este modo cada vez que cambie a pantalla completa o regrese lo detectaremos de manera sencilla.

También se puede capturar el hecho de que se produzca un error al saltar a pantalla completa. Este puede producirse, por ejemplo, porque estemos intentando mostrar el contenido de un <iframe> o un <video> que no hayan sido marcados con el atributo allowfullscreen, o en caso de que el usuario no lo permita. Para estos casos el evento funciona como el anterior y se llama, de manera estándar, fullscreenerror. Con sus variantes podemos definir un método análogo al anterior de esta manera:

function AddFullScreenErrorEventHandler(handler){
    document.addEventListener("fullscreenerror", handler);
    document.addEventListener("webkitfullscreenerror", handler);
    document.addEventListener("mozfullscreenerror", handler);
    document.addEventListener("MSFullscreenError", handler);
}

Diferencias entre navegadores al mostrar

Con todo lo anterior podemos controlar de manera sencilla desde código la experiencia de pasar elementos a pantalla completa, y nos dará mucho juego.

El problema es que según el navegador el comportamiento por defecto variará por completo.

Por ejemplo, si ponemos un <div> a pantalla completa, el efecto conseguido variará según el navegador de la siguiente manera:

  • Internet Explorer lo mostrará alineado a la izquierda y arriba, con su tamaño y aspecto originales.
  • Chrome, Opera y Safari (Webkit, vamos) lo mostrarán centrado en la pantalla, con su tamaño y aspecto originales.
  • Firefox lo muestra ocupando toda el área disponible y por lo tanto variando su tamaño.

Además, si el elemento es más pequeño que la pantalla o si su relación de aspecto es diferente a la de ésta, hay zonas que quedarán sin cubrir. Éstas son lo que se considera el fondo, y por defecto se ve de color negro en todos los navegadores.

Para poder controlar con precisión cómo queremos que se muestren los elementos a pantalla completo, los navegadores definen una pseudo-clase CSS llamada, de manera estándar, :fullscreen (con todas sus variantes que debemos definir).

Así, por ejemplo, podemos escribir unas reglas como estas:

#Contenido:fullscreen {
  margin:0px;
  left:0px;
  top:0px;
  width: 100%;
  height: 100%;
}
#Contenido:-webkit-full-screen {
  margin:0px;
  left:0px;
  top:0px;
  width: 100%;
  height: 100%;
}
#Contenido:-moz-full-screen {
  margin:0px;
  left:0px;
  top:0px;
  width: 100%;
  height: 100%;
}
#Contenido:-ms-fullscreen {
  margin:0px;
  left:0px;
  top:0px;
  width: 100%;
  height: 100%;
}

De esta manera, por ejemplo, estamos definiendo que un elemento de nombre “Contenido” que vamos a poner a pantalla completo, cuando se esté mostrando de esa manera, tenga una serie de propiedades definidas. He definido cuatro veces la misma regla, para la pseudo-clase estándar y para las variantes de Chrome/Safari/Opera, Firefox e Internet Explorer respectivamente.

Podemos modificar el estilo por defecto para cualquier elemento a pantalla completa si usamos la pseudo-clase suelta, sin combinarla con otros selectores CSS como acabo de hacer. De hecho todos los navegadores definen unos estilos por defecto para el pseudo-elemento :fullscreen que hacen que los elementos se comporten de la manera descrita anteriormente.

El único en el que es posible verlos en acción desde la herramientas del programador es Chrome, que nos deja ver cómo se aplican:

PantallaCompleta_PseudoElemento_Chrome

En este caso lo único que hace en la práctica es colocar la capa de pantalla completa por encima de todas las demás asignándole un z-index muy elevado.

Aunque especifiquemos nuestros propios estilos para :fullscreen debemos tener en cuenta que cada navegador puede hacer que algunas cosas no se vean del todo correctas. Por ejemplo, Chrome elimina los bordes laterales, aunque conserva el superior e inferior, mientras que Firefox elimina el borde superior (WTF?). El único que parece conservar con total fidelidad los estilos que se apliquen, incluyendo los bordes, es Internet Explorer. Bien por Microsoft esta vez ;-)

Respecto al color de fondo, que por defecto es negro, en el caso del estándar en teoría deberíamos poder cambiarlo gracias a la pseudo-clase ::backdrop. Sin embargo el único navegador que por el momento lo permite es Internet Explorer 11, pero lo hace usando su propio prefijo “-ms”. Así que por el momento lo que podemos especificar es algo como esto:

:fullscreen::backdrop {
    background-color: #CCC; 
}
:-ms-fullscreen::-ms-backdrop
{
    background-color: #CCC; 
}

De modo que especificamos un color de fondo gris con el estilo estándar para cuando lo soporten los navegadores, y con “-ms” para que lo haga Internet Explorer. Con Chrome, Firefox y los demás no tenemos esta posibilidad por el momento.

Resumen y descargas

La API para pantalla completa es muy interesante en especial para aplicaciones especializadas como pueden ser juegos, páginas que se basen mucho en vídeo o en contenidos que y queramos facilitar su lectura sin interferencias.

Aunque el soporte por parte de los navegadores modernos es bastante amplio, es muy irregular, en el sentido de que cada uno lo implementa de una manera diferente, usando sus propios prefijos, aunque todos funcionen de la misma manera.

He creado una pequeña biblioteca llamada fullScreen.js que contiene todas las funciones mencionadas en este artículo y que te ayudará a manejar la API de pantalla completa de manera coherente en todos los navegadores.

Dentro del ZIP anterior también se incluye un pequeño ejemplo práctico que muestra la biblioteca en funcionamiento. Contiene un simple DIV de color verde y bordes rojos con una imagen dentro. Al cargar se asigna el evento de cambio a pantalla completa para poder detectarlo. Al pulsar la imagen se pone el DIV a pantalla completa, y se muestra la detección de este hecho por pantalla. Al pulsar sobre la imagen de nuevo se vuelve al modo normal, pero antes se comprueba que el elemento actual que está a toda pantalla es el DIV y se muestra por pantalla también. Fíjate en como, según el navegador que uses, los bordes del DIV a pantalla completa se ven de modo diferente. Prueba a quitarlo los estilos de pantalla completa que hay en la cabecera para ver el comportamiento por defecto en cada navegador y comprobar las diferencias.

¡Espero que te resulte útil!

José Manuel Alarcón José Manuel Alarcón
Fundador de campusMVP.es, el proyecto de referencia en formación on-line para programadores en lengua española. Autor de varios libros y cientos de artículos. Galardonado como MVP de Microsoft desde 2004. Gallego de Vigo, amante de la ciencia y la tecnología, la música y la lectura. Ayudando a la gente en Internet desde 1996.
Descarga GRATIS mi último libro (no técnico): "Tres Monos, Diez Minutos".
Banner

Comentarios (6) -

Spain pregunton

Muy útil !

Responder

Peru m.globalhub.pe

Excelente post saludos!

Responder

Spain Novolatil

Estoy probando el ejemplo de la API que se muestra en este artículo y no me funciona en Safari a alguien más le pasa?

Responder

Colombia andres zapata

gracias por su aporte, pero de todas las maneras que he encontrado para fullscreen, no se puede seguir navegando porque lo saca de la pantalla completa.

Responder

A mi me funciona en todos los navegadores pero en las tabletas no detecta el objeto sobre el que pulso en los PC para que la pantalla sea completa.
Que habría que retocar?

Responder

Hola, puedes decirme como seria para abrir una url en vez de una imgen.

Por ejemplo como seria para abir la www.google.es ???

Responder

Agregar comentario