Contenido

Librerías para generar gráficas con Javascript

26 Jun

+ 11

Pocas son las cosas que no podamos hacer con Javascript, y la de hacer gráficas no es una de ellas.

Protochart2
(Ver Imagen)

Gracias a alguna de estas librerías, hacer nuestras gráficas más elegantes para nuestros usuarios es realmente sencillo:

  1. Flot [jQuery]
  2. fgCharting [jQuery]
  3. jQuery Sparklines [jQuery]
  4. jqPlot [jQuery]
  5. TufteGraph [jQuery]
  6. jQuery Google Charting [jQuery]
  7. ProtoChart [Prototype]
  8. JSXGraph [Prototype o jQuery]
  9. Protovis [Native JS]
  10. PlotKit [Nativa JS]

Me ha parecido muy raro que no hubiera nada para MooTools, así que he estado buscando algo para los que desarrollamos con este framework.

  1. MooChart
  2. TabletoChart
  3. MooWheel

¿Me he dejado alguna que valga la pena conocer?

Mozilla JetPack, todos podemos hacer extensiones para Firefox

25 May

+ 7

Mozilla JetPack es una extensión para Firefox que permite desarrollar extensiones mediante el uso de tecnologías de desarrollo web (HTML, CSS, Javascript), aprovechándose de la potencia de Ajax y los nuevos estándares multimedia (<canvas />, <video /> y <audio />) realizar extensiones para Firefox es muy sencillo y sobretodo muy potente.

logo
(Ver Imagen)

Gracias a la integración con jQuery, el desarrollo de extensiones será realmente sencillo y la pequeña API, será más que suficiente para hacer realidad esas ideas que tenemos en mente.

La facilidad de integrar librerías externas (Google Maps, Twitter, Delicious.com,…) hará que nuestro navegador esté más conectado que nunca.

Veamos un ejemplo:

function GmailNotifier(doc){
  $(doc).click( this.goToInbox );
  this.update( doc );
  setInterval( function(){
    this.update(doc);
  }, 60*1000 );
}

GmailNotifier.prototype = {
  goToInbox: function(){
    jetpack.tabs.open("http://mail.google.com");
    jetpack.tabs[ Jetpack.tabs.length-1 ].focus();
  },

  update: function(doc){
    var url = "http://mail.google.com/mail/feed/atom";
    doc = $(doc);
    $.get( url, function(xml){
      var el = $(xml).find("fullcount"); // Unread message count

      if( el ){
        var count = el.get(0).textContent;
        doc.find("#count").text( count );
      }
      else{
        doc.find("#count").text( "Login" );
      }
    });
  }
}

jetpack.statusBar.append({
  html: '<img src="http://mail.google.com/mail/images/favicon.ico"><span id="count"></span>',
  onReady: function(doc){
    var gmail = new GmailNotifier(doc);
    $("#count", doc).css({
      position: "absolute",
      left: 4, top: 8,
      fontSize: "10px",
      cursor: "pointer",
      backgroundColor: "rgba(255,255,255,.8)"
    });
  },
  width: 20
});

Este código nos mostrará un icono de gMail con el número de emails pendientes por leer en la parte inferior de nuestro Firefox (statusbar). Revisa el tutorial para ver que cosillas se pueden hacer.

Ya tenemos una buena serie de demos desarrolladas por que extendamos nuestro navegador.

Gracias Edu.

actuR.com, optimizador de código

20 May

+ 7

Carlos Sanches me avisa via email sobre la nueva aplicación en la que ha estado trabajando. acutR.com, un optimizador de código que nos permite desde optimizar código HTML hasta minimizar nuestro código CSS. Muy recomendable para ahorrarnos esos minutos de depuración :D

Dale un toque de color (animado) a tu web con jQuery

19 May

+ 2

En SentidoWeb publican un interesante plugin para jQuery que nos permite crear un efecto de Glow para adornar elementos de nuestras aplicaciones web. El resultado, además de impresionante es sorprendente debido a la técnica usada, una imagen grande con la gama de colores y la va moviendo detrás del formulario.[Demo]

