Contenido

Diagnosticando errores javascript más fácilmente con Error.stack

11 may

+ 2

Hoy, IEBlog publica un artículo muy interesante sobre el tratamiento de errores en IE10 sobre Windows 8. Al parecer, este último incluye soporte para un nuevo atributo al objeto Error(), el Error.stack, que activado desde las Web Developer Toolbars de IE10 nos ayudará a detectar los errores de forma más rápida.

Error.stack en IE10
(Ver Imagen)

Como podemos ver, nos ofrece una información detallada del error, al puro estilo Java mostrando toda la traza del error producido. Por lo tanto, nuestros try/catch vendrán cargados con todo lo necesario para conocer la causa de nuestros problemas, además podremos limitar el nivel de profundidad de dicha traza mediante el atributo stackTraceLimit disponible de igual modo en el objeto Error(). Una funcionalidad muy interesante que seguro nos ayudará a solventar los problemas que nos encontremos en IE10 … que seguro que los encontramos :D

jQuery transit, transformaciones y transiciones CSS3

10 may

+ 1

jQuery.Transit, es un plugin de jQuery (1.4+) que nos permite trabajar con las diferentes transiciones y transformaciones de CSS3 mediante una simple nomenclatura.

Para ello, dota al atributo css() de una serie de parámetros que nos permite extender los estilos básicos tratados con jQuery.


("#box").css({ x: '30px' });               // Move right
$("#box").css({ y: '60px' });               // Move down
$("#box").css({ translate: [60,30] });      // Move right and down
$("#box").css({ rotate: '30deg' });         // Rotate clockwise
$("#box").css({ scale: 2 });                // Scale up 2x (200%)
$("#box").css({ scale: [2, 1.5] });         // Scale horiz and vertical
$("#box").css({ skewX: '30deg' });          // Skew horizontally
$("#box").css({ skewY: '30deg' });          // Skew vertical
$("#box").css({ perspective: 100, rotateX: 30 }); // Webkit 3d rotation
$("#box").css({ rotateY: 30 });
$("#box").css({ rotate3d: [1, 1, 0, 45] });

// Valores relativos
$("#box").css({ rotate: '+=30' });          // 30 degrees more
$("#box").css({ rotate: '-=30' });          // 30 degrees less

// No importa usar unidades
$("#box").css({ x: '30px' });
$("#box").css({ x: 30 });

// Multivalores
$("#box").css({ translate: [60,30] });
$("#box").css({ translate: ['60px','30px'] });
$("#box").css({ translate: '60px,30px' });

Todos estos helpers implementados en css() usan la funcioón $.fn.transition() que es la encargada de gestionar las animaciones aplicadas a estos nuevos parámetros.


/*
   $('...').transition(options, [duration], [easing], [complete])
*/
$("#box").transition({ opacity: 0.1, scale: 0.3 });
$("#box").transition({ opacity: 0.1, scale: 0.3 }, 500);                         // duration
$("#box").transition({ opacity: 0.1, scale: 0.3 }, 'fast');                      // easing
$("#box").transition({ opacity: 0.1, scale: 0.3 }, 500, 'in');                   // duration+easing
$("#box").transition({ opacity: 0.1, scale: 0.3 }, function() {..});             // callback
$("#box").transition({ opacity: 0.1, scale: 0.3 }, 500, 'in', function() {..});  // everything

Funciona en: IE 10+, Firefox 4+, Safari 5+, Chrome 10+, Opera 11+, Mobile Safari

Un plugin de esos que te ayuda a hacer las cosas más faciles, de los que nunca viene mal conocer :D

Usando la Javascript Fullscreen API

9 may

+ 11

Si conoces Facebook, conocerás el nuevo sistema de visualizado de imágenes que permite, entre otras opciones, ver la imagen a pantalla completa, pero cuando decimos pantalla completa, es a pantalla completa, usando toda la pantalla, no usando el tamaño del elemento Window como lo usábamos antes.

¿Como es posible?

Pues debido a la implementación de la Javascript Fullscreen API :D.
Una implementación, introducida por Apple en el Safari 5.0 para los tags <video /> y que fue bien acogida en la comunidad de desarrolladores, lo que hizo que Mozilla se añadiera con una propuesta más firme en la que se extendía su uso a cualquier elemento del DOM. Y para consolidar esta buena idea, la W3C metió mano y definió la primera propuesta para estandarizar esta funcionalidad.

