Agregar fullscreen a distintos elementos

publicado en la categoría JavaScript
Mostrar contenido en pantalla completa no es algo exclusivo de los videos incrustados ya que puede hacerse sobre cualquier otro contenido aunque siempre veremos la advertencia del navegador que nos avisa que esta opción está en uso y que podemos volver atrás utilizando la tecla ESC.

Cualquiera que haya visto un video incrustado en una página web habrá visto que un ícono nos permite verlo en modo pantalla completa siempre que esta se haya habilitado con el atributo allowfullscreen o sus distintas variantes como webkitallowfullscreen o mozallowfullscreen:

<iframe width="560" height="315" src="https://www.youtube.com/embed/TOywUUqDuBE" allowfullscreen></iframe>

Esta es una opción también podemos verla en etiquetas HTML tales como video ya que por defecto, es parte de los controles:

Pero mostrar contenido en pantalla completa no es algo exclusivo de los videos ya que puede hacerse sobre cualquier otro contenido aunque siempre veremos la advertencia del navegador que nos avisa que esta opción está en uso y que podemos volver atrás utilizando la tecla ESC:

Si uno busca información en la web verá muchas contradicciones; es probable que esto se deba a que las funciones internas que manejan la pantalla completa están cambiando constantemente pero aún así, es confuso.

Para menejar esta opción debemos utilizar JavaScript y ahí nos encontramos con el primer problema, las funciones aún no están estandarizadas y cada navegador utiliza las suyas así que hay que anteponerles los prefijos correspondientes (-moz, -webkit y -ms); las funciones genéricas que necesitamos son tres:

fullscreenElement() devuelve true si el elemento está en pantalla completa
requestFullscreen() muestra al elemento en pantalla completa
exitFullscreen() cancela el modo pantalla completa (alias cancelFullScreen)

Para manejar eso lo mejor es crear una función genérica que ya está estandarizada y contempla las variantes de los distintos navegadores. En este caso la función recibirá como parámetro el valor del atributo id que deseemos mostrar:

function FS(id){
	if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement){
		// cerramos el modo pantalla completa
		if (document.exitFullscreen){
			document.exitFullscreen();
		} else if (document.mozCancelFullScreen){
			document.mozCancelFullScreen();
		} else if (document.webkitExitFullscreen){
			document.webkitExitFullscreen();
		} else if (document.msExitFullscreen){
			document.msExitFullscreen();
		}
	} else {
		// abrimos el modo pantalla completa para un cierto elemento
		var el = $('#'+id).get(0);
		if (el.requestFullscreen){
			el.requestFullscreen();
		} else if (el.mozRequestFullScreen){
			el.mozRequestFullScreen();
		} else if (el.webkitRequestFullscreen) {
			el.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
		} else if (el.msRequestFullscreen){
			el.msRequestFullscreen();
		}
	}
}

Este sería el HTML del ejemplo básico:

<div id="demo1" class="demo">
	<iframe src="url_pagina"></iframe>
	<button class="full" contenedor="demo1">texto botón</button>
</div>

En todos los casos, utilizaremos un botón que ejecutará la función genérica al cual le adosamos un atributo personal que identificará el contenedor:

$(document).on("click", ".full", function(){
	var idELEMENTO = $(this).attr("contenedor");
	FS(idELEMENTO);
});

Si se trata de elementos sencillos que sólo deben ampliarse, no necesitamos nada más pero, podemos aprovechar la pseudo-clase :full-screen que nos permite detectar si un elemento se encuentra en pantalla completa y, de ese modo modificar algunas de sus características. Lamentablemente, esta pseudo-clase aún no está estandarizada y también requiere prefijos así que debemos repetir las definiciones para que funcionen en todos los navegadores.

Por ejemplo, vamos a ocultar el botón

/* *******
en modo pantalla completa estableceremos el ancho y alto del elemento al máximo disponible
esto lo hacemos porque a veces Chrome no parece entenderlo
******* */
.demo:-moz-full-screen {height:100%;width:100%;}
.demo:-webkit-full-screen {height:100%;width:100%;}
.demo:-ms-fullscreen {height:100%;width:100%;}

/* *******
establecemos las características del botón
y lo ocultaremos cuando esta en pantalla completa
******* */
.demo button {display: block;margin: 1em auto;}
.demo:-moz-full-screen button {display:none;}
.demo:-webkit-full-screen button {display:none;}
.demo:-ms-fullscreen button {display:none;}

/* *******
cualquier elemento interno permanecerá oculto
hasta hacerlo visible cuando se esta en pantalla completa
******* */
.demo div {display:none;}
.demo:-moz-full-screen div {display:block;height: 100%;width: 100%;}
.demo:-webkit-full-screen div{display:block;height: 100%;width: 100%;}
.demo:-ms-fullscreen div {display:block;height: 100%;width: 100%;}

Otro ejemplo; en este caso el contenido a mostrar en modo pantalla lo creamos de modo dinámico:

<style>
#demo2:-moz-full-screen {background-color:#000;}
#demo2:-webkit-full-screen {background-color:#000;}
#demo2:-ms-fullscreen {background-color:#000;}
#demo2:-moz-full-screen p {
    color: #f00;
    font-size: 20vmin;
    line-height: 1em;
	text-align:center;
    text-shadow: 0.1em 0.1em #fff;
}
#demo2:-webkit-full-screen p {
    color: #f00;
    font-size: 20vmin;
    line-height: 1em;
	text-align:center;
    text-shadow: 0.1em 0.1em #fff;
}
#demo2:-ms-fullscreen p {
    color: #f00;
    font-size: 20vmin;
    line-height: 1em;
	text-align:center;
    text-shadow: 0.1em 0.1em #fff;
}
</style>

<script>
$(document).on("click", ".otrofull", function(){
	var idELEMENTO = $(this).attr("contenedor");
	$("#"+idELEMENTO+" div").html("<p>ejemplo<br>pantalla completa</p>");	
	FS(idELEMENTO);
});
</script>

<div id="demo2">
	<div><!-- acá agregaremos el contenido --></div>
  <button class="otrofull" contenedor="demo2">mostrar ejemplo</button>
</div>

Por defecto, el color de fondo de la pantalla completa será negro a menos que definamos lo contrario ya sea con la propiedad background o utilizando el pseudo-elemento ::backdrop aunque este es experimental y no es soportado por todos los navegadores:

<style>
#demo::backdrop {
	background-color: steelblue;
}