<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es_ES"><generator uri="https://jekyllrb.com/" version="4.3.2">Jekyll</generator><link href="https://www.manualweb.net/feed/html5.xml" rel="self" type="application/atom+xml" /><link href="https://www.manualweb.net/" rel="alternate" type="text/html" hreflang="es_ES" /><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/feed/html5.xml</id><title type="html">Manual Web | Html5</title><subtitle>Tutoriales de programación en español.
</subtitle><author><name>manual_web</name></author><entry><title type="html">WebStorage</title><link href="https://www.manualweb.net/html5/webstorage/" rel="alternate" type="text/html" title="WebStorage" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/webstorage</id><content type="html" xml:base="https://www.manualweb.net/html5/webstorage/"><![CDATA[<p>El <strong>API WebStorage</strong> nos permite almacenar elementos clave/valor de una forma sencilla en la memoria del navegador y que estos elementos estén disponibles a lo largo de la sesión de un usuario. Esto nos evita la necesidad de utilizar <strong>cookies</strong>.</p>

<p>Tenemos dos tipos de almacenamiento en los navegadores:</p>

<ul>
  <li>sessionStorage</li>
  <li>localStorage</li>
</ul>

<h3 id="sessionstorage">sessionStorage</h3>
<p>Mantiene un área de almacenamiento para cada uno de los sites mientras dure la sesión del navegador. Es decir, mientras el navegador permanezca abierto. El objeto que lo maneja es <code class="language-plaintext highlighter-rouge">window.sessionStorage</code>.</p>

<h3 id="localstorage">localStorage</h3>
<p>Funciona igual que el sessionStorage pero con la diferencia de que los datos persisten incluso después de cerrar el navegador. El objeto que lo maneja es <code class="language-plaintext highlighter-rouge">window.localStorage</code>.</p>

<h2 id="objeto-storage">Objeto Storage</h2>
<p>Cuando invocamos a cualquiera de los dos tipos de almacenamiento lo que se crea es un objeto <code class="language-plaintext highlighter-rouge">Storage</code>. Sobre el objeto <code class="language-plaintext highlighter-rouge">Storage</code> es dónde podremos almacenar, recuperar o borrar los elementos de la caché.</p>

<p>Con el objeto <code class="language-plaintext highlighter-rouge">Storage</code> podemos hacer múltiples operaciones que vemos a continuación:</p>

<h3 id="tamaño-de-la-storage">Tamaño de la Storage</h3>
<p>Si queremos saber cuál es el tamaño del almacenamiento, es decir, cuántos valores hay almacenados, lo que tenemos es que trabaja con la variable <code class="language-plaintext highlighter-rouge">.length</code>. Esta variable nos devuelve un número con el tamaño.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Tamaño Storage:</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="añadir-un-elemento-al-storage">Añadir un elemento al Storage</h3>
<p>Para añadir un elemento al <code class="language-plaintext highlighter-rouge">Storage</code> utilizamos el método <code class="language-plaintext highlighter-rouge">setItem()</code>. El método <code class="language-plaintext highlighter-rouge">setItem()</code> recibe dos parámetros, por un lado el nombre de la clave y por otro al valor que queremos asociar a la clave.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">localStorage</span><span class="p">.</span><span class="nf">setItem</span><span class="p">(</span><span class="dl">'</span><span class="s1">clave</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">valor</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<p>De esta forma podemos crear algunas claves:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">localStorage</span><span class="p">.</span><span class="nf">setItem</span><span class="p">(</span><span class="dl">'</span><span class="s1">color</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">rojo</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">localStorage</span><span class="p">.</span><span class="nf">setItem</span><span class="p">(</span><span class="dl">'</span><span class="s1">ancho</span><span class="dl">'</span><span class="p">,</span><span class="mi">12</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="recuperar-un-elemento-al-storage">Recuperar un elemento al Storage</h3>
<p>Una vez que tengamos claves en nuestra <code class="language-plaintext highlighter-rouge">Storage</code> podremos recuperar sus valores mediante el nombre de la clave utilizando el método <code class="language-plaintext highlighter-rouge">getItem</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">localStorage</span><span class="p">.</span><span class="nf">getItem</span><span class="p">(</span><span class="dl">'</span><span class="s1">clave</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<p>Así, si queremos recuperar las claves almacenadas anteriormente podemos hacerlo de la siguiente forma:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nf">getItem</span><span class="p">(</span><span class="dl">'</span><span class="s1">color</span><span class="dl">'</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nf">getItem</span><span class="p">(</span><span class="dl">'</span><span class="s1">ancho</span><span class="dl">'</span><span class="p">));</span>
</code></pre></div></div>

<h3 id="eliminar-un-elemento-al-storage">Eliminar un elemento al Storage</h3>
<p>Todo elemento almacenado en la <code class="language-plaintext highlighter-rouge">Storage</code> puede ser eliminado de la misma utilizando el método <code class="language-plaintext highlighter-rouge">removeItem</code> recibiendo el nombre de la clave como parámetro.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">localStorage</span><span class="p">.</span><span class="nf">removeItem</span><span class="p">(</span><span class="dl">'</span><span class="s1">clave</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<p>Vamos a eliminar la variable <em>‘color’</em> que habíamos creado anteriomente de la siguiente manera:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">localStorage</span><span class="p">.</span><span class="nf">removeItem</span><span class="p">(</span><span class="dl">'</span><span class="s1">color</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="vaciar-la-storage">Vaciar la Storage</h3>
<p>Si queremos ser más drásticos y lo que queremos es eliminar todo el contenido de la <code class="language-plaintext highlighter-rouge">Storage</code> recurriremos al método <code class="language-plaintext highlighter-rouge">clear</code>. El método <code class="language-plaintext highlighter-rouge">clear</code> elimina todo el contenido que exista en la <code class="language-plaintext highlighter-rouge">Storage</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">localStorage</span><span class="p">.</span><span class="nf">clear</span><span class="p">();</span>
</code></pre></div></div>

<h3 id="claves-de-los-elementos-de-la-storage">Claves de los elementos de la Storage</h3>
<p>Si desconocemos los nombres de las claves que se han insertado en la <code class="language-plaintext highlighter-rouge">Storage</code> lo que haremos será recurrir al método <code class="language-plaintext highlighter-rouge">key()</code> que nos devuelve el nombre de la clave de la posición pasada como parámetro.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">localStorage</span><span class="p">.</span><span class="nf">key</span><span class="p">(</span><span class="nx">numero</span><span class="p">);</span>
</code></pre></div></div>

<p>Podemos recuperar la clave que está en la segunda posición de la siguiente forma:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">localStorage</span><span class="p">.</span><span class="nf">key</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</code></pre></div></div>

<p>O podemos recuperar todas las claves y valores:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for </span><span class="p">(</span><span class="kd">var</span> <span class="nx">x</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">x</span><span class="o">&lt;</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nf">key</span><span class="p">(</span><span class="nx">x</span><span class="p">)</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">=</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nf">getItem</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nf">key</span><span class="p">(</span><span class="nx">x</span><span class="p">)));</span>
<span class="p">}</span>
</code></pre></div></div>

<blockquote>
  <p>El funcionamiento con <code class="language-plaintext highlighter-rouge">sessionStorage</code> es exactamente el mismo ya que de igual manera utiliza un objeto <code class="language-plaintext highlighter-rouge">Storage</code>. Así que puedes cambiar el valor <code class="language-plaintext highlighter-rouge">localStorage</code> por <code class="language-plaintext highlighter-rouge">sessionStorage</code> y funciona igual.</p>
</blockquote>

<h2 id="storageevent">StorageEvent</h2>
<p>Cuando se produce un cambio en la <code class="language-plaintext highlighter-rouge">Storage</code> tenemos la capacidad de avisar a otros documentos del dominio mediante el <code class="language-plaintext highlighter-rouge">StorageEvent</code>. Este evento es lanzado cada vez que hay un cambio en el <code class="language-plaintext highlighter-rouge">Storage</code> y es gestionado por otros documentos diferentes a dónde se produce el cambio.</p>

<p>Podemos controlar el evento <code class="language-plaintext highlighter-rouge">StorageEvent</code> de la siguiente forma:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">storage</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
  <span class="p">...</span>
<span class="p">},</span> <span class="kc">false</span><span class="p">);</span>
</code></pre></div></div>

<p>Los atributos que recibiremos en el evento y a los que tendremos acceso son:</p>

<h3 id="key">key</h3>
<p>Es una cadena con el nombre de la clave del <code class="language-plaintext highlighter-rouge">Storage</code> que ha cambiado.</p>

<h3 id="newvalue">newValue</h3>
<p>Es una cadena con el valor nuevo que se le ha asignado a la clave.</p>

<h3 id="oldvalue">oldValue</h3>
<p>Es una cadena con el valor original que tenía la clave.</p>

<h3 id="url">url</h3>
<p>Es una URI con la localización del documento que ha efectuado el cambio.</p>

<h3 id="storagearea">storageArea</h3>
<p>El un objeto DOM que representa el valor que ha sido modificado.</p>

<p>De esta manera podemos capturar toda la informacion de un <code class="language-plaintext highlighter-rouge">StorageEvent</code> de la siguiente forma:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">storage</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">key</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">oldValue</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">newValue</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">url</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">storageArea</span><span class="p">));</span>
<span class="p">},</span> <span class="kc">false</span><span class="p">);</span>
</code></pre></div></div>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[El API WebStorage nos permite almacenar elementos clave/valor de una forma sencilla en la memoria del navegador y que estos elementos estén disponibles a lo largo de la sesión de un usuario. Esto nos evita la necesidad de utilizar cookies.]]></summary></entry><entry><title type="html">Vídeo en HTML5</title><link href="https://www.manualweb.net/html5/video-html5/" rel="alternate" type="text/html" title="Vídeo en HTML5" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/video-html5</id><content type="html" xml:base="https://www.manualweb.net/html5/video-html5/"><![CDATA[<h2 id="introducción-al-vídeo-en-html5">Introducción al vídeo en HTML5</h2>

<p>Con los aumentos de los anchos de vanda el uso del vídeo en la web cada vez se extiende más y hoy en día es el contenido más consumido en las páignas web.</p>

<p>Atrás quedaron los días en los que no existían estándares para poder reproducir vídeos por Internet y en los cuales tecnologías como <strong>Flash</strong> o <strong>Silverlight</strong> disponian de este privilegio. Si bien acarreaban otros problemas de portabilidad, seguridad y al fin y al cabo poca integración con los estándares <a href="http://www.manualweb.net/html/">HTML</a> y <a href="http://www.manualweb.net/css/">CSS</a>.</p>

<p>A partir de <a href="http://www.manualweb.net/html5/">HTML5</a> se estándariza el uso del vídeo mediante el elemento <code class="language-plaintext highlighter-rouge">video</code> del lenguaje. De igual manera aparecn un conjunto de APIs que nos permiten interactuar con el contenido que muestra el vídeo.</p>

<p>Si queremos incluir un vídeo en nuestra página <a href="http://www.manualweb.net/html5/">HTML5</a> simplemente tendremos que escribir lo siguiente:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">controls</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<p>Dentro del código tenemos que conocer el significado de sus dos atributos. Por un lado el atributo <code class="language-plaintext highlighter-rouge">src</code> nos sirve para indicar el nombre del fichero que contiene el vídeo que queremos reproducir.</p>

<p>Mientras que por el otro el atributo <code class="language-plaintext highlighter-rouge">controls</code> permite que se muestre un panel de control de reprodución del vídeo, para que se pueda iniciar, parar, adelantar, cambiar el sonido,…</p>

<h2 id="atributos-del-vídeo">Atributos del vídeo</h2>
<p>Para poder manipular el vídeo, la forma en la que se muestra,… el elemento <code class="language-plaintext highlighter-rouge">video</code> de <a href="http://www.manualweb.net/html5/">HTML5</a> nos ofrece diferentes atributos. Revisemos para que sirven.</p>

<h3 id="fichero-del-vídeo">Fichero del vídeo</h3>
<p>Para poder indicar dónde está el fichero que contiene el vídeo deberemos de utilizar el atributo <code class="language-plaintext highlighter-rouge">src</code>. Este atributo recibirá como valor el nombre del fichero.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">controls</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<h3 id="ancho-y-alto-del-vídeo">Ancho y alto del vídeo</h3>
<p>Aunque como todo elemento <a href="http://www.manualweb.net/html/">HTML</a> podemos modificar la apariencia mediante el lenguaje <a href="http://www.manualweb.net/css/">CSS</a>, el elemento vídeo nos ofrece los atributos <code class="language-plaintext highlighter-rouge">widht</code> y <code class="language-plaintext highlighter-rouge">height</code> para poder definir el ancho y alto del vídeo respetivamente.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">width=</span><span class="s">"600"</span> <span class="na">height=</span><span class="s">"400"</span> <span class="na">controls</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<h3 id="inicio-automático-del-vídeo">Inicio automático del vídeo</h3>
<p>Si queremos que el vídeo se inicie de forma automática una vez que se carge el documento <a href="http://www.manualweb.net/html5/">HTML5</a> deberemos de utilizar el atributo <code class="language-plaintext highlighter-rouge">autoplay</code>.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">autoplay</span> <span class="na">controls</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<h3 id="vídeo-en-bucle">Vídeo en bucle</h3>
<p>En el caso de que queramos que el vídeo se reproduzca en bulce una y otra vez usaremos el atributo <code class="language-plaintext highlighter-rouge">loop</code>.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">autoplay</span> <span class="na">loop</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<h3 id="vídeo-sin-sonido">Vídeo sin sonido</h3>
<p>Otra opción es que el vídeo se ejecute sin sonido. Esto lo conseguimos apoyándonos en el atributo <code class="language-plaintext highlighter-rouge">muted</code>.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">autoplay</span> <span class="na">muted</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<h3 id="cartel-del-vídeo">Cartel del vídeo</h3>
<p>Antes de que se inicie el vídeo podemos poner una imagen de muestra (o cartel). Para ello vamos a utilizar el atributo <code class="language-plaintext highlighter-rouge">poster</code>. El atributo <code class="language-plaintext highlighter-rouge">poster</code> recibirá una URL con el nombre del fichero que queremos utilizar como cartel del vídeo.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">controls</span> <span class="na">poster=</span><span class="s">"mivideo.png"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<p>Si hemos utilizado el atributo <code class="language-plaintext highlighter-rouge">autoplay</code> no se verá el cartel del vídeo.</p>

<h3 id="precargar-el-vídeo">Precargar el vídeo</h3>
<p>Los vídeos suelen ser ficheros que tienen un tamño considerable y es por ello que el tiempo de descarga en la web suele ser superior que al contenido textual o gráfico. Es por ello que se puede dar el caso de que se haya cargado el contenido de un documento, pero no el vídeo que incluye.</p>

<p>Para paliar este tema del tamaño podemos precargar el vídeo. En este caso vamos a utilizar el atributo <code class="language-plaintext highlighter-rouge">preload</code>, el cual puede tener tres valores:</p>

<ul>
  <li><strong>‘none’</strong>, no hace buffering del vídeo.</li>
  <li><strong>‘auto’</strong>, hace buffering del vídeo.</li>
  <li><strong>‘metadata’</strong>, hace buffering, pero solo de la metainformación del vídeo.</li>
</ul>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">controls</span> <span class="na">preload=</span><span class="s">"auto"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<h2 id="formatos-de-vídeo">Formatos de Vídeo</h2>

<p>Cada uno de los navegadores es capaz de rederizar un formato de vídeo diferente.</p>

<h3 id="contenedores-de-formato">Contenedores de formato</h3>
<p>Formatos como mp3, mp4 o WebM son conocidos como <strong>contenedores de formato</strong>, ya que contienen diferentes partes que permiten que se componga un vídeo o canción.</p>

<h4 id="webm">WebM</h4>
<p>El contenedor <strong>WebM</strong> utiliza formatos <strong><em>Ogg Vorbis</em></strong> para el audio y <strong><em>VP8/VP9</em></strong> para el vídeo.</p>

<h4 id="mpeg-4">MPEG 4</h4>
<p>El contenedor <strong>MP4</strong> utiliza formato de audio <strong><em>mp3</em></strong> o <strong><em>aac</em></strong> y un formato de vídeo <strong><em>H.264</em></strong>.</p>

<h4 id="ogg">Ogg</h4>
<p>El contenedor <strong>Ogg</strong> utiliza formatos <strong><em>Ogg Vorbis</em></strong> para el audio y <strong><em>Ogg Theora</em></strong> para el vídeo.</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th>Chrome</th>
      <th>Firefox</th>
      <th>Internet Explorer</th>
      <th>Opera</th>
      <th>Safari</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>WebM</td>
      <td>6.0</td>
      <td>4.0</td>
      <td>9.0</td>
      <td>10.60</td>
      <td>3.1</td>
    </tr>
    <tr>
      <td>MPEG 4</td>
      <td> </td>
      <td> </td>
      <td>x</td>
      <td>x</td>
      <td> </td>
    </tr>
    <tr>
      <td>Ogg</td>
      <td>x</td>
      <td>x</td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
  </tbody>
</table>

<p>Estos <strong>contenedores de formato</strong> lo que hacen es comprimir el vídeo y audio en ficheros manejables.</p>

<p>Los navegadores utilizan los <strong>codecs</strong> para poder descomprimir el contenido de los contenedores y poder reproducir el vídeo y audio. Si el navegador no tiene un <strong>codec</strong> que soporte el formato, no se podrá reproducir el vídeo y/o audio.</p>

<h2 id="múltiples-orígenes-y-formatos-del-vídeo">Múltiples orígenes y formatos del vídeo</h2>

<p>Esta situación que nos obliga a tener diferentes contenedores de formato atendiendo al navegador hace que nuestros documentos <a href="http://www.manualweb.net/html5/">HTML5</a> tengan que permitir cargar varios ficheros en varios formatos.</p>

<p>Esto lo coseguimos mediante el elemento <code class="language-plaintext highlighter-rouge">source</code>. El elemento <code class="language-plaintext highlighter-rouge">source</code> es un elemento anidado al elemento <code class="language-plaintext highlighter-rouge">video</code> y nos sirve para enlazar diferentes ficheros de vídeo en formatos diferentes.</p>

<p>La estructura del elemento <code class="language-plaintext highlighter-rouge">source</code> es la siguiente:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">controls</span><span class="nt">&gt;</span>
  <span class="nt">&lt;source</span> <span class="na">src=</span><span class="s">"mivideo.mp4"</span> <span class="na">type=</span><span class="s">"video/mp4"</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;source</span> <span class="na">src=</span><span class="s">"mivideo.webm"</span> <span class="na">type=</span><span class="s">"video/webm"</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;p&gt;</span>Su navegador no soporta vídeos HTML5.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<p>A la hora de renderizar el vídeo, el navegador irá recorriendo los diferentes formatos hasta que encuentre uno que pueda reproducir.</p>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[Introducción al vídeo en HTML5]]></summary></entry><entry><title type="html">URLs HTML5</title><link href="https://www.manualweb.net/html5/urls-html5/" rel="alternate" type="text/html" title="URLs HTML5" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/urls-html5</id><content type="html" xml:base="https://www.manualweb.net/html5/urls-html5/"><![CDATA[<p>Aquí recojo una serie de URLs sobre <a href="http://www.manualweb.net/html5/">HTML5</a> que pueden ser de interés.</p>

<h2 id="generales">Generales</h2>

<ul>
  <li><a href="https://developer.mozilla.org/es/docs/HTML/HTML5">HTML5 Guide</a> de Mozilla Developer Network (MDN). <em>-español-</em></li>
</ul>

<h2 id="especificación-html5">Especificación HTML5</h2>

<ul>
  <li><a href="https://www.w3.org/TR/html5/">Especificación HTML 5.2</a> por la W3C. <em>-inglés-</em></li>
  <li><a href="https://html.spec.whatwg.org/">Especificación HTML “viva”</a> por Web Hypertext Application Technology Working Group (WHATWG). <em>-inglés-</em></li>
</ul>

<h2 id="canvas">Canvas</h2>
<ul>
  <li><a href="https://www.html5canvastutorials.com/">Tutorial sobre el Canvas</a> <em>-inglés-</em></li>
  <li><a href="http://www.dbp-consulting.com/tutorials/canvas/CanvasArcTo.html">Explicación de Uso del ArcTo</a> <em>-inglés-</em></li>
</ul>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[Aquí recojo una serie de URLs sobre HTML5 que pueden ser de interés.]]></summary></entry><entry><title type="html">Modo Offline</title><link href="https://www.manualweb.net/html5/modo-offline/" rel="alternate" type="text/html" title="Modo Offline" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/modo-offline</id><content type="html" xml:base="https://www.manualweb.net/html5/modo-offline/"><![CDATA[<p>Aunque a los inicios todo agente de usuario que estuviese en Internet se suponía que iba a estar constantemente conectado a la red, el paso del tiempo nos ha demostrado que en ciertas circustancias el agente de usuario estará desconectado y por lo tanto en modo <strong>offline</strong>.</p>

<p>La idea es que aunque el agente de usuario esté <strong>offline</strong> consigamos darle una misma experiencia de usuario que en online o al menos que afecte lo menos posible. Por ejemplo, si el usuario está realizando acciones, estas pueden ser encoladas para ser tratadas posteriormente o podemos recurrir a elementos que estén almacenados en el cliente para poder dar una respuesta.</p>

<p>Es por ello que en <a href="http://www.manualweb.net/html5/">HTML5</a> aparece la capacidad de detectar si el usuario está <strong>online</strong> u <strong>offline</strong> para gestionar las expectativas del mismo.</p>

<p>Así tenemos un API en <a href="http://www.manualweb.net/html5/">HTML5</a> que nos indica cuando un usuario pasa a estar <strong>offline</strong> y cuando el usuario vuelve a estar <strong>online</strong>.</p>

<h2 id="propiedad-online">Propiedad onLine</h2>
<p>La propiedad que indica si el usuario está <strong>online</strong> u <strong>offline</strong> es <code class="language-plaintext highlighter-rouge">navigator.onLine</code> dónde devolverá <code class="language-plaintext highlighter-rouge">true</code> si el usuario está online y <code class="language-plaintext highlighter-rouge">false</code> si el usuario está offline.</p>

<p>Así que simplemente tendremos que consultar el valor de la propiedad:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if </span><span class="p">(</span><span class="nb">navigator</span><span class="p">.</span><span class="nx">onLine</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">El usuario está online</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>
 <span class="k">else</span>
<span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">El usuario está offline</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="eventos-offline">Eventos Offline</h2>
<p>Cómo el usuario puede cambiar de estado, es decir, en cualquier momento de tiempo y por múltiples circustancias el usuario puede pasar de estar <strong>online</strong> a estar <strong>offline</strong> y viceversa. Bien porque haya perdido la conexión, por que el usuario lo fuerce,…</p>

<p>Para estas situaciones en <a href="http://www.manualweb.net/html5/">HTML5</a> disponemos de dos eventos sobre el elemento <code class="language-plaintext highlighter-rouge">window</code>. Estos son el evento <code class="language-plaintext highlighter-rouge">online</code> cuando el usuario pass a estar <strong>online</strong> y <code class="language-plaintext highlighter-rouge">offline</code> cuando el usuario pasa a estar <strong>offline</strong>.</p>

<p>Así que deberemos de controlar dichos eventos para poder gestionar de forma correcta el modo offline. Para ello nos valemos del método <code class="language-plaintext highlighter-rouge">addEventListener</code> y así gestionar dichos eventos.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">online</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">){</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">type</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">El usuario pasa a esta online</span><span class="dl">"</span><span class="p">);</span>
<span class="p">},</span><span class="kc">false</span><span class="p">);</span>

<span class="nb">window</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">offline</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">type</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">El usuario pasa a esta offline</span><span class="dl">"</span><span class="p">);</span>
<span class="p">},</span><span class="kc">false</span><span class="p">);</span>
</code></pre></div></div>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[Aunque a los inicios todo agente de usuario que estuviese en Internet se suponía que iba a estar constantemente conectado a la red, el paso del tiempo nos ha demostrado que en ciertas circustancias el agente de usuario estará desconectado y por lo tanto en modo offline.]]></summary></entry><entry><title type="html">Media Formats en HTML5</title><link href="https://www.manualweb.net/html5/media-formats/" rel="alternate" type="text/html" title="Media Formats en HTML5" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/media-formats</id><content type="html" xml:base="https://www.manualweb.net/html5/media-formats/"><![CDATA[<h1 id="media-formats">Media Formats</h1>

<p>Los elementos <code class="language-plaintext highlighter-rouge">video</code> y <code class="language-plaintext highlighter-rouge">audio</code> sirven para reproducir ficheros de audio y de vídeo de forma estándar y sin la necesidad de utilizar plugins de reproducción.</p>

<p>Los formatos de video y audio consisten en un contenedor dentro del cual encontramos los streams de datos a repoducir.</p>

<p>El contenedor puede albergar ficheros de video, audio, datos y subtítulos. Junto con el vídeo y el audio nos encontramos los <strong>codecs</strong>.</p>

<p>Un codec es un algoritmo de compresión que nos ayuda a descomprimir y comprimir los ficheros de media.</p>

<p>Cada navegador tiene capacidad para reproducir un tipo u otro de formatos de media. Algunos de estos formatos son estándares y otros son propietarios.</p>

<p>https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats</p>

<h1 id="formatos">Formatos</h1>

<h2 id="webm">WebM</h2>
<p>El formato WebM es una versión restringida del formato de contenedor <strong>Matroska</strong>. El cual utiliza el codec de vídeo <strong>VP8</strong> o <strong>VP9</strong> y el codec de audio <strong>Vorbis</strong> o <strong>Opus</strong>.</p>

<p>Los mime types para el formato <strong>WebM</strong> son:</p>

<ul>
  <li><em>video/webm</em>, para los ficheros de vídeo (y audio) de WebM.</li>
  <li><em>audio/webm</em>, para los ficheros de audio de WebM.</li>
</ul>

<h2 id="ogg-theora-vorbis">Ogg Theora Vorbis</h2>
<p>Es un contenedor de media <strong>Ogg</strong>, el cual contiene un codec de vídeo <strong>Theora</strong> y un codec de audio <strong>Vorbis</strong>. Este contenedor está soportado por Firefox, Chrome y Opera. En algunos casos dentro de Safari (fuera de iOS).</p>

<p>El formato <strong>WebM</strong> tiene mayor compresión que otros formatos como <strong>Ogg</strong> y es por ello que es preferido por los desarrolladores. Si bien se suele utilizar <strong>Ogg</strong> para navegegadores antiguos que no soportan <strong>WebM</strong>.</p>

<p>Los media types para un contenedor <strong>Ogg</strong> son:</p>

<ul>
  <li><em>audio/ogg</em>, para ficheros de audio.</li>
  <li><em>video/ogg</em>, para ficheros de vídeo (y posiblemente audio).</li>
  <li><em>application/ogg</em>, se utiliza en el caso de que no se sepa el contenido del contenedor Ogg.</li>
</ul>

<h2 id="ogg-opus">Ogg Opus</h2>
<p>En este caso tenemos el contenedor <strong>Ogg</strong> utilizando el codec de audio <strong>Opus</strong>.</p>

<p>El media type para el contenedor <strong>Ogg Opus</strong> es *audio/ogg; codecs=opus**.</p>

<h2 id="ogg-flac">Ogg FLAC</h2>
<p>Es un contenedor <strong>Ogg</strong> que utiliza un codec de audio <strong>FLAC</strong>.</p>

<h2 id="mp4-h264-aac-o-mp3">MP4 H.264 (AAC o MP3)</h2>
<p>El contenedor <strong>MP4</strong> está formato por un codec de vídeo <strong>H.264</strong> y un codec de audio <strong>AAC</strong>.</p>

<p>Este formato es soportado por Internet Explorer, Safari y Chrome.</p>

<p>Podemos encontar el contenedor <strong>MP4</strong> con un codec de audio <strong>MP3</strong>. Si bien en este caso este codec solo es soportado por Internet Explorer y Chrome.</p>

<p>Los formatos *mpeg** están patentados y no tienen licencias gratuitas para su distribución.</p>

<h2 id="mp4-flac">MP4 FLAC</h2>
<p>Es un contenedor <strong>MP4</strong> pero que tiene un codec de audio <strong>FLAC</strong>.</p>

<h1 id="contenedores-de-audio">Contenedores de Audio</h1>

<h2 id="mp3">MP3</h2>
<p>Es un formato de audio. Su media type es <em>audio/mpeg</em>. Necesita de un decoder mp3 para que pueda ser reproducido.</p>

<h2 id="wave-pcm">WAVE PCM</h2>
<p>El formato de contenedor <strong>Wave</strong> tiene el codec de audio <strong>PCM</strong>. Es el conocido como <em>wave codec 1</em>. Las extensiones de estos ficheros son <em>.wav</em>.</p>

<p>Los mime types reconocidos para el formato wave son:</p>

<ul>
  <li>audio/wave</li>
  <li>audio/wav</li>
  <li>audio/x-wav</li>
  <li>audio/x-pn-wav</li>
</ul>

<h2 id="flac">FLAC</h2>
<p>El contenedor de formato <strong>FLAC</strong> está compuesto por el codec de audio <strong>FLAC</strong>. Suelen tener la extensión <em>.flac</em>.</p>

<p>Los mime types para el formato <strong>FLAC</strong> son:</p>

<ul>
  <li>audio/flac</li>
  <li>audio/x-flac</li>
</ul>

<h1 id="compatibilidad-codecs">Compatibilidad Codecs</h1>
<p>Como hemos visto la compatibilidad de los codec varia dependiendo del navegador. Es por ello que puedes comprobar la compatibilidad de un determinado codec con un navegador en <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats#Browser_compatibility">Supported Media Formats de MDN</a>.</p>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[Media Formats]]></summary></entry><entry><title type="html">Introducción a IndexedDB</title><link href="https://www.manualweb.net/html5/introduccion-indexedDB/" rel="alternate" type="text/html" title="Introducción a IndexedDB" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/introduccion-indexeddb</id><content type="html" xml:base="https://www.manualweb.net/html5/introduccion-indexedDB/"><![CDATA[<p><strong>IndexedDB</strong> es un API de bajo nivel para poder almacenar datos estructurados en la parte del cliente. Estos datos pueden ser también ficheros o blobs. <strong>IndexedDB</strong> utiliza índices para poder realizar búsquedas de alto rendimiento.</p>

<p>Aunque existen otros mecanismos de almacenamiento en el cliente, como pueden ser las <strong>Cookies</strong> o la <a href="/html5/webstorage/"><strong>API WebStorage</strong></a> estos presentan unas limitaciones de tamaño, unos <em>4kb</em> en las <strong>Cookies</strong> y hasta los <em>10Mb</em> en la <a href="/html5/webstorage/"><strong>API WebStorage</strong></a>. Sin embargo la base de datos <strong>IndexedDB</strong> nos permite almacenar cantidades mayores de datos, llegando en algunas implementaciones a los <em>250Mb</em>.</p>

<h2 id="características-de-indexeddb">Características de IndexedDB</h2>
<p>Las principales características que definen a IndexedDB son:</p>

<h3 id="almacena-pares-clavevalor">Almacena pares clave/valor</h3>
<p><strong>IndexedDB</strong> es un almacén de objetos, es decir que podemos almacenar cualquier tipo de objeto dentro de la base de datos. Si bien cada objeto tiene asociada una <strong>clave</strong> que lo identificará de una forma única. A dicha <strong>clave</strong> va asociado el <strong>valor</strong> que es el objeto en sí.</p>

<h3 id="es-asíncrona">Es Asíncrona</h3>
<p>Para no penalizar el rendimiento del cliente, la base de datos <strong>IndexedDB</strong> funciona de forma asíncrona. Esto nos permite almacenar grandes cantidades de datos sin que estemos penalizando a la respuesta de renderizado del navegador. Cuando veamos el API de <strong>IndexedDB</strong> veremos que las respuestas de sus métodos son asíncronas. Si bien podemos encontrar algunas <a href="https://github.com/jakearchibald/idb">implementaciones de <strong>IndexedDB</strong> utilizando promesas</a>.</p>

<h3 id="soporta-transacciones">Soporta Transacciones</h3>
<p>Las operaciones que realicemos sobre <strong>IndexedDB</strong> se realizan mediante transacciones (incluidas las lecturas). Es decir, podremos deshacer ciertas operaciones en el caso de que se produzca un fallo dentro de la transacción.</p>

<h3 id="restricción-de-dominio">Restricción de Dominio</h3>
<p>Una base de datos <strong>IndexedDB</strong> solo pertenece a un dominio, es por ello que solo podremos acceder al contenido de la información que alberga cuando lo operemos desde el dominio al que corresponde. De esta manera mantenemos la seguridad de los datos almacenados.</p>

<h3 id="gran-capacidad-de-almacenamiento">Gran Capacidad de Almacenamiento</h3>
<p>Ya hemos visto que <strong>IndexedDB</strong> viene a paliar los límites de almacenamiento que aparecen en las <strong>Cookies</strong> o en la <a href="/html5/webstorage/"><strong>API WebStorage</strong></a>, llegando a poder almacenar hasta <em>250Mb</em>.</p>

<h3 id="soporte-almacenamiento-binario">Soporte Almacenamiento Binario</h3>
<p>Dentro de <strong>IndexedDB</strong> podemos almacenar contenido binario como un ArrayBuffer de objetos u objetos Blob.</p>

<h2 id="conceptos-básicos">Conceptos Básicos</h2>
<p>Cuando vayamos a manejar una base de datos <strong>IndexedDB</strong> debemos de manejar una serie de conceptos u elementos básicos de la misma:</p>

<ul>
  <li>Base de Datos: <code class="language-plaintext highlighter-rouge">IDBDatabase</code></li>
  <li>Almacén de Objetos: <code class="language-plaintext highlighter-rouge">IDBObjectStore</code></li>
  <li>Índices: <code class="language-plaintext highlighter-rouge">IDBIndex</code></li>
  <li>Transacciones: <code class="language-plaintext highlighter-rouge">IDBTransaction</code></li>
  <li>Consultas: <code class="language-plaintext highlighter-rouge">IDBRequest</code></li>
  <li>Punteros o Cursores: <code class="language-plaintext highlighter-rouge">IDBCursor</code></li>
  <li>Rango de Clave: <code class="language-plaintext highlighter-rouge">IDBKeyRange</code></li>
</ul>

<h3 id="base-de-datos-idbdatabase">Base de Datos: IDBDatabase</h3>
<p>La base de datos se representa mediante un objeto <code class="language-plaintext highlighter-rouge">IDBDatabase</code>. Por cada dominio podremos crear tantas bases de datos como queramos.</p>

<p>La base de datos se identifica por un <em>nombre de base de datos</em> y una <em>versión</em>. Solo puede existir una única <em>versión</em> a la vez. Es por ello que si queremos cambiar de <em>versión</em> deberemos de realizar una migración de los datos de la versión actual.</p>

<h3 id="almacén-de-objetos-idbobjectstore">Almacén de Objetos: IDBObjectStore</h3>
<p>El almacén de objetos, representado por el objeto <strong>IDBObjectStore</strong> es el conjunto de datos relativos a un concepto. Sería similar a una tabla dentro de una base de datos relacional.</p>

<p>Dentro del almacén de objetos encontraremos los datos. Cada uno de los datos es un registro. Lo que caracteriza a cada registro es que tiene una clave asociada.</p>

<h3 id="índices-idbindex">Índices: IDBIndex</h3>
<p>Los índices nos permiten optimizar las búsquedas dentro de <strong>IndexedDB</strong>. La base de datos se mantendrá ordenada por los índices que definamos. El objeto <code class="language-plaintext highlighter-rouge">IDBIndex</code> nos ayuda a definir los índices.</p>

<p>Es importante definir los índices mediante <code class="language-plaintext highlighter-rouge">IDBIndex</code> ya que será necesario para poder realizar búsquedas con filtros.</p>

<h3 id="transacciones-idbtransaction">Transacciones: IDBTransaction</h3>
<p>Como hemos comentado el acceso de lectura y escritura sobre la base de datos se hace mediante transacciones. El objeto que representa una transacción es <code class="language-plaintext highlighter-rouge">IDBTransaction</code>. La transacción nos ofrecerá métodos <code class="language-plaintext highlighter-rouge">error</code>, <code class="language-plaintext highlighter-rouge">abort</code> y <code class="language-plaintext highlighter-rouge">complete</code> para poder gestionar el resultado de la transacción.</p>

<h3 id="consultas-idbrequest">Consultas: IDBRequest</h3>
<p>Las consultas que realicemos sobre la base de datos <strong>IndexedDB</strong> las vamos a gestionar mediante un objeto <code class="language-plaintext highlighter-rouge">IDBRequest</code>. Tendremos un evento <code class="language-plaintext highlighter-rouge">onsuccess</code> que nos avisará cuando la consulta haya sido satisfactoria.</p>

<h3 id="punteros-o-cursores-idbcursor">Punteros o Cursores: IDBCursor</h3>
<p>En el caso de que la consulta sobre la base de datos <strong>IndexedDB</strong> devuelva un conjunto múltiples de datos deberemos de manejar un cursor (o puntero) para poder recorrer el conjunto de objetos devueltos como respuesta. El objeto que nos ayuda a manejar los cursores es <code class="language-plaintext highlighter-rouge">IDBCursor</code>.</p>

<h3 id="rango-de-clave-idbkeyrange">Rango de Clave: IDBKeyRange</h3>
<p>Si queremos gestionar un subconjuto de los elementos almacenados deberemos de apoyarnos en los índices, en concreto en el elemento <code class="language-plaintext highlighter-rouge">IDBKeyRange</code>. El elemento <code class="language-plaintext highlighter-rouge">IDBKeyRange</code> nos ayuda a establecer filtros sobre los datos para que el contenido devuelto solo corresponda a un rango.</p>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[IndexedDB es un API de bajo nivel para poder almacenar datos estructurados en la parte del cliente. Estos datos pueden ser también ficheros o blobs. IndexedDB utiliza índices para poder realizar búsquedas de alto rendimiento.]]></summary></entry><entry><title type="html">Manual HTML5</title><link href="https://www.manualweb.net/html5/" rel="alternate" type="text/html" title="Manual HTML5" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/index</id><content type="html" xml:base="https://www.manualweb.net/html5/"><![CDATA[<p>Dentro de este <strong>Tutorial Html5</strong> podrás encontrar los siguientes contenidos:</p>

<p><strong>Introducción HTM5</strong></p>
<ul>
  
    
    
    <li><a href="/html5/introduccion-html5/">Introducción HTML5</a></li>
  
    
    
    <li><a href="/html5/documento-html5/">Documento HTML5</a></li>
  
    
    
    <li><a href="/html5/semantica-html5/">Semántica HTML5</a></li>
  
</ul>

<p><strong>Formularios HTM5</strong></p>
<ul>
  
    
    
    <li><a href="/html5/formularios-html5/">Formularios HTML5</a></li>
  
    
    
    <li><a href="/html5/formularios-elementos-input/">Elementos Input</a></li>
  
    
    
    <li><a href="/html5/formularios-datalist/">DataList</a></li>
  
    
    
    <li><a href="/html5/formularios-barras-progreso/">Barras de Progreso</a></li>
  
    
    
    <li><a href="/html5/formularios-output/">Elemento Output</a></li>
  
    
    
    <li><a href="/html5/formularios-validacion/">Validación formularios</a></li>
  
</ul>

<p><strong>Multimedia HTM5</strong></p>
<ul>
  
    
    
    <li><a href="/html5/video-html5/">Vídeo en HTML5</a></li>
  
    
    
    <li><a href="/html5/media-formats/">Media Formats en HTML5</a></li>
  
</ul>

<p><strong>Gráficos HTM5</strong></p>
<ul>
  
    
    
    <li><a href="/html5/canvas/">Canvas HTML5</a></li>
  
    
    
    <li><a href="/html5/canvas-texto/">Texto en Canvas</a></li>
  
</ul>

<p><strong>Almacenamiento &amp; Offline</strong></p>
<ul>
  
    
    
    <li><a href="/html5/modo-offline/">Modo Offline</a></li>
  
    
    
    <li><a href="/html5/webstorage/">WebStorage</a></li>
  
</ul>

<p><strong>IndexedDB</strong></p>
<ul>
  
    
    
    <li><a href="/html5/introduccion-indexedDB/">Introducción a IndexedDB</a></li>
  
</ul>

<p><strong>Rendimiento &amp; Integración</strong></p>
<ul>
  
    
    
    <li><a href="/html5/fullscreen-api/">API Fullscreen</a></li>
  
    
    
    <li><a href="/html5/history-api/">History API</a></li>
  
</ul>

<p><strong>Contenido de Apoyo</strong></p>
<ul>
  
    
    
    <li><a href="/html5/urls-html5/">URLs HTML5</a></li>
  
</ul>

<h2 id="descargar-manual-html5">Descargar Manual HTML5</h2>

<p>Puedes descargarte nuestro <a href="/html5/descargar-manual-html5/">Manual HTML5 en formato PDF</a>. El manual se encuentra en continua revisión, de forma automática la URL proporcionada contendrá siemprre la última versión del <strong>Tutorial HTML5</strong>.</p>

<h2 id="ejemplos-manual-html5">Ejemplos Manual HTML5</h2>

<p>A lo largo del <strong>Tutorial HTML5</strong> se van explicando una serie de ejemplos. Podéis descargaros los ejemplos del <strong>Tutorial HTML5</strong> desde el GitHub de Manual Web.</p>

<p>Si os gusta el contenido del material y los ejemplos os agradecemos si nos aportáis una estrella en GitHub.</p>

<p><a class="github-button" href="https://github.com/manualweb/manualweb" data-icon="octicon-star" data-style="mega" aria-label="Star manualweb/manualweb on GitHub">Star</a></p>

<h2 id="más-sobre-el-manual-html5">Más sobre el Manual HTML5</h2>

<p>Todas las preguntas y dudas sobre HTML5 las puedes consultar en el <a href="http://dudasprogramacion.com/html/html5">Foro sobre HTML5</a>. Y puedes echar un ojo a los <a href="http://lineadecodigo.com/categoria/html5/">ejemplos sobre el lenguaje HTML5</a>.</p>

<script id="github-bjs" src="https://buttons.github.io/buttons.js" async="" defer="defer"></script>]]></content><author><name>manual_web</name></author><category term="html5" /><category term="form" /><category term="datalist" /><category term="video" /><category term="audio" /><category term="canvas" /><category term="offline" /><category term="webstorage" /><summary type="html"><![CDATA[Manual HTML5 que nos cuenta las novedades de esta versión de HTML, desde los elementos semáticos, nuevos elementos formularios, audio y vídeo hasta las nuevas WebAPI.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.manualweb.net/img/covers/html5-cover.jpg" /><media:content medium="image" url="https://www.manualweb.net/img/covers/html5-cover.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">History API</title><link href="https://www.manualweb.net/html5/history-api/" rel="alternate" type="text/html" title="History API" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/history-api</id><content type="html" xml:base="https://www.manualweb.net/html5/history-api/"><![CDATA[<p>Aunque ya llevaba tiempo el objeto <code class="language-plaintext highlighter-rouge">history</code> dentro del DOM de los documentos <a href="http://www.manualweb.net/html/">HTML</a>, la llegada de <a href="http://www.manualweb.net/html5/">HTML5</a> refuerza su uso y le incluye nuevos métodos para poder manipularlo.</p>

<p>Pero vayamos viendo poco a poco qué es el <strong>History API</strong> y como podemos manipular el historial de navegación mediante el objeto <code class="language-plaintext highlighter-rouge">history</code>.</p>

<h2 id="operaciones-básicas-history-api">Operaciones Básicas History API</h2>

<p>Lo primero que tenemos que saber es que el historial de navegación es una lista de páginas sobre la que nos podemos mover. Esta lista está compuesta por las últimas páginas web que hayamos visitado.</p>

<p>Por lo tanto, podemos movernos por ella hacia delante, hacía atrás o a un punto en concreto. Siempre teniendo en cuenta que partiremos en la última posición de la lista.</p>

<h3 id="moverse-por-el-historial">Moverse por el historial</h3>
<p>Si querermos movernos por el <strong>History API</strong> de forma sencilla vamos a tener dos métodos: <code class="language-plaintext highlighter-rouge">back()</code> y <code class="language-plaintext highlighter-rouge">forward()</code>.</p>

<p>Mediante el método <code class="language-plaintext highlighter-rouge">back()</code> vamos a movernos hacía atrás en el historial. Bastará con escribir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nf">back</span><span class="p">();</span>
</code></pre></div></div>

<p>Para poder ir a la última página que visitó el usuario con el navegador. Es el mismo efecto que si el usuario pulsase sobre el botón de atrás.</p>

<p>En el caso de que queramos ir adelante en el hitorial deberemos de utilizar <code class="language-plaintext highlighter-rouge">forward()</code>. En este caso deberemos de escribir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nf">forward</span><span class="p">();</span>
</code></pre></div></div>

<p>Para poder ir a la siguiente página que visitó el usuario. Es el mismo efecto que si el usuario pulsase sobre el botón de adelante en el navegador.</p>

<h3 id="ir-a-una-posición-concreta-del-historial">Ir a una posición concreta del historial</h3>
<p>Si no queremos hacer movimiento lineales sobre el historial podemos hacer un movimiento a un punto en concreto del historial. En este caso deberemos de apoyarnos en el método <code class="language-plaintext highlighter-rouge">go()</code>. El método <code class="language-plaintext highlighter-rouge">go()</code> recibe como parámetro la posicines sobre las que nos queremos mover. Es decir, si el número es positivo nos moveremos tantas posiciones adelante como indique el método y si es negativo nos moveremos tantas posiciones atrás como indique el número (en positivo) del método.</p>

<p>La sintaxis del método <code class="language-plaintext highlighter-rouge">go()</code> es:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nf">go</span><span class="p">(</span><span class="nx">numero</span><span class="p">);</span>
</code></pre></div></div>

<p>Así podemos movernos dos posiciones adelante de la actual:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nf">go</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
</code></pre></div></div>

<p>O, por ejemplo, movernos tres posiciones hacía atrás de la posición actual:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nf">go</span><span class="p">(</span><span class="o">-</span><span class="mi">3</span><span class="p">);</span>
</code></pre></div></div>

<p>De esta forma hay una similitu de métodos entre:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nf">go</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>  <span class="c1">// window.history.forward();</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nf">go</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// window.history.back();</span>
</code></pre></div></div>

<h3 id="número-de-elementos-del-historial">Número de elementos del historial</h3>
<p>Una cosa importante a la hora de movernos por el historial mediante el <strong>History API</strong> es saber cuántos elementos hay almacenados en el historial. Esto lo obtendremos mediante la propiedad  <code class="language-plaintext highlighter-rouge">.length</code>:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</code></pre></div></div>

<h2 id="gestionar-estados-history-api">Gestionar Estados History API</h2>
<p>Cuando se pensó inicialmente el objeto <code class="language-plaintext highlighter-rouge">history</code> se trabajaba con la hipótesis de que cada nueva navegación, y por lo tanto carga de página, iba a suponer un nuevo estado dentro del historial. Pero con la aparición de las técnicas <a href="http://www.manualweb.net/ajax/">AJAX</a> (Asynchronous Javascript and XML) llegaron las cargas parciales de las páginas o las modificaciones de los elementos del DOM para proporcionar una experiencia más rica de visualización al usuario.</p>

<p>Es decir, el usuario estaba navegando, pero su historial de navgeación no cambiaba. Por lo cual, si el usuario, habituado a manipular los botones del navegador, realizaba alguna navegación, alteraba por completo la navegación de la aplicación que usaba patrones <a href="http://www.manualweb.net/ajax/">AJAX</a>.</p>

<p>Es por ello que en <a href="http://www.manualweb.net/html5/">HTML5</a> se incrementan las funcionalidades del <strong>History API</strong> y se añade la gestión de estados. De esta forma, cuando se produce una navegación dentro de una aplicación <a href="http://www.manualweb.net/ajax/">AJAX</a> podemos introducir un nuevo estado dentro del historial y así paliar los efectos colaterales que se producen al navegar por el historial.</p>

<p>Estas capacidades de gestión de estados en el <strong>History API</strong> junto con la gestión de los anclas o hash (#) en la URL de la página, permitía que se hiciera una gestión de navegación en aplicaciones <a href="http://www.manualweb.net/ajax/">AJAX</a> satisfactoria.</p>

<p>Si queremos saber información del estado en el que se encuentra el historial nos bastará con escribir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">history</span><span class="p">.</span><span class="nx">state</span><span class="p">));</span>
</code></pre></div></div>

<h3 id="modificar-entradas-en-el-historial">Modificar entradas en el historial</h3>
<p>Si queremos modificar los estados dentro del <strong>History API</strong> tenemos dos métodos: <code class="language-plaintext highlighter-rouge">pushState()</code> para incluir un nuevo estado y <code class="language-plaintext highlighter-rouge">replaceState()</code> para reemplazar un estado ya existente.</p>

<h4 id="pushstate">pushState()</h4>
<p>El método que nos permite añadir un nuevo estado es <code class="language-plaintext highlighter-rouge">pushState()</code>. La estructura de <code class="language-plaintext highlighter-rouge">pushState()</code> es la siguiente:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">history</span><span class="p">.</span><span class="nf">pushState</span><span class="p">(</span><span class="nx">objeto_estado</span><span class="p">,</span> <span class="nx">titulo</span><span class="p">,</span> <span class="nx">url</span><span class="p">);</span>
</code></pre></div></div>

<p>Dónde <strong><em>objeto_estado</em></strong> es un objeto <a href="http://www.manualweb.net/javascript/">Javascript</a> que representa la información del estado que queremos guardar. Cuando navegemos hacía este estado, el evento que gestiona un cambio en el historial disponibilizará esta información. Así en este objeto deberemos de guardar todo aquello que necesitemos para poder recuperar mediante técnicas <a href="http://www.manualweb.net/ajax/">AJAX</a> la representación visual asociada al estado.</p>

<p>Algunos navegadores tiene la limitación de 640Kb de serialización de los objetos que deberemos de tener en cuenta.</p>

<p>El atributo <strong><em>titulo</em></strong> representa el título asociado al estado. Y por último, el atributo <strong><em>URL</em></strong> es la url que se insertará en el hsitorial de navegación, por lo tanto debe de existir dicha URL y puede expresarse de forma relativa o absoluta. Es importante saber que el navegador no cargará la URL cuando ejecutemos un <code class="language-plaintext highlighter-rouge">pushState()</code>.</p>

<p>Así, podemos crear un nuevo estado con el <strong>History API</strong> de la siguiente forma:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">history</span><span class="p">.</span><span class="nf">pushState</span><span class="p">({</span> <span class="na">pagina</span><span class="p">:</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span> <span class="p">},</span> <span class="dl">"</span><span class="s2">Título 1</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">state.html#p1</span><span class="dl">"</span><span class="p">);</span>
</code></pre></div></div>

<p>Vemos que tenemos un objeto <a href="http://www.manualweb.net/javascript/">Javascript</a> en el que solo hemos guardado una propiedad, pero sobre el que podríamos guardar toda la información que se necesite:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> <span class="nl">pagina</span><span class="p">:</span> <span class="dl">"</span><span class="s2">1</span><span class="dl">"</span> <span class="p">}</span>
</code></pre></div></div>

<h4 id="replacestate">replaceState()</h4>
<p>Otro método que tenemos para modificar los estados del historial es <code class="language-plaintext highlighter-rouge">replaceState()</code>. Mediante el método <code class="language-plaintext highlighter-rouge">replaceState()</code> podremos modificar la información asociada al estado actual que tengamos en el historial.</p>

<p>La estructura del método <code class="language-plaintext highlighter-rouge">replaceState()</code> es:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">history</span><span class="p">.</span><span class="nf">replaceState</span><span class="p">(</span><span class="nx">objeto_estado</span><span class="p">,</span> <span class="nx">título</span><span class="p">,</span> <span class="nx">URL</span><span class="p">);</span>
</code></pre></div></div>

<p>Dónde <strong><em>objeto_estado</em></strong> es el nuevo estado a aplicar, <strong><em>título</em></strong> el nuevo título a aplicar y <strong><em>url</em></strong> la nueva URL.</p>

<p>Así, podríamos cambiar el estado actual ejecutando el método <code class="language-plaintext highlighter-rouge">replaceState()</code> de la siguiente forma:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">history</span><span class="p">.</span><span class="nf">replaceState</span><span class="p">({</span> <span class="na">pagina</span><span class="p">:</span> <span class="dl">"</span><span class="s2">2</span><span class="dl">"</span> <span class="p">},</span> <span class="dl">"</span><span class="s2">Título 2</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">state.html#p2</span><span class="dl">"</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="gestionar-eventos-sobre-el-historial">Gestionar eventos sobre el historial</h3>
<p>Lo último que tenemos que saber en la gestión de estados dentro del <strong>History API</strong> es que cuando el usuario navega por el historial, ya sea mediante los métodos <code class="language-plaintext highlighter-rouge">bakc()</code>, <code class="language-plaintext highlighter-rouge">forward()</code>, <code class="language-plaintext highlighter-rouge">go()</code> o con los botones del navegador, se genera un evento <code class="language-plaintext highlighter-rouge">onpopstate</code>.</p>

<p>Controlando el evento <code class="language-plaintext highlighter-rouge">onpopstate</code> podremos realizar las acciones sobre el estado en el que está el navegador. Ya que dicho evento llevará asociado el estado como valor.</p>

<p>Podemos controlar el evento <code class="language-plaintext highlighter-rouge">onpopstate</code> de la siguiente forma:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">onpopstate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{};</span>
</code></pre></div></div>

<p>Así si, por ejemplo, queremos volvar el contenido del estado que se ha quedado al navegar escribiremos lo siguiente:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">onpopstate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">state</span><span class="p">));</span>
  <span class="p">};</span>