¿Como lo usamos?

Después de comprobar que el navegador del usuario dispone de dicha funcionalidad (que por ahora son Google Chrome 15+, Safari 5.1+ y Firefox 10+) ejecutamos la llamada RequestFullScreen() que nos cambiará a modo pantalla completa.

var docElm = document.documentElement;
if (docElm.requestFullscreen) {
    docElm.requestFullscreen();
}
else if (docElm.mozRequestFullScreen) {
    docElm.mozRequestFullScreen();
}
else if (docElm.webkitRequestFullScreen) {
    docElm.webkitRequestFullScreen();
}

Una vez ya en pantalla completa, el navegador no solicitará si deseamos permitir que el dominio sobre el que usamos dicha funcionalidad debe tener permitido el uso de la Fullscreen API.

Para detectar el estado de nuestra pantalla completa disponemos del evento fullscreenchange que nos permitirá detectar un cambio sobre esta funcionalidad. Pudiendo conocer en todo momento si estamos en modo normal o modo pantalla completa.


document.addEventListener("fullscreenchange", function () {
    fullscreenState.innerHTML = (document.fullscreen)? "" : "not ";
}, false);

document.addEventListener("mozfullscreenchange", function () {
    fullscreenState.innerHTML = (document.mozFullScreen)? "" : "not ";
}, false);

document.addEventListener("webkitfullscreenchange", function () {
    fullscreenState.innerHTML = (document.webkitIsFullScreen)? "" : "not ";
}, false);

Y además, disponemos de una pseudo-clase CSS que nos permite condicionar ciertos aspectos de nuestra pantalla completa.


html:-moz-full-screen {
    background: red;
}

html:-webkit-full-screen {
    background: red;
}

html:fullscreen {
    background: red;
}

Personalmente, creo que es una funcionalidad muy interesante y me ha llamado mucho la atención que se haya movido tan rápido y que podamos usarla con tantos navegadores en tan poco tiempo. Aunque al parecer, Microsoft aún no tiene claro si lo va a implementar debido a que Windows 8 ya está pensado para trabajar con Internet Explorer 10 en modo pantalla completa siempre… otra vez :(

Más Info

Detectando inserciones DOM con Javascript y animaciones CSS

8 may

+ 3

Ayer, David Walsh nos mostraba una técnica para detectar elementos insertados en nuestro DOM mediante animaciones CSS. Para ello usaremos javascript, pero no el elemento “deprecated” DOMNodeInserted de la DOM Event Reference.

Veamos el código

<ul id="parentElement"></ul>
<style type="text/css">
/* Definimos las animaciones */

/* La estándar */
@keyframes nodeInserted {
from { clip: rect(1px, auto, auto, auto); }
to { clip: rect(0px, auto, auto, auto); }
}

/* La de Firefox ¬¬ */
@-moz-keyframes nodeInserted {
from { clip: rect(1px, auto, auto, auto); }
to { clip: rect(0px, auto, auto, auto); }
}

/* La de WebKit ¬¬! */
@-webkit-keyframes nodeInserted {
from { clip: rect(1px, auto, auto, auto); }
to { clip: rect(0px, auto, auto, auto); }
}

/* La de IE ¬¬!! */
@-ms-keyframes nodeInserted {
from { clip: rect(1px, auto, auto, auto); }
to { clip: rect(0px, auto, auto, auto); }
}

/* La de Opera ¬¬!!!*/
@-o-keyframes nodeInserted {
from { clip: rect(1px, auto, auto, auto); }
to { clip: rect(0px, auto, auto, auto); }
}

/*
Definimos las duraciones
para toooodos los navegadores
*/
#parentElement > li {
	animation-duration: 0.001s;
	-o-animation-duration: 0.001s;
	-ms-animation-duration: 0.001s;
	-moz-animation-duration: 0.001s;
	-webkit-animation-duration: 0.001s;

	animation-name: nodeInserted;
	-o-animation-name: nodeInserted;
	-ms-animation-name: nodeInserted;
	-moz-animation-name: nodeInserted;
	-webkit-animation-name: nodeInserted;
}

</style>
<script type="text/javascript">
	var insertListener = function(event){	
		// Detectamos el nombre de la animación lanzada
		if (event.animationName == "nodeInserted") {
			console.warn("Another node has been inserted! ", event, event.target);
			}
		}