jQuery vs MooTools, ¿cual es mejor?

19 May

+ 16

Aunque se intente camuflar con frases como “No son para lo mismo”, “Las dos son muy buenas”,… hay una pregunta latente detrás que siempre posiciona en un bando u otro a los desarrolladores web. ¿Cual es mejor? Esta es la pregunta a la que le han buscado una solución intentando ser lo más objetivo posible. Yo no me voy a posicionar, por que no son para lo mismo y las dos son muy buenas :D

Extiende Google Analytics con jQuery

18 May

+ 10

El uso de Google Analytics en aplicaciones web es algo muy común y cada vez más corriente. Principalmente por que es un servicio gratis y ofrece una gran cantidad de información relevante sobre el uso de las mismas.

Debido a este crecimiento, es normal encontrarnos artículos como este de Carron Media en el que nos muestran como extender las posibilidades de Google Analytics con jQuery. Mediante una serie de pequeñas porciones de código podremos controlar los enlaces salientes o los ficheros que se decargan de nuestros sitios web.

<script type="text/javascript">
$(document).ready(function(){
// Cargamos el fichero JS
    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
    $.getScript(gaJsHost + "google-analytics.com/ga.js", function(){

        try {
	// Nos identificamos con nuestro cógico.
            var pageTracker = _gat._getTracker("UA-xxxxxxx-x");
            pageTracker._trackPageview();
        } catch(err) {}

	// Definimos los tipos de ficheros que vamos a registrar.
        var filetypes = /\.(zip|exe|pdf|doc*|xls*|ppt*|mp3)$/i;

	// Recorremos todos los enlaces
        $('a').each(function(){
	// Capturamos el atributo href.
            var href = $(this).attr('href');

		// Si es un enlace saliente
            if ((href.match(/^https?\:/i)) && (!href.match(document.domain))){
                $(this).click(function() {
                    var extLink = href.replace(/^https?\:\/\//i, '');
                    pageTracker._trackEvent('External', 'Click', extLink);
                });
            }
            // Si es un email (mediante mailto)
            else if (href.match(/^mailto\:/i)){
                $(this).click(function() {
                    var mailLink = href.replace(/^mailto\:/i, '');
                    pageTracker._trackEvent('Email', 'Click', mailLink);
                });
            }
            // Si es una decarga.
            else if (href.match(filetypes)){
                $(this).click(function() {
                    var extension = (/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined;
                    var filePath = href.replace(/^https?\:\/\/(www.)mydomain\.com\//i, '');
                    pageTracker._trackEvent('Download', 'Click - ' + extension, filePath);
                });
            }
        });
    });
});
</script>

Tambien puedes descargarlo para usar en tu aplicación.

Crea un chat como el de gMail/Facebook con jQuery

15 May

+ 5

Si estás buscando un chat para tu aplicación web, no dejes pasar este similar a los implementados en gMail o Facebook. Se trata de una implementación con jQuery y PHP que nos facilitará el trabajo de crearlo desde 0 nosotros mismo. El resultado, lo puedes ver en este ejemplo.[Descargar]

Optimizando el rendimiento de nuestros scritps jQuery

13 May

+ 15

Que soy un fan de jQuery no es una novedad, pero si que es una novedad el que no lo uso de la forma más correcta. Por lo menos así lo ven la gente de ArtzStudio, que nos muestran una serie de indicaciones con el fin de optimizar el uso del CPU el usuario mejorando el rendimiento de nuestros scripts.

1) Siempre desciende desde un #ID

Siempre el selector más rápido y que menos iteraciones produce es la búsqueda por un #id, ya que simplemente lanza un document.getElementById(), lo que al ser nativo nos asegura un tiempo de respuesta mínimo y un mínimo consumo de proceso.

<div id="content">
	<form method="post" action="/">
		<h2>Traffic Light</h2>
		<ul id="traffic_light">
			<li><input type="radio" class="on" name="light" value="red" /> Red</li>
			<li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li>
			<li><input type="radio" class="off" name="light" value="green" /> Green</li>
		</ul>
		<input class="button" id="traffic_button" type="submit" value="Go" />
	</form>
</div>

Con el código anterior, si queremos coger el elemento #traffic_button, siempre nos será más rápido hacerlo directamente que medainte la class del mismo elemento.

// Más lento
var traffic_button = $('#content .button');

// Más rápido
var traffic_button = $('#traffic_button');

Seleccionar varios elementos

Si por contra, necesitamos seleccionar una serie de elementos, siempre que podamos debemos hacerlo partiendo de un #id, de esta forma nos aseguramos una iteración más ajustada.

var traffic_lights = $('#traffic_light input');

Aclaración

Hay que destacar que esto afectará positivamente al rendimiento, aunque el uso de selectores más complejos permiten mejorar la flexibilidad de nuestros scripts. Es importante tener en cuenta esta recomendación, pero no se puede aplicar a todos los casos.

2) Usa tags delante de las clases

Al contrario que con el #id, en el que se innecesario indicar el tag asociado a ese #id (div#page), esto no tiene sentido y además penaliza a lo que comentamos en el punto 1. En la selección de clases, es recomendable indicar el tag del elemento solicitado ya que al hacer uso de document.getElementsByTagName() para localizarlos acotamos previamente los elementos en los que buscar las clases solicitadas. Con el mismo código:

<div id="content">
	<form method="post" action="/">
		<h2>Traffic Light</h2>
		<ul id="traffic_light">
			<li><input type="radio" class="on" name="light" value="red" /> Red</li>
			<li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li>
			<li><input type="radio" class="off" name="light" value="green" /> Green</li>
		</ul>
		<input class="button" id="traffic_button" type="submit" value="Go" />
	</form>
</div>

Si queremos seleccionar el elemento radio con class on, la opción rápida sería la siguiente:

var active_light = $('#traffic_light input.on');

3) Usa la caché de objetos