</code></pre></div></div>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[Aunque ya llevaba tiempo el objeto history dentro del DOM de los documentos HTML, la llegada de HTML5 refuerza su uso y le incluye nuevos métodos para poder manipularlo.]]></summary></entry><entry><title type="html">API Fullscreen</title><link href="https://www.manualweb.net/html5/fullscreen-api/" rel="alternate" type="text/html" title="API Fullscreen" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/fullscreen-api</id><content type="html" xml:base="https://www.manualweb.net/html5/fullscreen-api/"><![CDATA[<p>El <strong>API Fullscreen</strong> nos permite que un elemento del DOM (y sus descendientes) puedan ser representados a pantalla completa. Lo que permite es visualizar la página eliminando cualquier elemento del navegador (menús, pestañas,…). Con ello podremos poner desde el propio documento a pantalla completa, elementos de vídeo, imágenes,…</p>

<h2 id="métodos-fullscreen-api">Métodos Fullscreen API</h2>
<p>Lo primero que tenemos que conocer son los métodos que nos permite manejar el <strong>API Fullscreen</strong>. Los métodos que nos permiten visualizar un elemento a pantalla completa son:</p>

<ul>
  <li>Document.exitFullscreen()</li>
  <li>Element.requestFullscreen()</li>
</ul>

<h3 id="requestfullscreen">requestFullscreen()</h3>
<p>Solicita al agente de usuario (que normalmente será el navegador) el poder visualizar un elemento a pantalla completa. El método <code class="language-plaintext highlighter-rouge">Element.requestFullscreen</code> devolverá una promesa o <code class="language-plaintext highlighter-rouge">Promise</code> que será resuelta una vez que se activa el modo pantalla completa.</p>

<h3 id="exitfullscreen">exitFullscreen()</h3>
<p>Solicita al agente de usuario el salir del modo de visualización a pantalla completa para volver a una visualización normal. El método <code class="language-plaintext highlighter-rouge">Document.exitFullscreen</code> devolverá una promesa o <code class="language-plaintext highlighter-rouge">Promise</code> que será resuelta una vez que el modo pantalla completa se ha deshabilitado.</p>

<h3 id="poner-el-documento-a-pantalla-completa">Poner el documento a pantalla completa</h3>
<p>Una vez que conocemos los métodos que nos permiten manejar la pantalla completa del <strong>API Fullscreen</strong> vamos a ver cómo podemos poner un documento y un elemento a pantalla completa.</p>

<p>Lo que vamos a crear es una función sobre la que apoyarnos y lanzar la pantalla compelta:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">getFullscreen</span><span class="p">(</span><span class="nx">element</span><span class="p">){</span>
  <span class="k">if</span><span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">requestFullscreen</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">element</span><span class="p">.</span><span class="nf">requestFullscreen</span><span class="p">();</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">mozRequestFullScreen</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">element</span><span class="p">.</span><span class="nf">mozRequestFullScreen</span><span class="p">();</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">webkitRequestFullscreen</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">element</span><span class="p">.</span><span class="nf">webkitRequestFullscreen</span><span class="p">();</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">msRequestFullscreen</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">element</span><span class="p">.</span><span class="nf">msRequestFullscreen</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Vemos que lo primero que hacemos es comprobar si el elemento sobre el que queremos poner la pantalla completa soporta esta capacidad. Esta información nos la da la propiedd <code class="language-plaintext highlighter-rouge">requestFullscreen</code>. En el caso de que si que se soporte nos valdrá con invocar al método <code class="language-plaintext highlighter-rouge">requestFullscreen</code> sobre el elemento. En ste caso nos apoyamos en los hacks de los diferentes navegadores.</p>

<p>Ahora simplemente tendremos que llamar a nuestro método <code class="language-plaintext highlighter-rouge">getFullscreen</code> pasándole el elemento que representa el documento completo <code class="language-plaintext highlighter-rouge">document.documentElement</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">getFullscreen</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">documentElement</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="elemento-en-pantalla-completa">Elemento en pantalla completa</h3>
<p>Ahora que hemos visto cómo poner el documento a pantalla completa, vamos a pasar a realizar la misma acción con un elemento. En este caso nos vamos a apoyar en un elemento vídeo para enseñar cómo podemos poner un elemento en pantalla completa. Lo primero que haremos será crear el elemento vídeo en nuestra página:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;video</span> <span class="na">id=</span><span class="s">"mivideo"</span> <span class="na">src=</span><span class="s">"ejemplo-video.ogv"</span> <span class="na">controls</span><span class="nt">&gt;</span>
  Tu navegador no soporta el elemento <span class="nt">&lt;code&gt;</span>video<span class="nt">&lt;/code&gt;</span>.
<span class="nt">&lt;/video&gt;</span>
</code></pre></div></div>

<p>Lo siguiente que haremos será invocar al método <code class="language-plaintext highlighter-rouge">getFullscreen</code> que hemos definido. Pero en este caso llamaremos al elemento vídeo. Para poder obtener el elemento vídeo tendremos que utilizar el método <code class="language-plaintext highlighter-rouge">getElementById</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">getFullscreen</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">mivideo</span><span class="dl">"</span><span class="p">));</span>
</code></pre></div></div>

<h3 id="salir-de-la-pantalla-completa">Salir de la pantalla completa</h3>
<p>Para poder codificar el salir de una pantalla completa debería de bastar con utilizar el método <code class="language-plaintext highlighter-rouge">exitFullscreen</code>, pero hay que tener en cuenta los diferentes navegadores. Es por ello que es buena idea tener un método que valide los diferentes métodos.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">exitFullscreen</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">if</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">exitFullscreen</span><span class="p">)</span> <span class="p">{</span>
    <span class="nb">document</span><span class="p">.</span><span class="nf">exitFullscreen</span><span class="p">();</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">mozCancelFullScreen</span><span class="p">)</span> <span class="p">{</span>
    <span class="nb">document</span><span class="p">.</span><span class="nf">mozCancelFullScreen</span><span class="p">();</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">webkitExitFullscreen</span><span class="p">)</span> <span class="p">{</span>
    <span class="nb">document</span><span class="p">.</span><span class="nf">webkitExitFullscreen</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Una vez que tengamos este método simplemente tendremos que invocarlo para salir de la pantalla completa.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">exitFullscreen</span><span class="p">();</span>
</code></pre></div></div>

<h2 id="propiedades-fullscreen-api">Propiedades Fullscreen API</h2>
<p>Para poder manejar el <strong>API Fullscreen</strong> disponemos de dos propiedades:</p>

<ul>
  <li>DocumentOrShadowRoot.fullscreenElement</li>
  <li>Document.fullscreenEnabled</li>
</ul>

<h3 id="fullscreenelement">fullscreenElement</h3>
<p>La propiedad <code class="language-plaintext highlighter-rouge">fullscreenElement</code> nos indica qué elemento del DOM o del “shadow DOM” está siendo mostrado en pantalla completa.</p>

<h3 id="fullscreenenabled">fullscreenEnabled</h3>
<p>Mediante la propiedad <code class="language-plaintext highlighter-rouge">fullscreenEnabled</code> nos indica si podemos activar el modo de pantalla completa, lo cual nos devolvería el valor <code class="language-plaintext highlighter-rouge">true</code> o por si el contrario no está disponible el modo de pantalla completa. En este segundo caso el valor de la propiedad será <code class="language-plaintext highlighter-rouge">false</code>.</p>

<h3 id="saber-si-la-pantalla-completa-está-activa">Saber si la pantalla completa está activa</h3>
<p>Jugando con las propiedades <code class="language-plaintext highlighter-rouge">fullscreenEnabled</code> y <code class="language-plaintext highlighter-rouge">fullscreenElement</code> podemos comprobar si tenemos al agente de usuario mostrándose en pantalla completa y además podemos saber qué elemento es el que se está mostrando a pantalla completa.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">fullscreenElement</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">fullscreenElement</span> <span class="o">||</span> <span class="nb">document</span><span class="p">.</span><span class="nx">mozFullScreenElement</span> <span class="o">||</span> <span class="nb">document</span><span class="p">.</span><span class="nx">webkitFullscreenElement</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">fullscreenEnabled</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">fullscreenEnabled</span> <span class="o">||</span> <span class="nb">document</span><span class="p">.</span><span class="nx">mozFullScreenEnabled</span> <span class="o">||</span> <span class="nb">document</span><span class="p">.</span><span class="nx">webkitFullscreenEnabled</span><span class="p">;</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">enabled:</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">fullscreenEnabled</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">element:</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">fullscreenElement</span><span class="p">);</span>
</code></pre></div></div>

<p>De igual manera que en los casos anteriores tenemos que apoyarnos en los hacks que tienen los diferentes navegadores para poder evaluar el contenido de las propiedades.</p>

<h2 id="eventos-fullscreen-api">Eventos Fullscreen API</h2>
<p>Junto a las propiedades y método del Fullscreen API tendremos la gestión de eventos. Esta gestión de eventos nos ayudará a saber cuando ha existido un cambio hacía o desde la pantalla completa o bien cuándo se ha producido un error en la gestión de la pantalla completa.</p>

<p>Los eventos que podemos manejar son:</p>

<ul>
  <li>Document.onfullscreenchange</li>
  <li>Document.onfullscreenerror</li>
  <li>Element.onfullscreenchange</li>
  <li>Element.onfullscreenerror</li>
</ul>

<p>Podemos ver que los eventos pueden ser aplicados a un elemento en completo o a todo el documento. Todo dependiendo sobre qué estemos gestionando la pantalla completa.</p>

<h3 id="onfullscreenchange">onfullscreenchange</h3>
<p>Un evento es enviado bien a un documento (o <code class="language-plaintext highlighter-rouge">Document</code>) o a un elemento (<code class="language-plaintext highlighter-rouge">Element</code>), dependiendo de lo que estemos intentando mostrar a pantalla completa, ya sea un elemento en concreto o tdoda la página o documento.</p>

<h3 id="onfullscreenerror">onfullscreenerror</h3>
<p>Un evento de error es enviado al docunento o elemento que intentó mostrarse en pantalla completa o salir de ella.</p>

<h3 id="controlar-el-paso-a-pantalla-completa">Controlar el paso a pantalla completa</h3>
<p>Ya hemos visto como podemos ayudar al usuario a poner un documento o elementos a pantalla completa. Pero, ¿qué sucede si es el propio usuario el que pone el agente de usuario a pantalla completa?. ¿Cómo podemos aprovecharnos de saber que está visualizando el contenido de esa forma?</p>

<p>En este caso lo que tenemos que hacer es controlar el evento <code class="language-plaintext highlighter-rouge">onfullscreenchange</code>. Para ello vamos a registrar un listener que lo controle.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">document</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">fullscreenchange</span><span class="dl">"</span><span class="p">,</span><span class="nx">cambioPantalla</span><span class="p">,</span><span class="kc">false</span><span class="p">);</span>
<span class="nb">document</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">webkitfullscreenchange</span><span class="dl">"</span><span class="p">,</span><span class="nx">cambioPantalla</span><span class="p">,</span><span class="kc">false</span><span class="p">);</span>
<span class="nb">document</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">mozfullscreenchange</span><span class="dl">"</span><span class="p">,</span><span class="nx">cambioPantalla</span><span class="p">,</span><span class="kc">false</span><span class="p">);</span>
<span class="nb">document</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">MSFullscreenchange</span><span class="dl">"</span><span class="p">,</span><span class="nx">cambioPantalla</span><span class="p">,</span><span class="kc">false</span><span class="p">);</span>
</code></pre></div></div>