// Asociamos los la anterior funcionalidad al evento "animationstart"
document.addEventListener("animationstart", insertListener, false); // standard + firefox
document.addEventListener("MSAnimationStart", insertListener, false); // IE
document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari
</script>

Como podemos ver en el código, la técnica usada pasa por definir las animaciones CSS (en todos y cada uno de los navegadores, bufff! ) a las que se les asigna un nombre, después, usando la gestión de eventos asociamos (otra vez para los diferentes navegadores ¬¬) la función insetListener() que se encargará de comprobar que al accionar el evento animationstart se esté accionando la animación previamente definida. A nivel académico, me parece realmente interesante, aunque quizás un poco laborioso para implementar en el día a día.

Speech Javascript API, habla con las páginas web

8 ene

+ 5

La llegada de Internet a los móvil h a producido una gran serie de cambios en los lenguajes de programación que usamos para crear páginas web, hace unos días vimos como la W3C publicaba el primer borrador para controlar el estado de la batería mediante Javascript. Y ahora os traigo el primer borrador no oficial de la especificación javascript para dotar de voz y hacer que nuestras páginas nos entiendan.

Se trata de una propuesta por parte del equipo de desarrollo de Google para dotar a los navegadores de herramientas de síntesis y de reconocimiento de voz. Haciendo posible que podamos hablar con páginas web y que estas nos respondan.

Speech Javascript API

descarga
(Ver Imagen)

La API se compone de 2 interfaces:

  • SpeechReco(), que nos permite grabar al usuario directamente desde el navegador.
  • TTS(), que nos permitirá convertir texto en voz directamente.

Ver código

Que mejor que un poco de código para hacernos una idea de lo que podría ser adaptar nuestra página a esta nueva tecnología:

SpeechReco

<script type="text/javascript">
    var sr = new SpeechReco(); // Nuevo interface
    sr.onresult = function(event) {
      var q = document.getElementById("q");
      q.value = event.result[0].transcript; // Devolvemos la transcripción del mensaje
      q.form.submit();
    }
  </script>

  <form action="http://www.example.com/search">
  <input type="search" id="q" name="q"/>
  <input type="button" value="Speak" onclick="sr.start()"/> // Iniciamos la grabación
  </form>

TTS


  <script type="text/javascript">
     var tts = new TTS(); //Nuevo interface
     function speak(text, lang) {
        tts.text = text; // Indicamos el texto
        tts.lang = lang; // Indicamos el idioma
        tts.play(); // Hacemos hablar a nuestro navegador
     }
     speak("Hello world.", "en-US"); // Hola mundo :D
  </script>

No parece muy complicado, ¿no? :D
Esto haría que publicar en tu WordPress pudiera ser una tarea que haces mientras vas al trabajo en coche, por ejemplo :D

syze, añade @media queries avanzadas y cross browser con javascript

5 ene

+ 4

Syze, es una librería javascript cross-browser, cross-device y cross-library que nos permitirá disponer de una opción funcional para disfrutar de los @media queries de CSS3. Y todo ello en menos de 1KB.

Instalación

Añadimos la llamada al CDN (o descargamos el fichero JS y lo servimos desde nuestro servidor).

<script src="//rezitech.github.com/syze/syze.min.js"></script>

Y añadimos una línea Javascript que indicará las opciones de las que queremos disponer en nuestro CSS.

syze.sizes(320, 480, 768, 1024, 1920);

Esto nos permitirá trabajar con un sistema de clases que podremos condicionar, haciendo que se ajuste a cada dispositivo dependiendo de su tamaño y su orientación.

body { background: no-repeat center center; }
.is320  body { background-image: url(mobile-tall-128x128.png); }
.is480  body { background-image: url(mobile-wide-128x128.png); }
.is768  body { background-image: url(tablet-tall-256x256.png); }
.is1024 body { background-image: url(tablet-wide-256x256.png); }
.is1920 body { background-image: url(hdsize-wide-512x512.png); }

Podéis ver un ejemplo directamente desde aquí (redimensionar la página).

Battery Status API, controla la carga de la batería de tus usuarios con Javascript

5 ene

+ 4