Coger el hábito de guardar una variable con el valor de un objeto jQuery nos evita realizar una serie de comprobaciones innecesarias y que en scripts pesados pueden suponer un aumento de rendimiento preocupante.

// NO
$('#traffic_light input.on).bind('click', function(){...});
$('#traffic_light input.on).css('border', '3px dashed yellow');
$('#traffic_light input.on).css('background-color', 'orange');
$('#traffic_light input.on).fadeIn('slow');

// SI
var $active_light = $('#traffic_light input.on');
$active_light.bind('click', function(){...});
$active_light.css('border', '3px dashed yellow');
$active_light.css('background-color', 'orange');
$active_light.fadeIn('slow');

4) Aprovechate del encadenamiento

El encadenamiento pese a producir un amasijo de código que no contribuye a mejorar la lectura del código hace que nuestro Javascript sea más ligero y puede ayudar a mejorar el rendimiento de nuestros scritps. Veamos el ejemplo anterior:

var $active_light = $('#traffic_light input.on');
$active_light.bind('click', function(){...})
	.css('border', '3px dashed yellow')
	.css('background-color', 'orange')
	.fadeIn('slow');

5) Usa subqueries siempre que puedas.

Si debemos realizar varias búsquedas sobre un elemento es altamente recomendable realizar un uso intensivo del método find() de jQuery para realizar las búsquedas. Mejoraremos el tiempo de respuesta al evitarnos búsquedas previas ya realizadas.

Usando el código HTML anterior podemos hacer lo siguiente:

var $traffic_light = $('#traffic_light'),
	$active_light = $traffic_light.find('input.on'),
	$inactive_lights = $traffic_light.find('input.off');

6) Limita la manipulación de DOM

Ya vimos hace un tiempo que la manipulación directa del arbol DOM es muy costoso y lento. Por eso el limitar el uso de esta técnica nos favorecerá a la hora de procesar nuestros scripts.

// Más lento
var top_100_list = [...], // assume this has 100 unique strings
	$mylist = $('#mylist'); // jQuery selects our <ul> element

for (var i=0, l=top_100_list.length; i<l; i++) {
	$mylist.append('<li>' + top_100_list[i] + '</li>');
}

// Más rápido
var top_100_list = [...], // assume this has 100 unique strings
	$mylist = $('#mylist'), // jQuery selects our <ul> element
	top_100_li = ""; // This will store our list items

for (var i=0, l=top_100_list.length; i<l; i++){
	top_100_li += '<li>' + top_100_list[i] + '</li>';
}
$mylist.html(top_100_li);

7) Aprovechate de la delegación de eventos