<p>Hemos puesto todos los hacks del evento <code class="language-plaintext highlighter-rouge">onfullscreenchange</code> y les hemos enviado a la función <code class="language-plaintext highlighter-rouge">cambioPantalla</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">cambioPantalla</span><span class="p">(</span><span class="nx">event</span><span class="p">){</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Cambio en Pantalla Completa </span><span class="dl">"</span> <span class="o">+</span> <span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="diccionarios-fullscreen-api">Diccionarios Fullscreen API</h2>
<p>El API Fullscreenc cuenta con un diccionario <code class="language-plaintext highlighter-rouge">FullscreenOptions</code>. Este diccionario se le puede enviar al método <code class="language-plaintext highlighter-rouge">Element.requestFullscreen</code> para especificar propiedades adicionales.</p>

<h2 id="soporte-multi-navegador-del-fullscreen-api">Soporte Multi-Navegador del Fullscreen API</h2>
<p>En este artículo hemos visto como manejar los métodos que define el estándar del <strong>API Fullscreen</strong>, si bien el soporte puede variar por cada uno de los navegadores web y es por ello que tendremos que apoyarnos en el hack de cada navegador.</p>

<p>De est forma tendrás que tener en cuenta los siguientes:</p>

<ul>
  <li>.mozRequestFullScreen()</li>
  <li>.webkitRequestFullscreen()</li>
  <li>.msRequestFullscreen();</li>
