<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mundo Geek &#187; Javascript</title>
	<atom:link href="http://mundogeek.net/etiqueta/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://mundogeek.net</link>
	<description>Mundo geek, bitácora sobre todo lo geek: software, gadgets, tecnología, internet, ...</description>
	<lastBuildDate>Fri, 25 May 2012 14:51:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>on y off, los nuevos métodos para vincular y desvincular manejadores en jQuery</title>
		<link>http://mundogeek.net/archivos/2011/11/19/on-y-off-los-nuevos-metodos-para-vincular-y-desvincular-manejadores-en-jquery/</link>
		<comments>http://mundogeek.net/archivos/2011/11/19/on-y-off-los-nuevos-metodos-para-vincular-y-desvincular-manejadores-en-jquery/#comments</comments>
		<pubDate>Sat, 19 Nov 2011 10:25:02 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[bind]]></category>
		<category><![CDATA[delegate]]></category>
		<category><![CDATA[diferencias]]></category>
		<category><![CDATA[eventos]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[live]]></category>
		<category><![CDATA[manejadores]]></category>
		<category><![CDATA[off]]></category>
		<category><![CDATA[on]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=7446</guid>
		<description><![CDATA[Una de las novedades destacadas de la versión 1.7 de jQuery, publicada hace un par de semanas, son las funciones .on() y .off(), que tienen como objetivo unificar los distintos métodos que teníamos disponibles para asignar y desasignar manejadores a eventos: .bind(), .unbind(), .delegate(), .undelegate(), .live() y .die(). Es conveniente utilizar desde ya este nuevo [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las novedades destacadas de la versión 1.7 de <a href="http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/" title="jQuery, la librería JavaScript para escribir menos y hacer más">jQuery</a>, publicada hace un par de semanas, son las funciones <code>.on()</code> y <code>.off()</code>, que tienen como objetivo unificar los distintos métodos que teníamos disponibles para asignar y desasignar manejadores a eventos: <code>.bind()</code>, <code>.unbind()</code>, <code>.delegate()</code>, <code>.undelegate()</code>, <code>.live()</code> y <code>.die()</code>.</p>
<p>Es conveniente utilizar desde ya este nuevo par de métodos; no solo porque simplifican la API, sino porque es probable que en próximas versiones el resto de funciones termine por desaparecer. Tanto es así, que si echamos un vistazo al <a href="https://github.com/jquery/jquery/blob/1.7/src/event.js">código de la nueva versión</a>, veremos que la implementación de los antiguos métodos se ha sustituido ya por simples llamadas a <code>.on()</code> y <code>.off()</code>.<span id="more-7446"></span></p>
<p>Los nuevos métodos tienen la siguiente sintaxis:</p>
<pre name="code" class="javascript">$(elementos).on(eventos [,selector] [,datos], manejador);
$(elementos).off([eventos] [,selector] [,manejador]);</pre>
<p>Si no pasamos ningún selector como parámetro, <code>.on()</code> es similar a <code>.bind()</code>, donde simplemente asociamos el manejador a <code>elementos</code>. Esto es también lo que hacen <code>.click()</code>, <code>.hover()</code>, <code>.change()</code>, <code>.submit()</code> y el resto de abreviaturas.</p>
<pre name="code" class="javascript">$('tr').on('click', resaltar);
$('tr').bind('click', resaltar);</pre>
<p>Cuando se pasa un selector como parámetro, es similar a <code>.delegate()</code>, donde el manejador se añade a <code>elementos</code>, pero lo que comprobamos es si se produce el evento en los descendientes filtrados con <code>selector</code>. Cuando se produce el evento, se comprueba cada uno de los ancestros en el DOM hasta encontrar el que tiene el manejador adecuado. El tratamiento del evento se delega entonces al ancestro; de ahí su nombre. Esto puede ser útil, por ejemplo, si tenemos miles de filas: podemos asociar el manejador a la tabla, en lugar de tener que hacerlo sobre todas y cada una de las filas, lo cuál puede ser tremendamente lento.</p>
<pre name="code" class="javascript">$('table').on('click', 'tr', resaltar);
$('table').delegate('click', 'tr', resaltar);</pre>
<p>El uso de <code>.live()</code>, que es parecido a <code>.delegate()</code>, aunque usando <code>document</code> como raíz, no está recomendado, porque el evento tendría que recorrer todos los ancestros hasta <code>document</code> en busca del manejador adecuado, haciéndolo muy lento cuando nuestra jerarquía es muy profunda. Aun así, si queremos, también podemos imitarlo:</p>
<pre name="code" class="javascript">$(document).on('click', 'tr', resaltar);
$('tr').live('click', resaltar);</pre>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushXml.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushJScript.js"></script><br />
<script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/11/19/on-y-off-los-nuevos-metodos-para-vincular-y-desvincular-manejadores-en-jquery/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>jQuery in Action</title>
		<link>http://mundogeek.net/archivos/2011/11/08/jquery-in-action/</link>
		<comments>http://mundogeek.net/archivos/2011/11/08/jquery-in-action/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 15:59:21 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[criticas]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[libros]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[reviews]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=7393</guid>
		<description><![CDATA[jQuery in Action Calificación: Autores: Bear Bibeault, Yehuda Katz Año: 2010 Editorial: Manning Segunda edición de este libro sobre jQuery perteneciente a la serie &#8220;in Action&#8221; de Manning. Lanzado a mediados del año pasado, gran parte del texto fue reescrito y se agregaron más de 100 páginas. Tal fue el trabajo realizado, que sus autores [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://mundogeek.net/wp-content/jquery-in-action.jpg" alt="jQuery in Action" align="left" style="margin-right:1em"/><a href="http://www.amazon.co.uk/gp/product/1935182323/ref=as_li_ss_tl?ie=UTF8&#038;tag=mundogeek-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=1935182323">jQuery in Action</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=mundogeek-21&#038;l=as2&#038;o=2&#038;a=1935182323" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /><br />
Calificación: <img src="http://mundogeek.net/wp-content/themes/mg5/bueno.png"/><br />Autores: Bear Bibeault, Yehuda Katz<br />
Año: 2010<br />
Editorial: Manning<br clear="all"/><br />
Segunda edición de este libro sobre <a href="http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/" title="Tutorial rápido de jQuery">jQuery</a> perteneciente a la serie &#8220;in Action&#8221; de Manning. Lanzado a mediados del año pasado, gran parte del texto fue reescrito y se agregaron más de 100 páginas. Tal fue el trabajo realizado, que sus autores comentaron que les llevó más tiempo terminar esta segunda edición que escribir el original.</p>
<p>jQuery in Action cuenta con 475 páginas organizadas en 2 partes, una primera sobre <a href="http://jquery.com/" title="jQuery">jQuery</a> en sí, y una segunda sobre la biblioteca de componentes <a href="http://jqueryui.com/" title="jQuery UI">jQuery UI</a>. También cuenta con un apéndice que trata conceptos avanzados de <a href="http://mundogeek.net/tutorial_de_javascript/" title="Tutorial de JavaScript">JavaScript</a>, necesarios para utilizar jQuery de manera efectiva, como objetos, funciones de orden superior, <em>closures</em> o cierres, y el concepto de que las variables y funciones de ámbito global son en realidad propiedades del objeto <code>window</code>. Como véis, temas de conversación apasionantes para determinado tipo de reunión social.<span id="more-7393"></span></p>
<p>El libro trata las versiones 1.4 de jQuery y 1.8 de jQuery UI, por lo que es bastante actual, comparado con el resto de libros del mercado. Entre las editoriales grandes, sólo conozco un libro aún más moderno, el <a href="http://www.amazon.co.uk/gp/product/1449393217/ref=as_li_ss_tl?ie=UTF8&#038;tag=mundogeek-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=1449393217">Head First jQuery</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=mundogeek-21&#038;l=as2&#038;o=2&#038;a=1449393217" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> de O&#8217;Reilly, de septiembre de este año, que todavía no he tenido ocasión de leer.</p>
<p>jQuery in Action está escrito de forma clara y concisa, con algún toque de humor, ejercicios, y ejemplos prácticos. Creo que es una buena lectura para iniciarse en la librería y para afianzar conceptos.</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/11/08/jquery-in-action/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Buenas prácticas con jQuery</title>
		<link>http://mundogeek.net/archivos/2011/08/16/buenas-practicas-con-jquery/</link>
		<comments>http://mundogeek.net/archivos/2011/08/16/buenas-practicas-con-jquery/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 18:28:40 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[consejos]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=7198</guid>
		<description><![CDATA[Algunos consejos prácticos que os pueden ser de utilidad después de leer mi tutorial rápido de jQuery. ¿Tienes cualquier otro consejo o sugerencia, o cualquier puntualización al respecto? Tu comentario será MUY bienvenido No abuses de $(document).ready Una de las primeras cosas que aprendemos en cualquier tutorial de jQuery es cómo y por qué utilizar [...]]]></description>
			<content:encoded><![CDATA[<p>Algunos consejos prácticos que os pueden ser de utilidad después de leer mi <a href="http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/" title="Tutorial de jQuery">tutorial rápido de jQuery</a>. ¿Tienes cualquier otro consejo o sugerencia, o cualquier puntualización al respecto? Tu comentario será MUY bienvenido <img src='http://mundogeek.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <span id="more-7198"></span></p>
<h2>No abuses de <code>$(document).ready</code></h2>
<p>Una de las primeras cosas que aprendemos en cualquier <a href="http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/" title="Tutorial de jQuery">tutorial de jQuery</a> es cómo y por qué utilizar <a href="http://api.jquery.com/ready/" title="Función ready de jQuery"><code>$(document).ready</code></a> y <code>$()</code> para inicializar nuestro código, en lugar del tradicional <code>window.onload</code> y su contrapartida en jQuery, <a href="http://api.jquery.com/load-event/"  title="Función load de jQuery"><code>$(window).load</code></a>.</p>
<pre name="code" class="javascript">$(document).ready(function() {
  // La magia ocurre aquí
});

$(function() {
  // La magia ocurre aquí
});

window.onload = function() {
  // La magia ocurre aquí
} 

$(window).load(function(){
   // La magia ocurre aquí
});</pre>
<p>La principal diferencia entre ambos métodos es que el evento <code>ready</code> se lanza cuando el navegador termina de cargar el árbol del documento (evento <code>DOMContentLoaded</code> en los navegadores más modernos), mientras que el manejador de <code>onload</code> se ejecuta cuando se termina de cargar todo el documento, incluidas las imágenes y los iframes.</p>
<p>Consecuentemente, habitualmente nos interesará colocar el código de inicialización en el manejador del evento <code>ready</code>, de forma que nuestra página parezca más rápida, al no tener que esperar el usuario a que cargue toda la página para poder usar la funcionalidad.</p>
<p>Sin embargo, hay ocasiones en las que el uso de <code>$(document).ready</code> puede ser contraproducente. Es el caso de funcionalidades que no son prioritarias, que pueden estar retrasando la carga de otras características más importantes, y que podemos postergar hasta después del evento <code>onload</code>.</p>
<p>Otro caso es el <em>binding</em> de eventos con <a href="http://api.jquery.com/live/" title="Función live de jQuery"><code>live</code></a> y <a href="http://api.jquery.com/delegate/" title="Función delegate de jQuery"><code>delegate</code></a>, funciones introducidas en las versiones 1.3 y 1.4.2 y que permiten agregar manejadores de eventos a elementos que aún no existen en el DOM. Si agregamos un manejador para aumentar el tamaño de la fuente de un párrafo al hacer clic sobre él y lo colocamos en el manejador de <code>$(document).ready</code>, tendremos que esperar a que cargue todo el DOM, mientras que si lo sacamos del manejador del evento <code>ready</code>, la funcionalidad estará activa en cuanto se cargue el elemento.</p>
<pre name="code" class="html">&lt;html&gt;
  &lt;head&gt;
    &lt;script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
      $('#mensaje').live('click', aumentarTamanyo);

      function aumentarTamanyo() {
        $(this).css('font-size', '200%');
      }
    &lt;/script&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;p id="mensaje"&gt;jQuery: The Write Less, Do More, JavaScript Library&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
<h2><code>preventDefault</code>, <code>stopPropagation</code> y <code>return false</code></h2>
<p>Otra de las cosas que se aprenden en los tutoriales de jQuery y que tampoco solemos cuestionar es el devolver <code>false</code> en un manejador para evitar que el navegador ejecute el comportamiento por defecto para el evento generado por el usuario. Podemos devolver <code>false</code> en el manejador del evento <code>click</code> de un enlace para evitar que se cargue la página enlazada, por ejemplo, o en el manejador de <code>submit</code> de un formulario para evitar que se envíe.</p>
<p>Esto último es muy común en funciones de validación de formularios:</p>
<pre name="code" class="html">&lt;html&gt;
  &lt;head&gt;
    &lt;script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
      $(function() {
        $('#frmLogin').submit(comprobarCampos);
      });

      function comprobarCampos() {
        if(!$('#usuario').val() || !$('#password').val()) {
          alert('Por favor, introduzca su nombre de usuario y contraseña');
          return false;
        }
      }
    &lt;/script&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;form id="frmLogin" action="login" method="post"&gt;
      &lt;label for="usuario"&gt;Usuario&lt;/label&gt;: &lt;input type="text" name="usuario" id="usuario"/&gt;
      &lt;label for="password"&gt;Contraseña&lt;/label&gt;: &lt;input type="password" name="password" id="password"/&gt;
      &lt;input type="submit" value="Entrar"/&gt;
    &lt;/form&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
<p>El ejemplo funciona perfectamente, y <code>return false</code> parece estar haciendo lo que queríamos. Sin embargo, en realidad, al devolver un valor <code>false</code> en el manejador, lo que estamos haciendo, además de prevenir la ejecución del comportamiento por defecto del navegador, es evitar que el evento se propague y que, por lo tanto, se ejecute el código de los manejadores de los padres para este evento.</p>
<p>Si sólo queremos evitar el comportamiento por defecto lo correcto es llamar a la función <a href="http://api.jquery.com/event.preventDefault/" title="Función preventDefault de jQuery"><code>preventDefault()</code></a> del objeto <code>event</code>. De igual manera, si sólo queremos evitar que se propague a los padres, llamaremos a la función <a href="http://api.jquery.com/event.preventDefault/" title="Función stopPropagation de jQuery"><code>stopPropagation()</code></a> del objeto <code>event</code>.</p>
<pre name="code" class="html">&lt;html&gt;
  &lt;head&gt;
    &lt;script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
      $(function() {
        $('#frmLogin').submit(comprobarCampos);
      });

      function comprobarCampos(event) {
        if(!$('#usuario').val() || !$('#password').val()) {
          alert('Por favor, introduzca su nombre de usuario y contraseña');
          event.preventDefault();
        }
      }
    &lt;/script&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;form id="frmLogin" action="login" method="post"&gt;
      &lt;label for="usuario"&gt;Usuario&lt;/label&gt;: &lt;input type="text" name="usuario" id="usuario"/&gt;
      &lt;label for="password"&gt;Contraseña&lt;/label&gt;: &lt;input type="password" name="password" id="password"/&gt;
      &lt;input type="submit" value="Entrar"/&gt;
    &lt;/form&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
<h2><code>each</code> y <code>map</code> para sustituir bucles</h2>
<p>Aunque un bucle nativo <a href="http://jsperf.com/jquery-each-vs-for-loop/31" title="Comparativa de rendimiento en varios navegadores de bucles nativos contra each">siempre será más rápido</a>, los tiempos por los que tenemos que preocuparnos en primer lugar son los de desarrollo y mantenimiento. Por este motivo, en ocasiones, es posible que prefieras utilizar las funciones <code>$.each</code>, <code>$.fn.each</code>, <code>$.map</code> y <code>$.fn.map</code> en lugar de usar bucles.</p>
<p>Aunque el siguiente ejemplo no es lo bastante complejo como para obtener ningún tipo de beneficio al utilizar estas funciones, os servirá para ver el aspecto de cada una de las alternativas</p>
<pre name="code" class="javascript">// Bucle for
var numeros = [1, 2, 3];
var numItems = numeros.length;
for(var i = 0; i &lt; numItems; i++) {
  numeros[i] = numeros[i] * numeros[i];
}

// Bucle for in
var numeros = [1, 2, 3];
for(var i in numeros) {
  numeros[i] = numeros[i] * numeros[i];
}

// Bucle for in con la lógica en una función
var numeros = [1, 2, 3];
for(var i in numeros) {
  numeros[i] = cuadrar(numeros[i]);
}

function cuadrar(num) {
    return num * num;
}

// $.each
var numeros = [1, 2, 3];
$.each(numeros, function(i, val) {
    numeros[i] = val * val;
});

// $.map
var numeros = [1, 2, 3];
numeros = $.map(numeros, function(val) {
    return val * val;
});

// $.map con la lógica en una función
var numeros = [1, 2, 3];
numeros = $.map(numeros, cuadrar);

function cuadrar(num) {
    return num * num;
}</pre>
<h2>Los bucles y los each no siempre son necesarios</h2>
<p>jQuery intenta facilitarnos trabajar con las colecciones de elementos. No es necesario que hagas algo así para ocultar todos los enlaces:</p>
<pre name="code" class="javascript">// Con $.fn.each
$('a').each(function () {
    $(this).hide();
});

// Con for in
var enlaces = $('a');
for(var i in enlaces) {
  $(enlaces[i]).hide();
};</pre>
<p>basta, simplemente, con que hagas esto:</p>
<pre name="code" class="javascript">$('a').hide();</pre>
<h2>HTML elegante</h2>
<p>Aunque un script no es lugar adecuado para tener nuestro código HTML, en ocasiones queremos crear nuevos elementos que añadir al DOM y no queremos o no podemos utilizar <a href="http://api.jquery.com/jQuery.template/">plantillas</a>. La manera más cándida de hacer esto sería algo como:</p>
<pre name="code" class="javascript">$('&lt;img src="http://www.jquery.com/logo.png" alt="Logo de jQuery" id="logo" onclick="alert(\'Este es el logo de jQuery\')"/&gt;')</pre>
<p>O una forma más &#8220;a lo jQuery&#8221;</p>
<pre name="code" class="javascript">$('&lt;img/&gt;').attr('src', 'http://www.jquery.com/logo.png').
  attr('alt', 'Logo de jQuery').
  attr('id', 'logo').
  click(function() {
    alert('Este es el logo de jQuery')
  });</pre>
<p>Pero desde jQuery 1.4 tenemos una forma aún mejor de hacer esto, pasando como segundo argumento un objeto cuyas propiedades son los nombres de los atributos, y al que podemos pasar también funciones de jQuery:</p>
<pre name="code" class="javascript">$("&lt;img/&gt;", {
  src: 'http://www.jquery.com/logo.png',
  id: 'logo',
  click: function() {
    alert('Este es el logo de jQuery')
  }
});</pre>
<h2>Encadenado y caché de selecciones</h2>
<p>Cada vez que utilizamos un selector en nuestro código, el engine de jQuery tiene que realizar operaciones más o menos costosas dependiendo del soporte nativo del navegador. Un selector por identificador, por ejemplo, es bastante rápido, dado que utiliza <code>document.getElementById</code> por debajo; selectores más complejos, como las pseudoclases, requieren de un mayor tiempo y mayores recursos para su procesado.</p>
<p>Lo ideal es no abusar demasiado de las búsquedas en el DOM y guardar el resultado en un variable, o bien aprovechar que las funciones suelen devolver la propia colección y utilizar cadenas de funciones.</p>
<pre name="code" class="javascript">// Mala idea, desde el punto de vista del rendimiento
$('a:not([href*=mundogeek.net])').attr('target', '_blank');
$('a:not([href*=mundogeek.net])').css('background-image', 'url("/img/externo.gif")');

// Cacheando en una variable
var enlacesExternos = $('a:not([href*=mundogeek.net])');
enlacesExternos.attr('target', '_blank');
enlacesExternos.css('background-image', 'url("/img/externo.gif")');

// Usando cadenas de funciones
$('a:not([href*=mundogeek.net])')
  .attr('target', '_blank')
  .css('background-image', 'url("/img/externo.gif")')</pre>
<h2><code>data</code> en lugar de <code>rel</code></h2>
<p>En ocasiones, y aunque no es recomendable abusar de ello, es posible que nos interese almacenar cierta información en el propio DOM. Esto se venía haciendo hasta ahora utilizando hacks como el uso dudoso del atributo <code>rel</code>, las clases, o los atributos con nombres inventados, que generaban HTML no válido.</p>
<p>Esto cambiará en HTML 5, con la introducción de los nuevos atributos data, pero jQuery viene ofreciendo desde su versión 1.2.3 un sistema aún mejor, que evita tener que interactuar con el DOM, pero que también soporta la lectura de estos nuevos atributos de HTML 5. Este fantástico método se llama, como era de esperar, <a href="http://api.jquery.com/data">data</a> y su uso es de lo más sencillo:</p>
<pre name="code" class="javascript">$('table#tabla').data({
  campoOrden: 'id',
  orden: 'asc'
});

$('table#tabla').data('campoOrden');</pre>
<h2>Agrupa las operaciones</h2>
<p>¿Necesitas aplicar un mismo método a varios elementos? No es necesario que los selecciones uno por uno. Si los agrupas utilizando un único selector, irás más rápido y el código será más corto.</p>
<pre name="code" class="javascript">// Tedioso
$('#formularioCrear').show();
$('#tablaItems').show();
$('#mensajeAlerta').show();

// Mucho mejor
$('#formularioCrear, #tablaItems, #mensajeAlerta').show();</pre>
<h2>Evita conflictos en tus plugins</h2>
<p>Crear plugins para jQuery es tan sencillo que muchos desarrolladores se encuentran escribiendo sus propios plugins a los pocos días de empezar a utilizar la librería. Si quieres distribuir tus extensiones, es una buena idea utilizar una sintaxis como la siguiente, para evitar conflictos con otras librerías que puedan utilizar <code>$</code> para otros fines:</p>
<pre name="code" class="javascript">(function($) {
  $.alertar = function(mensaje) {
    alert(mensaje);
  }
})(jQuery);</pre>
<p>Aunque el código puede parecer un poco confuso a simple vista, si lo analizamos detenidamente, veremos que no tiene mayor misterio. No hacemos más que crear una función anónima a la que pasamos como parámetro el objeto <code>jQuery</code>, dando a este parámetro el nombre <code>$</code>, para poder utilizar este símbolo indistintamente dentro de la función.</p>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushXml.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushJScript.js"></script><br />
<script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/08/16/buenas-practicas-con-jquery/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Doom en tu navegador</title>
		<link>http://mundogeek.net/archivos/2011/06/02/doom-en-tu-navegador/</link>
		<comments>http://mundogeek.net/archivos/2011/06/02/doom-en-tu-navegador/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 15:27:32 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[doom]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Juegos]]></category>
		<category><![CDATA[navegadores]]></category>
		<category><![CDATA[quake]]></category>
		<category><![CDATA[red]]></category>
		<category><![CDATA[videojuegos]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=6859</guid>
		<description><![CDATA[Atrás quedaron los tiempos en los que JavaScript se consideraba un lenguaje de programación de juguete y lo más excitante que podía ofrecernos HTML era la perversa etiqueta blink. Lo demostró Google el año pasado con su implementación de Quake II usando WebGL, por ejemplo, y lo vuelve a hacer hoy Mozilla compilando el código [...]]]></description>
			<content:encoded><![CDATA[<p>Atrás quedaron los tiempos en los que <a href="http://mundogeek.net/tutorial_de_javascript/" title="Tutorial de JavaScript">JavaScript</a> se consideraba un lenguaje de programación de juguete y lo más excitante que podía ofrecernos <a href="http://mundogeek.net/archivos/2010/02/26/tutorial-rapido-de-html-xhtml/" title="Tutorial de HTML">HTML</a> era la perversa etiqueta <code>blink</code>.</p>
<p>Lo demostró Google el año pasado con su implementación de <a href="http://code.google.com/p/quake2-gwt-port/" title="Quake II para navegadores">Quake II usando WebGL</a>, por ejemplo, y lo vuelve a hacer hoy Mozilla compilando el código original de Doom a JavaScript para que podamos <a href="https://developer.mozilla.org/es/demos/detail/doom-on-the-web/launch" title="Doom en el navegador">jugar en nuestro navegador</a>. <span id="more-6859"></span></p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/doom-navegador.jpg" alt="Doom corriendo en Firefox"/></div>
<p>Merece la pena echar una partida y rememorar viejos tiempos mientras sopesamos qué sorpresas nos deparará el futuro de la web.</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/06/02/doom-en-tu-navegador/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>jQuery 1.5</title>
		<link>http://mundogeek.net/archivos/2011/02/01/jquery-1-5/</link>
		<comments>http://mundogeek.net/archivos/2011/02/01/jquery-1-5/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 17:21:51 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[Linklog]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=6349</guid>
		<description><![CDATA[jQuery 1.5 ya está disponible. ¿Necesitas ayuda para empezar con esta fantástica librería? Echa un vistazo a mi tutorial rápido de jQuery.]]></description>
			<content:encoded><![CDATA[<p>jQuery 1.5 <a href="http://blog.jquery.com/2011/01/31/jquery-15-released/">ya está disponible</a>. ¿Necesitas ayuda para empezar con esta fantástica librería? Echa un vistazo a mi <a href="http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/" title="Tutorial de jQuery">tutorial rápido de jQuery</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/02/01/jquery-1-5/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Grafikart: un tema oscuro para NetBeans</title>
		<link>http://mundogeek.net/archivos/2010/12/11/grafikart-un-tema-oscuro-para-netbeans/</link>
		<comments>http://mundogeek.net/archivos/2010/12/11/grafikart-un-tema-oscuro-para-netbeans/#comments</comments>
		<pubDate>Sat, 11 Dec 2010 11:40:10 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[colores]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[resaltado]]></category>
		<category><![CDATA[sintaxis]]></category>
		<category><![CDATA[tema]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=6209</guid>
		<description><![CDATA[Contestando a algunos lectores que me preguntaron por el tema utilizado en Code folding personalizado en NetBeans os dejo el enlace desde donde podréis descargar Grafikart, un tema oscuro para NetBeans especialmente pensado para PHP, XHTML, JavaScript, CSS y SQL (requiere registro, y está en francés): Ressource Netbeans, Thème Grafikart]]></description>
			<content:encoded><![CDATA[<p>Contestando a algunos lectores que me preguntaron por el tema utilizado en <a href="http://mundogeek.net/archivos/2010/12/02/code-folding-personalizado-en-netbeans/">Code folding personalizado en NetBeans</a> os dejo el enlace desde donde podréis descargar Grafikart, un tema oscuro para NetBeans especialmente pensado para PHP, XHTML, JavaScript, CSS y SQL (requiere registro, y está en francés): <a href="http://www.grafikart.fr/ressources/theme-netbeans-10">Ressource Netbeans, Thème Grafikart</a></p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/tema-netbeans-grafikart.png" alt="Tema para NetBeans Grafikart"/></div>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2010/12/11/grafikart-un-tema-oscuro-para-netbeans/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>10 plugins para jQuery que no puedes perderte</title>
		<link>http://mundogeek.net/archivos/2010/04/27/10-plugins-para-jquery-que-no-puedes-perderte/</link>
		<comments>http://mundogeek.net/archivos/2010/04/27/10-plugins-para-jquery-que-no-puedes-perderte/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 09:14:55 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[programacion]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=5424</guid>
		<description><![CDATA[Qué mejor forma de animarte a leer el pequeño tutorial de jQuery de Mundo geek que enseñarte algunas de las cosas que podemos lograr con unas pocas líneas de código gracias a sus plugins. Esta lista con 10 plugins para jQuery que no debes perderte es sólo una pequeña muestra. Y tú, ¿qué plugins para [...]]]></description>
			<content:encoded><![CDATA[<p>Qué mejor forma de animarte a leer el pequeño <a href="http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/" title="Tutorial de jQuery">tutorial de jQuery</a> de Mundo geek que enseñarte algunas de las cosas que podemos lograr con unas pocas líneas de código gracias a sus plugins. Esta lista con 10 <strong>plugins para jQuery</strong> que no debes perderte es sólo una pequeña muestra.</p>
<p>Y tú, ¿qué plugins para jQuery recomendarías?<span id="more-5424"></span></p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/galleria.jpg" alt="Plugin para jQuery Galleria"/></div>
<p><a href="http://devkick.com/lab/galleria/">Galleria</a>: Como es de esperar por su nombre, se trata de un plugin para la creación de una galería de imágenes.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/jgrowl.png" alt="Plugin para jQuery"/></div>
<p><a href="http://www.stanlemon.net/projects/jgrowl.html">jGrowl</a>: Para crear notificaciones al estilo de Growl de Mac OS X.</p>
<p><a href="http://www.appelsiini.net/projects/lazyload">Lazy loader</a>: Retrasa la carga de las imágenes hasta que el usuario haga scroll y vaya a necesitarlas, o hasta que se haya terminado de cargar toda la página.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/datatables.png" alt="Plugin para jQuery"/></div>
<p><a href="http://www.datatables.net/index">DataTables</a>: Añade distintas funcionalidades interesantes a las tablas HTML, como paginación, ordenación por columnas o filtrado.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/qtip.jpg" alt="Plugin para jQuery"/></div>
<p><a href="http://craigsworks.com/projects/qtip/">qTip</a>: Un completo plugin para la creación de tooltips.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/jqtransform.png" alt="Plugin para jQuery"/></div>
<p><a href="http://www.dfc-e.com/metiers/multimedia/opensource/jqtransform/">jqTransform</a>: Transforma el aspecto de tus widgets en alternativas, en teoría, mucho más elegantes y vistosas.</p>
<p><a href="http://razorjack.net/quicksand/">Quicksand</a>: Filtra y reordena distintos elementos utilizando una animación de lo más vistosa, a lo Mac OS.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/colorbox.jpg" alt="Plugin para jQuery"/></div>
<p><a href="http://colorpowered.com/colorbox/">ColorBox</a>: Ventanas modales superpuestas, al estilo lightbox, con distintos efectos de transición.</p>
<p><a href="http://webdev.stephband.info/parallax.html">jParallax</a>: Permite implementar al técnica de animación 2D &#8220;parallax scrolling&#8221; (desplazamiento con paralaje), que permite dar sensación de profundidad moviendo distintas capas distinta distancia en función de la supuesta lejanía al observador.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/masonry.png" alt="Plugin para jQuery"/></div>
<p><a href="http://desandro.com/resources/jquery-masonry/">Masonry</a>: Encaja los elementos flotantes de forma que no quede espacio en blanco entre ellos.</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2010/04/27/10-plugins-para-jquery-que-no-puedes-perderte/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Tutorial rápido de jQuery</title>
		<link>http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/</link>
		<comments>http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 15:26:36 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=5390</guid>
		<description><![CDATA[El mejor resumen de lo que es jQuery lo podemos encontrar en el lema de su propia página web: &#8220;La librería JavaScript para escribir menos y hacer más&#8221;. Ampliando algo más esta definición, dejémoslo en que es una forma de convertir el desarrollo de la parte de cliente de una aplicación web en algo mucho [...]]]></description>
			<content:encoded><![CDATA[<p>El mejor resumen de lo que es <a href="http://jquery.com/" title="jQuery">jQuery</a> lo podemos encontrar en el lema de su propia página web: &#8220;La librería JavaScript para escribir menos y hacer más&#8221;. Ampliando algo más esta definición, dejémoslo en que es una forma de convertir el desarrollo de la parte de cliente de una aplicación web en algo mucho más divertido, rápido y sencillo, facilitando la interacción con los elementos del árbol de documento, el manejo de eventos, el uso de animaciones, etc.</p>
<p>Con algo más de 4 años de vida, jQuery se ha convertido en la librería JavaScript más utilizada actualmente, y es que, además, es gratuita, de código abierto (bajo licencia MIT y GPL v2) e increíblemente ligera. Entre sus usuarios podemos encontrar a Google, Microsoft, IBM, Amazon, Twitter, WordPress, Mozilla o Drupal.<span id="more-5390"></span></p>
<p>Para poder utilizar esta librería lo primero que tendremos que hacer será incluir su código en nuestro proyecto. Podemos descargar el script desde su página web, subirlo a nuestro servidor, y ejecutarlo con la etiqueta script:</p>
<pre name="code" class="html">&lt;script type="text/javascript" src="jquery.js"&gt;&lt;/script&gt;</pre>
<p>También podemos cargarla directamente desde el CDN que mantiene Google:</p>
<pre name="code" class="html">&lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;</pre>
<p>el de Microsoft:</p>
<pre name="code" class="html">&lt;script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js"&gt;&lt;/script&gt;</pre>
<p>o el del propio jQuery</p>
<pre name="code" class="html">&lt;script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"&gt;&lt;/script&gt;</pre>
<p>Independientemente de la opción elegida, ya estaremos listos para comenzar a trabajar con la librería. Sin embargo, y aunque no es estrictamente necesario, os aconsejaría tener unos conocimientos básicos de JavaScript primero, conocimientos que podéis obtener con nuestro <a href="http://mundogeek.net/tutorial_de_javascript/" title="Tutorial de JavaScript">tutorial de JavaScript</a>. Y ahora, manos a la obra.</p>
<p>El corazón de jQuery es la función sobrecargada del mismo nombre, <code>jQuery</code>, que ofrece distinta funcionalidad dependiendo de los parámetros utilizados. Además, como JavaScript también toma conceptos del paradigma funcional, y las funciones no son más que otro tipo de objeto, la función <code>jQuery</code> cuenta a su vez con distintas propiedades y métodos. La intención de esta decisión de diseño es la de evitar llenar el espacio de nombres global con montones de nombres inútiles esperando a colisionar.</p>
<p>Si queremos escribir menos y que nuestros archivos sean más pequeños, y si no utilizamos ninguna otra librería que pueda causar algún conflicto con este símbolo, también podemos utilizar el alias <code>$</code> en sustitución de <code>jQuery</code>.</p>
<h2>Selectores jQuery</h2>
<p>El primer paso a la hora de trabajar con jQuery es seleccionar los elementos del árbol de documento sobre los que queremos trabajar. Para ello se utiliza la función <code>jQuery</code>, pasando como argumento a la función una cadena con un selector, la mayoría de los cuales utilizan una sintaxis similar a la de CSS 3 (ver <a href="http://mundogeek.net/archivos/2010/03/02/tutorial-rapido-de-css/" title="Tutorial rápido de CSS">Tutorial rápido de CSS</a>). El engine que utiliza jQuery para seleccionar elementos se llama <a href="http://sizzlejs.com/" title="Una librería de selección de elementos HTML en JavaScript">Sizzle</a>, y puede descargarse y utilizarse de forma aislada.</p>
<p>Los distintos selectores que podemos utilizar son los siguientes:</p>
<h3>Selectores básicos</h3>
<p>Selector universal: selecciona todos los elementos de la página (CSS 2)</p>
<pre name="code" class="javascript">jquery("*")</pre>
<p>Selector de tipo o etiqueta: selecciona todos los elementos con el tipo de etiqueta indicado (CSS 1)</p>
<pre name="code" class="javascript">jQuery("div")</pre>
<p>Selector de clase: selecciona todos los elementos con la clase indicada (atributo class) (CSS 1)</p>
<pre name="code" class="javascript">jQuery("div.entrada")</pre>
<p>Selector de identificador: selecciona el elemento con el identificador (atributo id) indicado (CSS 1)</p>
<pre name="code" class="javascript">jQuery("div#cabecera")</pre>
<p>Grupos de selectores: se puede combinar el resultado de varios selectores distintos separándolos con comas (CSS 1)</p>
<pre name="code" class="javascript">jquery("p,div,a")</pre>
<h3>Selectores de atributos</h3>
<p>Selector de atributo: selecciona elementos que tengan un cierto atributo (CSS 2)</p>
<pre name="code" class="javascript">jquery("a[rel]")</pre>
<p>También se puede seleccionar aquellos que tengan un cierto valor para un atributo (CSS 2)</p>
<pre name="code" class="javascript">jquery("a[rel='nofollow']")</pre>
<p>O que tengan un valor distinto del indicado (jQuery)</p>
<pre name="code" class="javascript">jQuery("a[rel!='nofollow']")</pre>
<p>Aquellos cuyo valor empieza por una cierta cadena (CSS 3)</p>
<pre name="code" class="javascript">jquery("a[href^='http://mundogeek.net/']")</pre>
<p>Los que terminan con una cierta cadena (CSS 3)</p>
<pre name="code" class="javascript">jquery("a[href$='.com']")</pre>
<p>Y los que contienen una cierta cadena (CSS 3)</p>
<pre name="code" class="javascript">jquery("a[href*='geek']")</pre>
<p>Por último, podemos hacer combinaciones de todo lo anterior (CSS 2)</p>
<pre name="code" class="javascript">jquery("a[rel='nofollow'][href]")</pre>
<h3>Selectores de widgets</h3>
<p>Pseudo clase botón: selecciona todos los botones (jQuery)</p>
<pre name="code" class="javascript">jquery(":button")</pre>
<p>Pseudo clase checkbox: selecciona todos los checkboxes (jQuery)</p>
<pre name="code" class="javascript">jquery(":checkbox")</pre>
<p>Pseudo clase archivo: selecciona todos los widgets de tipo archivo (jQuery)</p>
<pre name="code" class="javascript">jquery(":file")</pre>
<p>Pseudo clase cabeceras: selecciona todas las cabeceras (jQuery)</p>
<pre name="code" class="javascript">jquery(":header")</pre>
<p>Pseudo clase imagen: selecciona todas las imágenes (jQuery)</p>
<pre name="code" class="javascript">jquery(":image")</pre>
<p>Pseudo clase input: selecciona todos los widgets de tipo input (jQuery)</p>
<pre name="code" class="javascript">jquery(":input")</pre>
<p>Pseudo clase contraseña: selecciona todos los elementos password (jQuery)</p>
<pre name="code" class="javascript">jquery(":password")</pre>
<p>Pseudo clase radiobutton: selecciona todos los elementos radiobutton (jQuery)</p>
<pre name="code" class="javascript">jquery(":radio")</pre>
<p>Pseudo clase reset: selecciona todos los elementos reset (jQuery)</p>
<pre name="code" class="javascript">jquery(":reset")</pre>
<p>Pseudo clase seleccionado: selecciona las opciones seleccionadas en un select (jQuery)</p>
<pre name="code" class="javascript">jquery(":select")</pre>
<p>Pseudo clase submit: selecciona todos los elementos submit (jQuery)</p>
<pre name="code" class="javascript">jquery(":submit")</pre>
<p>Pseudo clase texto: selecciona todos las cajas de texto (jQuery)</p>
<pre name="code" class="javascript">jquery(":text")</pre>
<p>Pseudo clase marcado: selecciona todos los radiobuttons y checkboxes marcados (CSS 3)</p>
<pre name="code" class="javascript">jquery(":checked")</pre>
<p>Pseudo clase activo: selecciona todos los elementos que estén activos (CSS 3)</p>
<pre name="code" class="javascript">jquery("input:enabled")</pre>
<p>Pseudo clase inactivo: selecciona todos los elementos que no estén activos (CSS 3)</p>
<pre name="code" class="javascript">jquery("input:disabled")</pre>
<p>Pseudo clase ocultos: selecciona todos los elementos ocultos (jQuery)</p>
<pre name="code" class="javascript">jquery(":hidden")</pre>
<p>Pseudo clase visible: selecciona todos los elementos visibles (jQuery)</p>
<pre name="code" class="javascript">jquery(":visible")</pre>
<h3>Selectores de jerarquía</h3>
<p>Selector de descendientes: selecciona elementos que desciendan de otro elemento (CSS 1)</p>
<pre name="code" class="javascript">jquery("div.entrada h2")</pre>
<p>Selector de hijos: selecciona elementos que sean hijos directos de otro elemento (CSS 2)</p>
<pre name="code" class="javascript">jquery("div.entrada &gt; h2")</pre>
<p>Pseudo clase hijo: selecciona el enésimo hijo de un elemento (CSS 3)</p>
<pre name="code" class="javascript">jquery("tr:nth-child(1)")</pre>
<p>Pseudo clase primer hijo: selecciona el primero hijo de un elemento (CSS 2)</p>
<pre name="code" class="javascript">jquery("tr:first-child")</pre>
<p>Pseudo clase último hijo: selecciona el último hijo de un elemento (CSS 3)</p>
<pre name="code" class="javascript">jquery("tr:last-child")</pre>
<p>Pseudo clase hijo único: selecciona los elementos que sean hijos únicos de otros elementos (CSS 3)</p>
<pre name="code" class="javascript">jquery("div:only-child")</pre>
<p>Pseudo clase índice: selecciona el elemento con el índice indicado de un grupo de elementos (jQuery)</p>
<pre name="code" class="javascript">jquery("td:eq(0)")</pre>
<p>Pseudo clase primero: selecciona el primer elemento de un grupo de elementos. Equivale a <code>eq(0)</code> (jQuery)</p>
<pre name="code" class="javascript">jquery("td:first)")</pre>
<p>Pseudo clase último: selecciona el último elemento de un grupo de elementos (jQuery)</p>
<pre name="code" class="javascript">jquery("td:last)")</pre>
<p>Pseudo clase mayor que: selecciona todos los elementos con un índice mayor que el indicado en un grupo de elementos (jQuery)</p>
<pre name="code" class="javascript">jquery("td:gt(0)")</pre>
<p>Pseudo clase menor que: selecciona todos los elementos con un índice menor que el indicado en un grupo de elementos (jQuery)</p>
<pre name="code" class="javascript">jquery("td:lt(3)")</pre>
<p>Pseudo clase par: selecciona los elementos pares de un grupo de elementos (jQuery)</p>
<pre name="code" class="javascript">jquery("td:even")</pre>
<p>Pseudo clase impar: selecciona los elementos impares de un grupo de elementos (jQuery)</p>
<pre name="code" class="javascript">jquery("td:odd")</pre>
<p>Selector de hermanos: selecciona todos los hermanos que se encuentren precedidos de otro elemento (CSS 3)</p>
<pre name="code" class="javascript">jquery("div.entrada ~ p")</pre>
<p>Selector de próximo adyacente: similar al anterior, pero sólo selecciona el adyacente directo (CSS 2)</p>
<pre name="code" class="javascript">jquery("div.entrada + p")</pre>
<p>Pseudo clase padre: selecciona los padres de otros elementos (jQuery)</p>
<pre name="code" class="javascript">jquery("h2:parent")</pre>
<p>Pseudo clase vacío: selecciona los elementos que no tengan ningún hijo, incluyendo texto plano (CSS 3)</p>
<pre name="code" class="javascript">jquery(":empty")</pre>
<h3>Otros selectores</h3>
<p>Pseudo clase animado: selecciona todos los elementos que están en proceso de animación en este momento (jQuery)</p>
<pre name="code" class="javascript">jquery(":animated")</pre>
<p>Pseudo clase contiene: selecciona todos los elementos que contengan el texto indicado, directamente o en uno de los hijos (jQuery)</p>
<pre name="code" class="javascript">jquery("div:contains('Mundo geek')")</pre>
<p>Pseudo clase tiene: selecciona todos los elementos que contengan al menos un elemento que responda al selector indicado (jQuery)</p>
<pre name="code" class="javascript">jquery("div:has(h2)")</pre>
<p>Pseudo clase negación: selecciona todos los elementos que no cumplan con el selector dado (CSS 3)</p>
<pre name="code" class="javascript">jquery("div:not(.entrada)")</pre>
<h2>Gestionando una colección jQuery</h2>
<p>Al llamar a la función <code>jQuery</code> con un selector como argumento, el valor devuelto será otro objeto <code>jQuery</code> representando la colección de elementos DOM seleccionados. Tanto es así, que podremos obtener uno de los elementos utilizando el operador <code>[]</code>, como si de un array normal se tratara</p>
<pre name="code" class="javascript">jQuery("div.entrada")[0]</pre>
<p>y también tenemos acceso a una propiedad <code>length</code> con el número de elementos que contiene la colección</p>
<pre name="code" class="javascript">jQuery("div.entrada").length</pre>
<p>Otras cosas que podemos hacer con este objeto son añadir elementos a la colección</p>
<pre name="code" class="javascript">jQuery("div.entrada").add("div.comentario")</pre>
<p>eliminar elementos</p>
<pre name="code" class="javascript">jQuery("div.entrada").not("div.destacada")</pre>
<p>filtrar elementos con un selector o basándonos en el valor devuelto por una función</p>
<pre name="code" class="javascript">jQuery("div.entrada").filter(":has(h2)")</pre>
<p>quedarnos con los elementos que contengan otro cierto elemento</p>
<pre name="code" class="javascript">jQuery("div.entrada").has("h2")</pre>
<p>obtener un sólo elemento, por su índice</p>
<pre name="code" class="javascript">jQuery("div.entrada").eq(3)</pre>
<p>obtener el primer elemento de la colección</p>
<pre name="code" class="javascript">jQuery("div.entrada").first()</pre>
<p>obtener el último elemento de la colección</p>
<pre name="code" class="javascript">jQuery("div.entrada").last()</pre>
<p>crear una sub colección a partir de la original</p>
<pre name="code" class="javascript">jQuery("div.entrada").slice(0,5);
jQuery("div.entrada").slice(3);</pre>
<p>obtener los descendientes directos</p>
<pre name="code" class="javascript">jQuery("div.entrada").children()
jQuery("div.entrada").children("p")</pre>
<p>obtener los descendientes directos, incluyendo el texto plano</p>
<pre name="code" class="javascript">jQuery("div.entrada").contents()</pre>
<p>obtener los hijos que cumplan con un determinado selector</p>
<pre name="code" class="javascript">jQuery("div.entrada").find("p")</pre>
<p>obtener el hermano siguiente</p>
<pre name="code" class="javascript">jQuery("div.entrada").next()</pre>
<p>obtener los hermanos siguientes</p>
<pre name="code" class="javascript">jQuery("div.entrada").nextAll()</pre>
<p>obtener el hermano anterior</p>
<pre name="code" class="javascript">jQuery("div.entrada").prev()</pre>
<p>obtener los hermanos anteriores</p>
<pre name="code" class="javascript">jQuery("div.entrada").prevAll()</pre>
<p>obtener todos los hermanos</p>
<pre name="code" class="javascript">jQuery("div.entrada").siblings()</pre>
<p>obtener el padre de cada elemento</p>
<pre name="code" class="javascript">jQuery("div.entrada").parent()</pre>
<p>obtener todos los ancestros de cada elemento</p>
<pre name="code" class="javascript">jQuery("div.entrada").parents()</pre>
<p>crear una copia de la colección</p>
<pre name="code" class="javascript">jQuery("div.entrada").clone()</pre>
<p>o buscar la posición que ocupa un elemento en la colección (si existe)</p>
<pre name="code" class="javascript">jQuery("*").index("div.entrada")</pre>
<h2>Modificar la página con jQuery</h2>
<p>Veamos ahora cómo utilizar jQuery para modificar nuestra página web. Podemos, por ejemplo, modificar el valor de un atributo</p>
<pre name="code" class="javascript">jQuery("a#principal").attr("href", "http://mundogeek.net/")</pre>
<p>añadir una nueva clase a uno o varios elementos</p>
<pre name="code" class="javascript">jQuery("div.entrada:first").addClass("primera")</pre>
<p>añadir una propiedad CSS a uno o varios elementos</p>
<pre name="code" class="javascript">jQuery("div.entrada").css("border", "1px solid red")</pre>
<p>añadir contenido a un elemento</p>
<pre name="code" class="javascript">jQuery("div.entrada:first").before("&lt;strong&gt;Destacada&lt;/strong&gt;")
jQuery("div.entrada:first").prepend("&lt;strong&gt;Destacada&lt;/strong&gt;")
jQuery("div.entrada:first").after("&lt;strong&gt;Destacada&lt;/strong&gt;")
jQuery("div.entrada:first").append("&lt;strong&gt;Destacada&lt;/strong&gt;")</pre>
<p>modificar el contenido de un elemento</p>
<pre name="code" class="javascript">jQuery("p").html("&lt;strong&gt;Sustituido&lt;/strong&gt;")</pre>
<p>eliminar un elemento de la página</p>
<pre name="code" class="javascript">jQuery("div.entrada:first").remove()</pre>
<p>ocultar un elemento</p>
<pre name="code" class="javascript">jQuery("p").hide()</pre>
<p>o volver a mostrar un elemento</p>
<pre name="code" class="javascript">jQuery("p").show()</pre>
<h2>Eventos en jQuery</h2>
<p>Existen distintas funciones para asignar una función que maneje un evento lanzado por un widget. Para el evento click, al hacer clic sobre un elemento:</p>
<pre name="code" class="javascript">jQuery(":button#pulsame").click(function () {
  alert("Has hecho clic");
});</pre>
<p>evento submit, cuando se pulsa sobre el botón de enviar de un formulario:</p>
<pre name="code" class="javascript">jQuery("#formulario").submit(function() {
  alert("Enviando");
});</pre>
<p>evento dblclick, al hacer doble clic sobre un elemento:</p>
<pre name="code" class="javascript">jQuery("p:first").dblclick(function () {
  alert("Has hecho doble clic");
});</pre>
<p>evento hover, cuando al pasar el ratón por encima de un elemento. Podemos utilizar <code>jQuery(this)</code> para referirnos a este elemento:</p>
<pre name="code" class="javascript">jQuery("p:first").hover(function () {
  jQuery(this).css("border", "1px solid red");
});</pre>
<p>evento mouseenter, cuando el cursor entra en un elemento</p>
<pre name="code" class="javascript">jQuery("p:first").mouseenter(function () {
  jQuery(this).css("border", "1px solid red");
});</pre>
<p>evento mouseout, cuando el cursor sale de un elemento</p>
<pre name="code" class="javascript">jQuery("p:first").mouseenter(function () {
  jQuery(this).css("border", "1px solid red");
});

jQuery("p:first").mouseout(function () {
  jQuery(this).css("border", "0");
});</pre>
<p>evento change, cuando se modifica un elemento:</p>
<pre name="code" class="javascript">jQuery(":text#nombre").change(function () {
  alert("Cambiado");
});</pre>
<p>evento load, cuando se termina de cargar el elemento:</p>
<pre name="code" class="javascript">jQuery(window).load(function () {
  alert("Página cargada");
});</pre>
<p>evento ready, cuando se termina de cargar el DOM, para no tener que esperar a cargar las imágenes, por ejemplo, de forma que el usuario pueda utilizar nuestra funcionalidad JavaScript cuanto antes:</p>
<pre name="code" class="javascript">jQuery(document).ready(function () {
  alert("DOM cargado");
});</pre>
<p>esto último, al ser esto algo muy común, se puede resumir pasando una función a la función <code>jQuery</code>, directamente:</p>
<pre name="code" class="javascript">jQuery(function () {
  alert("DOM cargado");
});</pre>
<h2>Animaciones con jQuery</h2>
<p>jQuery viene con unas pocas animaciones útiles y vistosas por defecto, aunque para sacarle todo el partido probablemente tendremos que recurrir a plugins.</p>
<p>Para hacer un fundido a opaco:</p>
<pre name="code" class="javascript">jQuery(function () {
  jQuery("p").hide();
  jQuery("p").delay(200).fadeIn();
});</pre>
<p>En el ejemplo anterior se utiliza <code>delay</code> para hacer pasar un par de segundos y que se vea más claramente el efecto. A esta función se le puede pasar un valor numérico con el número de milisegundos a esperar, o una cadena, como <code>"slow"</code> (lento) o <code>"fast"</code> (rápido).</p>
<p>para hacer un fundido a transparente:</p>
<pre name="code" class="javascript">jQuery(":button").click(function () {
  jQuery("p").fadeOut();
});</pre>
<p>También podemos cambiar la opacidad de un elemento a cualquier valor intermedio</p>
<pre name="code" class="javascript">jQuery(":button").click(function () {
  jQuery("p").fadeTo("slow", 0.5);
});</pre>
<p>mostrar los elementos con una animación de deslizamiento de arriba a abajo:</p>
<pre name="code" class="javascript">jQuery(function () {
  jQuery("p").hide().delay(200).slideDown();
});</pre>
<p>ocultarlos deslizándolos hacia arriba:</p>
<pre name="code" class="javascript">jQuery(function () {
  jQuery("p").delay(200).slideUp();
});</pre>
<p>mostrarlos u ocultarlos, dependiendo de si se estaban mostrando o no:</p>
<pre name="code" class="javascript">jQuery(":button").click(function () {
  jQuery("p").delay(200).slideToggle();
});</pre>
<p>Por último, para cualquier otro tipo de animación con propiedades CSS cuyos valores sean numéricos, utilizaríamos:</p>
<pre name="code" class="javascript">jQuery(":button").click(function () {
  jQuery("p").animate({opacity:0.50,width:100}, 'slow');
});</pre>
<h2>jQuery y AJAX</h2>
<p>La forma más sencilla de enviar una petición HTTP de forma asíncrona y mostrar el resultado en la página actual es utilizar la función <code>load</code>. Esta se ejecuta sobre el elemento al que se va a añadir la respuesta, y se le pasa como argumento una cadena con el archivo a cargar. Esta cadena puede contener también un selector con el que seleccionar qué elementos queremos mostrar de la respuesta.</p>
<pre name="code" class="javascript">jQuery(":button").click(function () {
  $("#citas").load("citas.html li");
});</pre>
<p>también se pueden enviar parámetros al documento (se utiliza GET a menos que los datos se manden en forma de objeto):</p>
<pre name="code" class="javascript">jQuery(":button#login").click(function () {
  $("#mensaje").load("login.php", {nombre: "zootropo", pass: "contraseña"});
});</pre>
<p>e indicar una función a ejecutar cuando se termine de llevar a cabo la petición</p>
<pre name="code" class="javascript">jQuery(":button#login").click(function () {
  jQuery("#mensaje").load("login.php", {nombre: "zootropo", pass: "contraseña"}, function(responseText, textStatus, XMLHttpRequest) {
    alert("cargado");
    });
});</pre>
<p>También se pueden utilizar los métodos <code>get</code> y <code>post</code> del objeto <code>jQuery</code>, en cuyo caso se nos devolverá unos ciertos datos con los que nosotros mismos tendremos que trabajar para generar la respuesta y mostrarla en nuestro documento actual:</p>
<pre name="code" class="javascript">jQuery.get("login.php", {nombre: "zootropo", pass:"contraseña"},
  function(data, textStatus, XMLHttpRequest){
    jQuery("#mensaje").html("Han devuelto: " + data);
  });

jQuery.post("login.php", {nombre: "zootropo", pass:"contraseña"},
  function(data, textStatus, XMLHttpRequest){
    jQuery("#mensaje").html("Han devuelto: " + data);
  });</pre>
<p>Si la respuesta del servidor va a estar en formato JSON (JavaScript Object Notation), muy utilizado actualmente, podemos utilizar el método <code>jQuery.getJSON()</code>, al que se le pasa la URL de la petición y, opcionalmente, cualquier parámetro que se necesite, además de una función de callback que ejecutar cuando se termine con la petición. Este método se encargará de parsear la estructura del objeto JSON devuelta utilizando <code>jQuery.parseJSON()</code>, objeto que estará disponible como primer parámetro de la función de callback.</p>
<pre name="code" class="javascript">$.getJSON('tareas.php', function(data, textStatus){
          $.each(data, function(i, tarea){
            $("&lt;li&gt;&lt;/li&gt;").html(tarea.nombre + " - " + tarea.hora).appendTo("ul#tareas");
          });
        });</pre>
<p>El código de este tareas.php podría tener este aspecto:</p>
<pre name="code" class="php">&lt;?php
header('Content-type: text/javascript');

$bbdd = new mysqli('servidor.com', 'usuario', 'pass', 'tareas');

$query = 'SELECT * FROM tareas';
$tareas = array();
if($resultado = $bbdd-&gt;query($query))
  while($tarea = $resultado-&gt;fetch_object())
    $tareas[] = $tarea;

$bbdd-&gt;close();

echo json_encode($tareas);
?&gt;</pre>
<p>Como veis, se utiliza la función <code>json_encode</code> para convertir el array u objeto PHP a formato JSON. Esta función, junto con su complemento, <code>json_encode</code>, se introdujo en PHP en la versión 5.2.0.</p>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushXml.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushJScript.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushPhp.js"></script><br />
<script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2010/04/21/tutorial-rapido-de-jquery/feed/</wfw:commentRss>
		<slash:comments>107</slash:comments>
		</item>
		<item>
		<title>Nuevo Firefox 3.6: ¿el mejor navegador del mercado?</title>
		<link>http://mundogeek.net/archivos/2010/01/21/nuevo-firefox-3-6-%c2%bfel-mejor-navegador-del-mercado/</link>
		<comments>http://mundogeek.net/archivos/2010/01/21/nuevo-firefox-3-6-%c2%bfel-mejor-navegador-del-mercado/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 18:42:40 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[navegadores]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=4728</guid>
		<description><![CDATA[Ayuda -> Buscar actualizaciones, señores. ¿Novedades? Unas cuantas. Y MUY interesantes: Personas: una característica de la que ya podíamos disfrutar anteriormente en forma de extensión y que permite personalizar aún más el aspecto del navegador. Herramienta para el autocompletado de formularios Mayor soporte de HTML 5 y CSS 3 lo que a efectos prácticos nos [...]]]></description>
			<content:encoded><![CDATA[<p><center><img src="http://mundogeek.net/wp-content/firefox-3.6.png" alt="Firefox 3.6" title="Firefox 3.6"/></center></p>
<p>Ayuda -> Buscar actualizaciones, señores. ¿Novedades? Unas cuantas. Y MUY interesantes:</p>
<ul>
<li><a href="http://www.getpersonas.com/en-US/gallery/All/">Personas</a>: una característica de la que ya podíamos disfrutar anteriormente en forma de extensión y que permite personalizar aún más el aspecto del navegador.</li>
<li>Herramienta para el autocompletado de formularios</li>
<li>Mayor soporte de HTML 5 y CSS 3 lo que a efectos prácticos nos trae, entre otras cosas, vídeo nativo en pantalla completa o gradientes con CSS</li>
<li>Mejoras de rendimiento. Un 20% más rápido que Firefox 3.5.</li>
<li>Herramienta de actualización de plugins</li>
<li>Mejoras en el rendimiento de JavaScript</li>
<li>Mejoras en la estabilidad</li>
<li>Mejoras en el tiempo de arranque</li>
</ul>
<p>Y tú, ¿piensas usar Firefox 3.6 como navegador principal? ¿o crees que existen alternativas mejores?</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2010/01/21/nuevo-firefox-3-6-%c2%bfel-mejor-navegador-del-mercado/feed/</wfw:commentRss>
		<slash:comments>85</slash:comments>
		</item>
		<item>
		<title>Google Closure Tools</title>
		<link>http://mundogeek.net/archivos/2009/11/06/google-closure-tools/</link>
		<comments>http://mundogeek.net/archivos/2009/11/06/google-closure-tools/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 16:18:51 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[Linklog]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=4304</guid>
		<description><![CDATA[Muy a tener en cuenta para desarrolladores JavaScript: Google Closure Tools]]></description>
			<content:encoded><![CDATA[<p>Muy a tener en cuenta para desarrolladores <a href="http://mundogeek.net/tutorial_de_javascript/" title="Tutorial de JavaScript">JavaScript</a>: <a href="http://code.google.com/closure/" title="Google Closure Tools">Google Closure Tools</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2009/11/06/google-closure-tools/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

