Contenido

El elemento audio del HTML5

14 jul

+ 11

Hace un par de semanas vimos lo que el tag <video /> del HTML5 nos puede ofrecer. Hoy le toca al tag <audio /> :D

El tag <audio />

Destinado para la inclusión directa mediante HTML de ficheros de audio en nuestras páginas web este tag, evitará que tengamos que usar reproductores creados el flash para que nuestros usuarios puedan escuchar sonidos, canciones, podcasts… directamente desde nuestra página web.

<audio src="music.oga" controls>
 <a href="music.oga">Descargar canción</a>
</audio>

Como podemos ver, además de delegar al navegador la reproducción del fichero, hacemos nuestro código más semántico aplicando una mayor claridad al elemento usado, mucho más que como lo estabamos haciendo hasta ahora:

<object type="application/x-shockwave-flash" data="player_mp3.swf" width="200" height="20">
<param name="movie" value="player_mp3.swf" />
<param name="FlashVars" value="mp3=music.mp3&showstop=1&showinfo=1" />
</object>

Al ser un tag abierto (<audio></audio>) nos permite ofrecer un valor alternativo para los usuarios que no tienen disponible esta capacidad. En el primer ejemplo vemos como ofrecemos la posibilidad de descargar el fichero de audio music.oga en caso de que el navegador no reconozca el tag <audio />.

<audio src="music.oga" controls>
 <object type="application/x-shockwave-flash" data="player_mp3.swf" width="200" height="20">
 <param name="movie" value="player_mp3.swf" />
 <param name="FlashVars" value="mp3=music.mp3&showstop=1&showinfo=1" />
 </object>
</audio>

Aprovechándonos de esta propiedad, podemos hacer una mezcla entre las dos técnicas para así acercar ambas técnicas a todos los usuarios. Eso sí, a costa de no validar nuestra página.

Manipulando el tag <audio />

Como todo elemento alojado en el DOM, el tag <audio /> nos permite interactucar con el mediante una serie de métodos Javascript comunes con todos los elementos y además dispone de una serie de métodos propios que nos permitirán manipular la ejecución de la reproducción.

// Accedemos al elemento
var audioElement = document.createElement('audio');

// Cambiamos de canción
audioElement.setAttribute('src', 'loading.ogg');

// Comenzamos la reproducción
audioElement.play();

// Definimos el elemento onload
audioElement.addEventListener("load", function() {
 // Comenzamos la reproducción
 audioElement.play();

 // Mostramos la duración del archivo de sonido
 $(".duration span").html(audioElement.duration);

 // Mostramos el nombre del archivo de audio
 $(".filename span").html(audioElement.src);
}, true);

// Ejecutamos el evento onload() del elemento
audioElement.load()

// Pausamos la ejecución
audioElement.pause();

// Definimos el volumen
audioElement.volume=0;

// Indicamos una posición de tiempo
audioElement.currentTime=35;

Snow Stack, impresionantes efectos CSS 3D con HTML puro y Javascript

14 jul

+ 24

Snow Stack es la última muestra de lo que los CSS transformation nos puede llegar a ofrecernos, mediante el uso de javascript conseguimos un efecto de dinamismo que ya le gustaría a más de una aplicación de escritorio.

snow_stack
(Ver Imagen)

Para probarlo necesitaremos la última versión de WebKit (r45824 o superior) y acceder a esta demo.

Me gustaría tener el pedazo de máquina que debe tener el que ha grabado el video para poder verlo así de fluido, por desgracia no he podido verlo de esa forma, pero ya despunta como una nueva forma de ver Internet.

¿Como detectar un navegador de tus usuarios en WordPress?

14 jul

+ 6

WordPress está desarrollado en PHP, y en ese lenguaje tenemos herramientamientas para conocer el navegador del usuario que te está visitando. Este dato, puede ser crucial para condicionar la salida por pantalla de nuestro código, por esto, WordPress dispone de una serie de variables que podemos usar en nuestros script con el fin de conocer el navegador que nos visita:

global $is_lynx, $is_gecko, $is_IE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone;

Mediante el uso de estas variables booleanas (true o false) podremos conocer el navegador que usa nuestro usuario. Incluso podemos generarnos una función que nos facilite la comprobación de cada una de las variables.