Mientras no se diga lo contrario los eventos se propagan hasta el elemento padre. Esto tiene una utilidad realmente interesante y nos puede ayudar a evitar tener que realizar busquedas muy concretas.

// Menos eficiente
$('#entryform input).bind('focus', function(){
	$(this).addClass('selected');
}).bind('blur', function(){
	$(this).removeClass('selected');
});

// Más eficiente
$('#entryform).bind('focus', function(e){
	var cell = $(e.target);  // e.target almacena el nodo que ha lanzado el evento.
	cell.addClass('selected');
}).bind('blur', function(e){
	var cell = $(e.target);
	cell.removeClass('selected');
});

8 ) Elimina consultas innecesarias

Prácticamente todos los puntos anteriores, nos dan soluciones para realizar el mínimo de consultas posibles realizando las mismas funciones. Pero este punto ataca más directamente a llamadas innecesarias como por ejemplo el $(document).ready(); que podemos evitar.

// Menos eficiente
$(document).ready(function(){
	mylib.article.init();
});

// Más eficiente
<script type="text/javascript>
mylib.article.init();
</script>
</body>

Como vemos la clave está en lanzar el <script /> justo antes de cerrar el tag </body> lo que nos asegura que todos los elementos que podemos necesitar están ya cargados en el árbol DOM.

9) Piensa en usar $(window)load()

Aunque $(document).ready() es muy útil y potente, no espera a que se carguen todos los elementos (imagenes, flash,..) para ejecutarse. Lo que puede producir un problema ya que está cargando nuestros scripts y además el navegador está trabajando en mostrar por pantalla otros elementos.

En estos casos, quizas nos sería conveniente usar $(window).load().

$(window).load(function(){
...
});

Esta función, esperará a cargar toda la página (imagenes, flash,…) incluidos, para lanzar nuestros scripts.

10) Comprime tu código

Este punto es discutible ya que al comprimir tu código estás haciendo que el navegador del usuario lo haya de descomprimir, lo que puede incrementar el rendimiento requerido frente a la velocidad de carga del script. Es interesnate tener en cuenta los factores que intervienen para decidir que acción realizar.

11) Aprenderte la librería

A estas alturas seguro que ya la conoces, pero no está de más tener a mano alguna Cheat Sheet(.pdf) para evitar caer en soluciones poco optimizadas.

12) Usa html() con cabeza

Como nos recuenda Joseanpg en los comentarios, el uso de html() nos penaliza sustancialmente el rendimiento de nuestros scripts. jQuery, al contrario de MooTools y Prototype (no he mirado los demás) no injecta el código HTML mediante innerHTML, sinó que construye los elementos DOM y los añade al nodo indicado.

Este proceso es más lento que usar un simple innerHTML aunque nos puede provocar problemas en insercciones en las que necesitemos refrescar el arbol DOM.

En la mayoría de casos, la mejor opción es usar innerHTML en nuestros scripts ya que añaden elementos perfectamente a nuestro arbol DOM y es realmente rápido. Para todo lo demás, html().

jPlayer el reproductor de MP3 personalizable por CSS

7 May

+ 19

jPlayer es un plugin para jQuery que nos permite crear un reproductor de MP3 que irá incrustado en nuestra página web, la gracia de este reproductor es que mediante CSS podemos personalizarlo y hacer que se integre perfectamente en nuestra aplicación web.

jplayer
(Ver Imagen)

Podeis ver una serie de demos aquí y descargar el plugin desde aqui.

Simulando la gravedad con jQuery

5 May

+ 2

Impresionante tutorial para consegir simular el efecto de la gravedad en nuestros elementos HTML usando jQuery. [Demo][Descargar]