</ul>

<h2 id="más-ejemplos-del-api-fullscreen">Más ejemplos del API Fullscreen</h2>
<p>Puedes revisar <a href="https://lineadecodigo.com/tag/html5-fullscreen/">más artículos sobre el <strong>Fullscreen API</strong> en Línea de Código</a>.</p>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[El API Fullscreen nos permite que un elemento del DOM (y sus descendientes) puedan ser representados a pantalla completa. Lo que permite es visualizar la página eliminando cualquier elemento del navegador (menús, pestañas,…). Con ello podremos poner desde el propio documento a pantalla completa, elementos de vídeo, imágenes,…]]></summary></entry><entry><title type="html">Validación formularios</title><link href="https://www.manualweb.net/html5/formularios-validacion/" rel="alternate" type="text/html" title="Validación formularios" /><published>2026-01-29T16:33:46+01:00</published><updated>2026-01-29T16:33:46+01:00</updated><id>https://www.manualweb.net/html5/formularios-validacion</id><content type="html" xml:base="https://www.manualweb.net/html5/formularios-validacion/"><![CDATA[<p>Cuando estamos introduciendo datos en un formulario puede suceder que el usuario inserte un dato que no es correcto, ya sea por el formato del dato, por el valor del dato,… Es por ello que deberemos de realizar validaciones a los formularios que creemos.</p>