El pasado día 29 de Noviembre la W3C publicó el primer borrador sobre el que se está trabajando para permitir conocer el estado de la batería directamente desde el navegador, algo que actualmente no hay forma de hacer. Esta opción, que puede parecer una tontería puede ayudarnos muchos en casos de operativas delicadas, ya que podríamos advertir al usuario antes de que la batería se termine.

Por el momento, solo Mozilla Aurora 11, una futura versión de Firefox, lo incluye entre muchas otras nuevas funcionalidades.

La API dispone de una serie de atributos que cuelgan directamente del elemento window.navigator.

window.navigator.battery

Por el momento, ya que solo está disponible en Mozilla Aurora 11 y la API no está del todo definida tendremos que usarlo con el prefijo moz como ya nos tienen acostumbrados. Por lo tanto pasaría a ser window.navigator.mozBattery.

El nuevo objeto dispone de una serie de atributos que nos permitirá conocer ciertos datos sobre el estado de la batería:

  • charging (boolean): true si la batería está cargando y false si no lo está.
  • chargingTime(int): Número de segundos en los que se estima que la batería esté cargada.
  • dischargingTime(int): Número de segundos en los que se estima que la batería se descargará y entraremos en modo suspensión (o apagado).
  • level(int): Escala de 0-10 que indica el estado de carga de la batería, siendo 0 completamente descargada y 10 completamente cargada.

Además, disponemos de una serie de eventos que podremos controlar para condicionar acciones a ellos:

  • onchargingchange
  • onchargingtimechange
  • ondischargingtimechange
  • onlevelchange

Una interesante propuesta para mejorar, sobretodo las aplicaciones móviles web con posibilidades nuevas y realmente útiles.

POM: Programación Orientada a Maquetadores

25 jul

+ 20

Entre diseñadores web y desarrolladores web siempre ha habido una línea un tanto difusa entre las funciones de uno y las funciones de otros. En esa línea difusa aparece el perfil de maquetador que en muchas empresas recae entre las funciones de uno o de otro.

Si nos ponemos tiquismiquis podemos sacar muchos más perfiles, pero para este artículo nos bastará con estos 3  :D

Proceso de creación

Para entendernos un poco mejor, explico lo que entiendo por un proceso de creación de una aplicación web, partiendo de que se haya hecho (o no…) un buen análisis, con su correspondiente toma de requerimientos y si ya estás en una empresa seria de verdad, un proceso de validación de prototipos, y especificaciones… pero solo si es una empresa seria de verdad, no vale con ir de ello…

En ese punto, una vez aprovado todo por el cliente, remarcado y explicado perfectamente lo que se ha pedido y lo que se ha de entregar, se comienza a trabajar.

En este punto, los diseñadores empiezan a darle forma a esos prototipos, esos wireframes que el usuario a validado y que espera recibir. Una vez terminados estos diseños, generalmente en formato imagen, se le muestran al usuario para que valide el diseño de la página y pasemos a darle funcionalidad a la misma. (Ojo!, creo que estoy entrando en un mundo utópico rodeado de unicornios y dragones… :D).

Vale, ya hemos validado con el usuario el diseño y la funcionalidad que desea para su nueva y flamante nueva aplicación web, ha sido un proceso duro, pero nos permite disponer de toda la información necesaria para empezar y no tener que volver a molestar al usuario, salvo las notificaciones periódicas que se planifiquen.

En este punto, el diseño se pasa a los maquetadores, encargados de convertir ese diseño en el HTML que el usuario podrá ver en su navegador, este HTML no contendrá ninguna funcionalidad, únicamente habrá HTML y CSS.

En este punto, entramos una zona pantanosa, ya que nos encontramos código javascript que necesita el diseño para ser funcional (sliders, autocompletes, ….). Soy de los que cree que esta responsabilidad debería caer en el maquetador, ya que es el que está más cerca del diseñador para saber que funcionamiento ha de tener esa porción de web concreta.

Por otro lado, nos encontramos con que hay ciertas funcionalidades que afectan, tanto al maquetador como al desarrollador web, por ejemplo los autocompletes (suggest), validación de formularios, … esta funcionalidad es a veces un poco difusa. En este punto entra lo que yo llamo, en alarde de originalidad POM (Programación Orientada a Maquetadores).

POM: Programación Orientada a Maquetadores