add_filter('body_class','browser_body_class');
function browser_body_class($classes) {
	global $is_lynx, $is_gecko, $is_IE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone;

	if($is_lynx) $classes[] = 'lynx';
	elseif($is_gecko) $classes[] = 'gecko';
	elseif($is_opera) $classes[] = 'opera';
	elseif($is_NS4) $classes[] = 'ns4';
	elseif($is_safari) $classes[] = 'safari';
	elseif($is_chrome) $classes[] = 'chrome';
	elseif($is_IE) $classes[] = 'ie';
	else $classes[] = 'unknown';

	if($is_iphone) $classes[] = 'iphone';
	return $classes;
}

Este código añadirá automáticamente al class del tag <body /> el navegador de nuestro usuario, permitiéndonos personalizar la apariencia del blog dependiendo de dicha versión.

25 reglas para hacer CSS accesibles

9 jul

+ 2

Olga Carreras publica un interesante artículo en el que nos muestra 25 reglas que deberíamos seguir para conseguir que nuestro CSS sea más accesible.

Glow, otra librería javascript

9 jul

+ 1

Glow es una librería javascript con una gran cantidad de widgets que nos permite integrarlos fácilmente en nuestro sitios web. Actualmente se encuentra en su versión 1.5.1 y ofrece una documentación bastante extensa y gráfica.[Descargar]

Ajax cross-domain con Safari 4, Google Chrome 2 y Firefox 3.5

9 jul

+ 8

Uno de los problemas con los que nos encontramos al trabajar con Ajax, es la limitación a trabajar siempre bajo el mismo dominio. Para entendernos, desde http://www.anieto2k.com no puedo acceder mediante una petición Ajax a un contenido en http://www.google.com.

Debido a las peticiones por parte de la comunidad de desarrolladores se creó una estandarización para permitir extender el objeto XMLHttpRequest() con la capacidad de permitir peticiones entre diferentes dominios, permitiendo una mejor integración entre servicios online.

Safari4, Google Chrome 2 y ahora Firefox 3.5, ya implementan dicha mejora y nos permite trabajar con ella. Por otro lado Microsoft, en otro mundo, desarrolla XDomainRequest() que permite realizar exactamente lo mismo en la última versión de su navegador (la 8.0).

¿Como funciona?

La idea básica es muy sencilla, el nuevo objeto XMLHttpRequest() envia una nueva cabecera al servidor destino

Access-Control-Allow-Origin: http://servidor.destino

Y este, permite el acceso o no indicándo una cabecera nueva en la respuesta:

//PHP
<?php header('Access-Control: allow <*>'); ?> //Permitimos todos
<?php header('Access-Control: deny <*>');?>  //Denegamos todos
<?php header('Access-Control: allow <mozilla.org>');?> //Permitimos solo mozilla.org
<?php header('Access-Control: allow <mozilla.org> exclude <developer.mozilla.org>');?> //Permitimos mozilla.org y denegamos developer.mozilla.org
<?php header('Access-Control: allow <developer.mozilla.org:80> method GET, POST');?> //Permitimos developer.mozilla.org para el puerto 80 en los métodos GET y POST

//XML
<?access-control allow="*"?> //Permitimos todos
<?access-control deny="*"?> //Denegamos todos
<?access-control allow="mozilla.org"?> //Permitimos solo mozilla.org
<?access-control allow="mozilla.org" exclude="developer.mozilla.org"?> //Permitimos mozilla.org y denegamos developer.mozilla.org
<?access-control allow="developer.mozilla.org" method="GET POST"?> //Permitimos developer.mozilla.org para el puerto 80 en los métodos GET y POST

Veamos un ejemplo de la cabecera devuelta al navegador:

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: http://servidor.destino
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

Cross-domain && Cross-browser

Como en casi todas las nuevas funcionalidades tenemos que contemplar las posibilidad de que esta no esté disponible en el navegador del usuario,  para ello debemos detectarlas y ofrecer una alternativa…

Ejemplo simple de envio por GET