<p>Algunas de las validaciones típicas que nos encontraremos serán: “No puedes dejar el campo en blanco”, “La longitud debe de ser mayor de 8”, “El valor introducido no es un email”,…</p>

<p>Además las validaciones permiten que el valor del dato que se va a enviar al servidor ya tenga cierta calidad, por lo que reducirá la posibilidad de fallo de validación en el servidor y por lo tanto reduzca las llamadas que hagamos a nuestros servicios de datos (o negocio).</p>

<blockquote>
  <p>Recuerda que hacer validaciones en la parte del cliente no implica el dejar de hacerlas en el lado del servidor.</p>
</blockquote>

<p>Dentro de <a href="http://www.manualweb.net/html5/">HTML5</a> encontramos dos formas de hacer validaciones de formulario:</p>

<ul>
  <li><strong>Validaciones propias del <a href="http://www.manualweb.net/html5/">HTML5</a></strong>, son las que nos ofrece el propio lenguaje, son validaciones básicas que no podremos personalizar, pero que nos serán de gran ayuda.</li>
  <li><strong>Validaciones utilizando <a href="http://www.manualweb.net/javascript/">Javascript</a></strong>, nos permite utilizar la potencia del lenguaje <a href="http://www.manualweb.net/javascript/">Javascript</a> junto con un API de Validación para personalizar al máximo nuestras validaciones de formularios.</li>