Se trata de ofrecer al maquetador una serie de herramientas que le permita añadir funcionalidad básica al HTML sin necesidad de tocar una sola línea de Javascript. Básicamente se trata de generar componentes autónomos que lean el HTML y los atributos especiales que este HTML ha de tener.

Hace ya mucho tiempo, publiqué un ejemplo de validación de formularios con jQuery que seguía esta metodología. Se basaba en indicar a cada elemento de que tipo de validación requería para comprobar los datos de entrada. A grandes rasgos, vemos que usando el class de los atributos <input />, <select />,… informábamos el tipo de validación.

Atributos data-*

Entonces llegó HTML5 y sus atributos data-*, unos atributos que abren un abanico de posibilidades, y aunque antes me daban un poco de miedo, ahora disfruto con ellos :D

Los atributos data-*, nos permiten dotar a nuestros elementos de un montón de datos que podemos usar en nuestro código javascript, de forma que podremos construir un código capaz de trabajar con ellos y construirse en función de ellos.

Veamos un ejemplo:

<input type="text" class="autocomplete estilobonito" data-max-items="15" data-type="clientes" data-min-length="3" />

// jQuery
$("input.autocomplete").bind(function(){

	// Recogemos valores
	var $this = $(this),
	 	$value = $this.val(),
		$maxitems = $this.data("max-items") || 5,
		$type = $this.data("type") || "compras", 
		$minlength = $this.data("min-length") || 5;
	
	
	/* Funcionalidad */
	
	// Salimos si ha pulsado menos de $minlength carácteres
	if ($value.length < $minlength) return;
	
	jQuery.getJSON("http://miservicio.com/", {
		type: $type,
		items: $maxitems,
		value: $value
	},function(){
		/* LO QUE QUIERAS HACER*/
	});
});

Como podemos ver, nos permita acceder a ellos fácilmente, sin jQuery y para IE es igual de fácil.

¿Donde está la gracia?

La gracia está en hacer el código lo más reutilizable posible, haciendo que nos permita configurar nuestros elementos HTML de forma fácil. En mi caso personal, esta programación ha conseguido descargarme bastante de trabajo que antes hacía yo para que ahora los maquetadores/diseñadores puedan configurar.

Por experiencia, puedo decir que siempre terminas modificando el código y adaptando el código a las diferentes necesidades del diseño, pero se convierte en una tarea más sencilla y fácil de depurar.

Un ejemplo que estamos usando y que nos funciona muy bien, a ver si un día puedo implementar una versión de demo para que la veáis, es un autocomplete usando el de jQuery UI, capaz de diferenciar entre 3 o 4 tipos diferentes de datos y 3 o 4 salidas diferentes que comparten prácticamente todo el código.

Esto, añadido al modelo de programación modular que vimos hace ya muuucho tiempo, nos está dando unos muy buenos resultados, tanto a la hora de desarrollar como a la hora de depurar la aplicación.

Qwery, el mini selector CSS3

24 mar

+ 1

Dustin Diaz presenta un nuevo selector CSS3 que parece ser el más ligero de los actuales. Con tan solo 6, 7kb, tenemos la posibilidad de recorrer el DOM de nuestra página realizando búsquedas usando los selectores CSS1, CSS2 y CSS3 disponibles. Para ello se ha basado en el ya mítico script de Simon Willison que publicó en 2003 (getElementsBySelector()) del que han surgido otros tantos. [Descargar]

$script.js, otra librería de Javascript ondemand

21 feb

+ 1

Dustin Diaz ha publicado su propia librería javascript para cargar javascript cuando realmente lo necesitemos.

$script('analytics.js');
$script('library.js', function() {
  // do stuff with library.
});

$script.js, nos permite añadir un funcionalidad que será ejecutada al cargar el fichero Javascript que estemos solicitando. Lo que nos permitirá cargar más JS, o ejecutar directamente el código que acabamos de cargar.

$script('yui-base.js', function() {
 // do stuff with base...
 $script(['yui-anim.js', 'yui-connect.js'], function() {
 // do stuff with anim and connect...
 });
 $script('yui-drag.js', function() {
 // do stuff with drag...
 });
});

No es algo nuevo, hace ya tiempo vimos una versión simple de como conseguir esto, y vimos como IncludeJS además nos devolvía el contenido comprimido, pero nunca está de mal conocer otras alternativas.