var url = "http://bar.other/publicNotaries/";
if(XMLHttpRequest) {
  var request = new XMLHttpRequest();

  if("withCredentials" in request) {
   // Firefox 3.5 y Safari 4
   request.open('GET', url, true);
   request.onreadystatechange = handler;
   request.send();

  } else if (XDomainRequest) {
   // IE8
   var xdr = new XDomainRequest();
   xdr.open("get", url);
   xdr.send();

  } else {
  // Otros navegadores
  }
}

En este caso, usaremos como flag el atribute withCredentials para comprobar que está disponible esta nueva característica en el navegador del usuario.

“Preflighted” Request (No lo he sabido traducir).

Otra opción de la que disponemos es la capacidad de realizar una consulta previa al servidor para comprobar la disponibilidad de la funcionalidad.

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
function callOtherDomain(){
if(invocation) {
    invocation.open('POST', url, true);
    invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
    invocation.setRequestHeader('Content-Type', 'application/xml');
    invocation.onreadystatechange = handler;
    invocation.send(body);
}

En este caso, estamos enviando una cabecera previa llamada OPTIONS:

OPTIONS /resources/post-here/ HTTP/1.1
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER

Y el servidor de destino nos devolverá información sobre las capacidades disponibles:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://arunranga.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER
Access-Control-Max-Age: 1728000

Posteriormente, devolverá las cabeceras con la respuesta:

POST /resources/post-here/ HTTP/1.1
...
Content-Type: application/xml; charset=UTF-8
X-PINGOTHER: pingpong
...

Esta funcionalidad no está disponible en XDomainRequest() de Internet Explorer 8.

Envio de Credenciales

Por defecto, las credenciales como Cookies o HTTP Auth, no se envian en la petición XMLHttpRequest(), si necesitamos enviarlos, la nueva implementación nos lo permite con un atributo que hemos visto previamente.

Por defecto, el valor de  withCredentials es false, así que tendremos que modificarlo antes de realizar la petición.

var request = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
function callOtherDomain(){
  if(request)
  {
   request.open('GET', url, true);
   request.withCredentials = "true";
   request.onreadystatechange = handler;
   request.send();
  }

Otra vez, Internet Explorer 8 y si XDomainRequest() no permiten hacer esto.

Alternativas para navegador más antiguos

Enlaces rápidos

8 jul

+ 3

Un par de cosillas que no me da tiempo a extender:

  1. WP-Newsletter, plugin para gestionar Newsletters en tu WordPress.
  2. Theme base basado en Grid960, facilitando (aun más) la creación de themes de WordPress profesionales (Espectacular LordMaX)

WordPress 2.8.1 RC1 disponible para descargar

8 jul

+ 2

Ya tenemos la RC1 de WordPress 2.81 disponible para descargar, podeis ver los cambios desde la beta 2 y la lista de cambios de esta 2.8.1.[Descargar]

Gazelle y Google Chrome OS, los SO del futuro para los amantes de la red

8 jul

+ 16

Ayer leí que Microsoft estaba trabajando en Gazelle, una visión de Microsoft con la que crear un navegador muy ligero que verá la luz a finales de este año con la intención de que las aplicaciones no estuvieran ligadas al sistema operativo y que el navegador fuera el interfaz que las ejecute.

Por otro lado, ayer Google, dijo lo que todos nos olíamos, Google Chrome OS. Un sistema operativo en forma de navegador web en el que todas las aplicaciones estarían en un servidor remoto y que los usuarios que viven de Internet puedan hacer uso de las principales herramienta que ahora usan sin necesidad de tener un Sistema Operativo instalado en su máquina. Tendremos que esperar hasta mediados de 2010, pero ya podemos saber que no tiene nada que ver con Android, que la misma compañia se a apresurado a indicar que está pensado para una finalidad distinta al nuevo Google Chrome OS.

Sin duda, y aunque el tema lleva ya tiempo deambulando por Internet parece que por fín está aquí y es cuestión de tiempo que podamos ser partícipes del cambio :D

Bueno, esto es embarazoso.

7 jul

+ 16

Con esta pantalla tan curiosa me he encontrado al abrir el portátil después de que ayer se me agotara la batería antes de acostarme.
firefox-restore
(Ver Imagen)

Realmente es un detalle  (que ya tienen muchos otros navegadores) que Firefox (Por fin!) lo haya incluido :D