</ul>

<h2 id="validaciones-html5">Validaciones HTML5<a href="#validaciones-html5"><img src="/img/marker.png" alt="Validaciones HTML5" class="marca" /></a></h2>

<h3 id="atributo-required">Atributo Required<a href="#atributo-required"><img src="/img/marker.png" alt="Atributo Required" class="marca" /></a></h3>
<p>El primer atributo que nos vamos a encontrar dentro de un formulario es el atributo <code class="language-plaintext highlighter-rouge">required</code>. Mediante el atributo <code class="language-plaintext highlighter-rouge">required</code> podremos indicar que el campo sobre el que se aplica es obligatorio.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"nombre"</span> <span class="na">id=</span><span class="s">"nombre"</span> <span class="na">required</span><span class="nt">/&gt;</span>
</code></pre></div></div>

<p>Si intentamos procesar el formulario y el campo que hemos marcado como <code class="language-plaintext highlighter-rouge">required</code> sigue vacío, el navegador nos mostrará un mensaje de error.</p>

<p><img src="/html5/img/input-required.png" alt="Imagen de un Input Obligatorio" class="img-responsive" /></p>

<h3 id="expresiones-regulares">Expresiones Regulares<a href="#expresiones-regulares"><img src="/img/marker.png" alt="Expresiones Regulares" class="marca" /></a></h3>
<p>Otra posibilidad es validar el contenido utilizando una expresión regular. Si queremos definir una expresión regular deberemos de utilizar el atributo <code class="language-plaintext highlighter-rouge">pattern</code>.  El atributo <code class="language-plaintext highlighter-rouge">pattern</code> recibirá <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions">una expresión regular Javascript</a>.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"nombre"</span> <span class="na">id=</span><span class="s">"nombre"</span> <span class="na">pattern=</span><span class="s">"patron"</span><span class="nt">/&gt;</span>
</code></pre></div></div>

