Vídeos adaptables (RWD) automáticos | Oloblogger ¿Queréis plugins ? Pues tomad plugins ... Este lo que hace es muy sencillo pero cada vez más neces...

3 de noviembre de 2015

Vídeos adaptables (RWD) automáticos

¿Queréis plugins? Pues tomad plugins...

Este lo que hace es muy sencillo pero cada vez más necesario: toma un vídeo de YouTube (u otros servicios) insertado mediante un iframe, calcula sus medidas y le inserta un código CSS personalizado para que ese vídeo se convierta en adaptable (RWD).

A diferencia del simple (pero no menos eficaz) código CSS que nos sirve para hacer lo mismo, las proporciones serán exactamente las que necesite ese vídeo, ni más ni menos.

Con CSS el inconveniente es que hay que añadir marcado HTML extra al vídeo y, por otra parte, que la proporción si no queremos estar añadiendo más cosas a mano, será la misma para todos los vídeos, viéndose algunos sin rellenar todo el espacio disponible.



Este código está hecho con simple JavaScript, por lo que no necesita jQuery ni ninguna otra librería adicional. Con ellas podría haberse hecho más corto, pero si vamos a necesitar cargar para ello una librería completa, el ahorro de unas pocas líneas no compensaría el mayor peso.

El que entienda un poco el idioma podrá fácilmente entender el algoritmo:

  • Se crea un nodo con el estilo CSS necesario y se añade al final de la página
  • Luego se capturan todos los iframes que se encuentren en ella y mediante un bucle se "rodean" con una caja que incluirá la misma clase usada en el CSS (video100)
  • Al tiempo se calculará la ratio entre la altura y la anchura que incluya el iframe como parámetros y se aplicará mediante CSS inline el padding-bottom necesario para respetar esa ratio

<script>//<![CDATA[
function rwdiframes() {
    var estilo = document.createElement("style");
    var contenido = document.createTextNode(".video100 {position:relative; width:100%; height:0; overflow:hidden;} .video100 iframe, .video100 embed {position: absolute;top: 0; left: 0;width: 100%;height: 100%;");
    estilo.appendChild(contenido);
    document.head.appendChild(estilo);
    var iframes = document.getElementsByTagName("iframe");
    var div = document.createElement("div");
    div.className = "video100";
    if (!iframes.length) iframes = [iframes];
    for (var i = iframes.length - 1; i >= 0; i--) {
      var child = (i > 0) ? div.cloneNode(true) : div;
      var actual = iframes[i];
      if (actual.height > 0 && actual.width > 0) {
        child.style.paddingBottom = actual.height / actual.width * 100 + "%";
        var parent = actual.parentNode;
        var sibling = actual.nextSibling;
        child.appendChild(actual);
        if (sibling) {
          parent.insertBefore(child, sibling);
        } else {
          parent.appendChild(child);
        }
      }
    }
  }
addEventListener("load", rwdiframes);
//]]></script>

Este código lo podéis insertar directamente en la plantilla, antes del </head> o antes del </body>, o bien si lo preferís, como gadget tipo HTML/JavaScript.

Si queréis juguetear con él, en este Codepen lo tenéis disponible. Allí podréis ver cómo funciona y cómo respeta la proporción original de dos vídeos con distintas medidas.

¡Ah! y para el que prefiera la versión jQuery, a continuación la tiene:

<script>//<![CDATA[
$(document).ready(function() {
  $estilo = "<style>.video100 {position:relative; width:100%; height:0; overflow:hidden;} .video100 iframe, .video100 embed {position: absolute;top: 0; left: 0;width: 100%;height: 100%;</style>";
  $("head").append($estilo);
  $("iframe,embed").each(function() {
    $ratio = $(this).height() / $(this).width() * 100;
    $(this).wrap("<div class='video100' style='padding-bottom:" + $ratio + "%;'></div>");
  });
});
//]]></script>

¿Vemos otro post al azar por si le encuentras utilidad o quizás prefieres ser más metódico y suscribirte a nuestras entradas por correo? También puedes imprimir este artículo y por supuesto compartirlo en redes sociales si fue de tu agrado.

Compartir
Copy URL

Y muchos más artículos interesantes si nos sigues en...

follow us in feedly

12 comentarios :

  1. Una puntualización sobre el código utilizado: cuidado con la forma de asignar las funciones a un evento. En la versión sin jQuery se asigna así:
    onload = rwdiframes;
    Si hubiera otra función asignada a la propiedad "onload" se sobreescribiría, ya que las propiedades solo admiten un único valor.

    Para poder asignar varias funciones al evento "onload", es preferible usar:
    addEventListener("load", rwdiframes);
    attachEvent("onload", rwdiframes);
    // para IE 8 e inferiores (versiones tan viejas que quizás no haya que tener en cuenta)

    Además, de esta forma podemos eliminar el evento si fuera necesario:
    removeEventListener("onload", rwdiframes);

    ResponderEliminar
    Respuestas
    1. Ups, el último código es incorrecto, esta es la forma correcta:
      removeEventListener("load", rwdiframes);

      Eliminar
    2. Gracias Jorge por el apunte. Ya lo he incorporado a la entrada.

      Lo cierto es que me cuesta horrores montar cosas en JavaScript porque toco "de oído" ;)

      Eliminar
  2. Me quedó perfecto, muchas gracias Oloman!

    ResponderEliminar
  3. Mientras leia la entrada. No dejaba de pensar en las imagenes dentro de las entradas. Tambien podria servir? Pero versionadolo para imagenes.

    ResponderEliminar
    Respuestas
    1. Es que eso es mucho más fácil Teleri. Sólo añade esto al CSS de tu plantilla:
      .post-body img {
      width: 100%;
      height: auto;
      }

      Eliminar
    2. Pero luego esta el caso de esas imagenes que ya en el codigo del IMG tiene el tamaño ya puesto. ¿Que sucede con esos?

      Eliminar
    3. Nada si le pones a cada cosa un !important
      .post-body img {
      width: 100% !important;
      height: auto !important;
      }

      ...pero quizás sea contraproducente porque podrían pixelar.

      Eliminar
    4. Entonces no seria nada responsive..

      Eliminar
    5. ¿No? Bueno, no sé realmente qué quieres porque esto va de vídeos que ocupan todo el ancho de pantalla y los dos anteriores códigos que te expliqué hacen exactamente eso, pero como opción también podrías usar:
      .post-body img {
      max-width: 100%;
      height: auto;
      }
      Con eso se respetan las dimensiones establecidas en la imagen... como tamaño máximo.

      Eliminar
  4. Oloman, si pongo cualquiera de los 2 codigos a mi plantilla, los videos que tenga en las entradas se veran de manera responsive o tengo que incluir algun otro codigo a los iframes de youtube. Otra cosa ya tengo JQuerry en mi plantilla, me convendría el segundo creo. Saludos

    ResponderEliminar
    Respuestas
    1. No tienes que añadir nada más Jhonny. Si añades ese JS TODOS tus vídeos de YouTube que estén en las entradas se maximizarán y pasarán a ser RWD.

      Y si tienes ya jQuery, puedes usar el segundo. Para eso lo puse.

      Eliminar