<p>Algunas de estas exprexiones regulares son:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">a</code> — Que aparezca la letra ‘a’.</li>
  <li><code class="language-plaintext highlighter-rouge">abc</code> — Que aparezca la letra ‘a’, seguida de la ‘b’ y seguida de la ‘c’.</li>
  <li><code class="language-plaintext highlighter-rouge">a*</code> — El carácter aparece 0 o muchas veces.</li>
  <li><code class="language-plaintext highlighter-rouge">a+</code> — El carácter aparece 1 o muchas veces.</li>
  <li><code class="language-plaintext highlighter-rouge">[^a]</code> — Cualquier carácter que no sea una ‘a’</li>
  <li><code class="language-plaintext highlighter-rouge">a|b</code> — El carácter es uno u otro.</li>
  <li><code class="language-plaintext highlighter-rouge">[a-z]</code> — Cualquier carácter de la ‘a’ a la ‘z’.</li>
  <li><code class="language-plaintext highlighter-rouge">[0-9</code> — Cualquier número.</li>
  <li><code class="language-plaintext highlighter-rouge">a{5}</code> —  El carácter aparece 5 veces.</li>
  <li><code class="language-plaintext highlighter-rouge">a{5,8}</code> — El carácter aparece de 5 a 8 veces.</li>
  <li><code class="language-plaintext highlighter-rouge">\w</code> — Cualquier carácter alfanumérico (letras, números y subrayado).</li>
  <li><code class="language-plaintext highlighter-rouge">\d</code> — Cualquier dígito.</li>
</ul>

<p>Y lógicamente puedes combinarlas todas como quieras.</p>

<p>Así por ejemplo podríamos indicar que elija entre “Madrid” y “Barcelona”.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"ciudad"</span> <span class="na">id=</span><span class="s">"ciudad"</span> <span class="na">pattern=</span><span class="s">"Madrid|Barcelona"</span><span class="nt">/&gt;</span>
</code></pre></div></div>

<p>O que el usuario pueda meter las letras, números y subrayados que quiera, pero al menos uno, de la siguiente forma:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"texto"</span> <span class="na">id=</span><span class="s">"texto"</span> <span class="na">pattern=</span><span class="s">"[\w]+"</span><span class="nt">/&gt;</span>
</code></pre></div></div>

<p>O que el número contenga 5 dígitos:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"number"</span> <span class="na">name=</span><span class="s">"numero"</span> <span class="na">id=</span><span class="s">"numero"</span> <span class="na">pattern=</span><span class="s">"\d{5}"</span><span class="nt">/&gt;</span>
</code></pre></div></div>

<p>Si quieres, <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions">puedes leer más sobre expresiones regulares en Javascript</a>.</p>

<p>En el caso de que el valor introducido en el usuario no corresponda con el patrón, el navegador nos mostrará un mensaje de error.</p>

<p><img src="/html5/img/input-pattern.png" alt="Imagen de un Mensaje Error de Patrón" class="img-responsive" /></p>

<p>Podemos utilizar el atributo <code class="language-plaintext highlighter-rouge">title</code> para poder dar más información al usuario cuando se muestre el error.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"nombre"</span> <span class="na">id=</span><span class="s">"nombre"</span> <span class="na">pattern=</span><span class="s">"[\w]+"</span> <span class="na">title=</span><span class="s">"Letras, números o subrayados"</span><span class="nt">/&gt;</span>
</code></pre></div></div>

<p>Veremos que lo que se muestra por pantalla incluye la información adicional.</p>

<p><img src="/html5/img/input-pattern-title.png" alt="Imagen de un Mensaje Error de Patrón con Información Adicional" class="img-responsive" /></p>

<h3 id="limitar-tamaños">Limitar Tamaños<a href="#limitar-tamaños"><img src="/img/marker.png" alt="Limitar Tamaños" class="marca" /></a></h3>
<p>Si queremos limitar el tamaño de un campo <code class="language-plaintext highlighter-rouge">input</code> o de un <code class="language-plaintext highlighter-rouge">textarea</code>, ya sea limitándolo a tener un número mínimo o un número máximo de caracteres, podemos recurrir a los atributos <code class="language-plaintext highlighter-rouge">minlength</code> y <code class="language-plaintext highlighter-rouge">maxlength</code>.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">id=</span><span class="s">"nombre"</span> <span class="na">minlength=</span><span class="s">"numero"</span> <span class="na">maxlength=</span><span class="s">"numero"</span><span class="nt">/&gt;</span>
</code></pre></div></div>

<p>Por ejemplo, imagina que quieres una contraseña que tenga, al menos, 8 caracteres:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"password"</span> <span class="na">name=</span><span class="s">"pwd"</span> <span class="na">id=</span><span class="s">"pwd"</span> <span class="na">minlength=</span><span class="s">"8"</span> <span class="na">required</span><span class="nt">/&gt;</span>
</code></pre></div></div>

<p>Si no insertamos el número suficiente de caracteres, el navegador nos avisará del número de caracteres que nos falta.</p>

<p><img src="/html5/img/input-minlength.png" alt="Imagen de un Mensaje Error de Número Mínimo de Caracteres" class="img-responsive" /></p>

<p>En el caso de que el <a href="/html5/formularios-elementos-input/#input-number">campo sea de tipo <code class="language-plaintext highlighter-rouge">number</code></a>, los propios atributos <code class="language-plaintext highlighter-rouge">min</code> y <code class="language-plaintext highlighter-rouge">max</code> establecen este tipo de validación.</p>

<h2 id="validaciones-javascript">Validaciones Javascript<a href="#validaciones-javascript"><img src="/img/marker.png" alt="Validaciones Javascript" class="marca" /></a></h2>

<p>Ya hemos visto como <a href="http://www.manualweb.net/html5/">HTML5</a> nos permite de forma sencilla realizar validaciones de datos. Si bien estas se nos pueden quedar cortas a la hora de realizar validaciones o de personalizar los mensajes de error asociados al formulario.</p>

<p>Es por ello que <a href="http://www.manualweb.net/html5/">HTML5</a> dispone de un <strong>API de Validación de Formularios</strong> el cual nos ofrece un conjunto de propiedades y métodos para realizar nuestras validaciones personalizadas.</p>

<p>Propiedades:</p>
<ul>
  <li><em>validationMessage</em></li>
  <li><em>validity</em></li>
  <li><em>willValidate</em></li>
</ul>

<p>Métodos:</p>
<ul>
  <li><em>checkValidity()</em></li>
  <li><em>HTMLFormElement.reportValidity()</em></li>
  <li><em>setCustomValidity(message)</em></li>
</ul>

<h3 id="interface-validitystate">Interface ValidityState<a href="#interface-validitystate"><img src="/img/marker.png" alt="Interface ValidityState" class="marca" /></a></h3>
<p>El interface <code class="language-plaintext highlighter-rouge">ValiditySate</code> describe el estado de validación de un elemento. De esta manera sobre este estado podremos ver si hay un problema de rango <code class="language-plaintext highlighter-rouge">.rangeOverflow</code> o si el valor del campo es demasiado largo <code class="language-plaintext highlighter-rouge">.tooLong</code> o si el tipo de dato introducido no es correcto <code class="language-plaintext highlighter-rouge">.typeMismatch</code> o …</p>

<p>Dentro del <strong>API de Validación de Formularios</strong> es el objeto <code class="language-plaintext highlighter-rouge">validity</code> el que implementa dicho interface. Este objeto está asociado a los campos de un formulario.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Accedemos a un elemento input de tipo email</span>
<span class="kd">var</span> <span class="nx">email</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">mail</span><span class="dl">"</span><span class="p">);</span>
<span class="k">if </span><span class="p">(</span><span class="nx">email</span><span class="p">.</span><span class="nx">validity</span><span class="p">.</span><span class="nx">typeMismatch</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Hay un error en el formato introducido!!!</span><span class="dl">"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="validationmessage">validationMessage<a href="#validationmessage"><img src="/img/marker.png" alt="validationMessage" class="marca" /></a></h3>
<p>Una vez que sabemos cómo acceder al objeto <code class="language-plaintext highlighter-rouge">validity</code> que contiene el estado de validación de un campo de formulario. Pero si lo que queremos saber es qué mensaje va a mostrar el navegador, deberemos de acceder a la propiedad <code class="language-plaintext highlighter-rouge">validationMessage</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Accedemos a un elemento input de tipo email</span>
<span class="kd">var</span> <span class="nx">email</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">mail</span><span class="dl">"</span><span class="p">);</span>
<span class="k">if </span><span class="p">(</span><span class="nx">email</span><span class="p">.</span><span class="nx">validity</span><span class="p">.</span><span class="nx">typeMismatch</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">email</span><span class="p">.</span><span class="nx">validationMessage</span><span class="p">);</span> <span class="c1">// Mensaje por defecto</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="willvalidate">willValidate<a href="#willvalidate"><img src="/img/marker.png" alt="willValidate" class="marca" /></a></h3>
<p>Si queremos saber si el elemento del formulario va a ser evaluado en el envío, lo que deberemos de hacer es consultar la propiedad <code class="language-plaintext highlighter-rouge">willValidate</code>. La cual devolerá <code class="language-plaintext highlighter-rouge">true</code> si el campo se validará en el envío o <code class="language-plaintext highlighter-rouge">false</code> si no se le va a hacer una validación.</p>

<h3 id="checkvalidity">checkValidity<a href="#checkvalidity"><img src="/img/marker.png" alt="checkValidity" class="marca" /></a></h3>
<p>El método <code class="language-plaintext highlighter-rouge">checkValidity()</code> nos permite comprobar si el elemento tiene problemas de validación. Devuelve <code class="language-plaintext highlighter-rouge">true</code> en el caso de que el elemento no tenga problemas de validación y <code class="language-plaintext highlighter-rouge">false</code> si el elemento tiene problemas de validación.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Accedemos a un elemento input de tipo email</span>
<span class="kd">var</span> <span class="nx">email</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">mail</span><span class="dl">"</span><span class="p">);</span>
<span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">email</span><span class="p">.</span><span class="nf">checkValidity</span><span class="p">())</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">email</span><span class="p">.</span><span class="nx">validity</span><span class="p">.</span><span class="nx">typeMismatch</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Hay un error en el formato introducido!!!</span><span class="dl">"</span><span class="p">)</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="reportvalidity">reportValidity<a href="#reportvalidity"><img src="/img/marker.png" alt="reportValidity" class="marca" /></a></h3>
<p>En este caso el método <code class="language-plaintext highlighter-rouge">reportValidity</code> realiza una <strong>comprobación de la validación a nivel del elemento de formulario</strong>. Es por eso que su sintaxis en <code class="language-plaintext highlighter-rouge">HTMLFormElement.reportValidity()</code>. Es decir, comprueba si todos los elementos que hay en un formulario pasan la validación de formato o hay campos con error.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">webform</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">webform</span><span class="dl">"</span><span class="p">);</span>

<span class="nx">webform</span><span class="p">.</span><span class="nx">onchange</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">webform</span><span class="p">.</span><span class="nf">reportValidity</span><span class="p">()){</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Todos los campos del formulario están validados correctamente.</span><span class="dl">"</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Hay campos del formulario con problemas de validación.</span><span class="dl">"</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="setcustomvalidity">setCustomValidity<a href="#setcustomvalidity"><img src="/img/marker.png" alt="setCustomValidity" class="marca" /></a></h3>
<p>El último método que vemos es el más interesante, ya que mediante <code class="language-plaintext highlighter-rouge">setCustomValidity</code> vamos a poder <strong>personalizar el mensaje de error que se le muestra al usuario</strong> cuando el formulario contiene errores de validación.</p>

<p>El método <code class="language-plaintext highlighter-rouge">setCustomValidity</code> <strong>recibe como parámetro el mensaje que queremos personalizar</strong> y es aplicado sobre el elemento que estamos validando y por lo tanto adaptamos el mensaje a dicho tipo de elemento.</p>

<pre><code class="language-javaScript">var email = document.getElementById("mail");

email.addEventListener("input", function (event) {
  if (email.validity.typeMismatch) {
    email.setCustomValidity("Cuidado, el campo es de tipo email!!!");
  } else {
    email.setCustomValidity("");
  }
});
</code></pre>

<p>Aquí podemos ver que lanzamos el cambio de mensaje cada vez que se produce una modificación sobre el campo <code class="language-plaintext highlighter-rouge">input</code>. Si bien podemos hacerlo en cualquier momento.</p>

<h2 id="deshabilitar-validaciones">Deshabilitar Validaciones<a href="#deshabilitar-validaciones"><img src="/img/marker.png" alt="Deshabilitar Validaciones" class="marca" /></a></h2>
<p>Ya hemos visto cómo aprovecharnos al máximo de las validaciones automáticas de <a href="http://www.manualweb.net/html5/">HTML5</a> y de cómo podemos personalizarlas mediante el <strong>API de Validaciones de Formularios</strong>. Si bien puede darse el caso de que no nos interese que estas validaciones se ejecuten. En este caso podemos deshabilitar las validaciones del formulario mediante el atributo <code class="language-plaintext highlighter-rouge">novalidate</code> a nivel de formulario.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">"#"</span> <span class="na">novalidate</span><span class="nt">&gt;</span>
  <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"nombre"</span><span class="nt">&gt;</span>¿Cómo te llamas?:<span class="nt">&lt;/label&gt;</span>
  <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"nombre"</span> <span class="na">id=</span><span class="s">"nombre"</span> <span class="na">required</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">value=</span><span class="s">"Enviar"</span><span class="nt">&gt;</span>
<span class="nt">&lt;/form&gt;</span>
</code></pre></div></div>

<p>El atributo <code class="language-plaintext highlighter-rouge">novalidate</code> dentro del elemento <code class="language-plaintext highlighter-rouge">form</code> deshabilitara todos los controles del formulario.</p>]]></content><author><name>manual_web</name></author><summary type="html"><![CDATA[Cuando estamos introduciendo datos en un formulario puede suceder que el usuario inserte un dato que no es correcto, ya sea por el formato del dato, por el valor del dato,… Es por ello que deberemos de realizar validaciones a los formularios que creemos.]]></summary></entry></feed>