<?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>elBlëg - Interactividad, usabilidad y web &#187; Web Dev</title>
	<atom:link href="http://www.elbleg.com/category/web-dev/feed" rel="self" type="application/rss+xml" />
	<link>http://www.elbleg.com</link>
	<description>Interactividad, usabilidad y web</description>
	<lastBuildDate>Thu, 19 Aug 2010 16:41:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>10 buenas razones para usar Firebug</title>
		<link>http://www.elbleg.com/web-dev/10-buenas-razones-para-usar-firebug.html</link>
		<comments>http://www.elbleg.com/web-dev/10-buenas-razones-para-usar-firebug.html#comments</comments>
		<pubDate>Mon, 28 Dec 2009 06:14:11 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[consola]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[performance testing]]></category>
		<category><![CDATA[xhtml]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=271</guid>
		<description><![CDATA[
            Firebug una de las herramientas que ha revolucionado la forma en que hacemos web hoy en día, su uso nos es indispensable para muchos y en lo personal es la herramienta que más utilizo para trabajar después de Textmate. 
La idea con este [...]]]></description>
			<content:encoded><![CDATA[<p>
            Firebug una de las herramientas que ha revolucionado la forma en que hacemos web hoy en día, su uso nos es indispensable para muchos y en lo personal es la herramienta que más utilizo para trabajar después de Textmate. </p>
<p>La idea con este post, es recorrer diez de las mejores caracteristicas de Firebug. Así quienes no lo usan lo conocen y quienes lo conocen de repente puedan encontrarse con algo nuevo.
        </p>
<p><span id="more-271"></span></p>
<h2>
            1. Consola<br />
        </h2>
<p>
            La primer cosa que vas a ver cuando abrís firebug va a ser el panel de consola . Después de verlo un momento podrías darte cuenta que es una versión alternativa de la consola de errores de Firefox que básicamente nos sirve para:
        </p>
<ul>
<li>Registro de errores, advertencias y avisos
            </li>
<li>Habilidad para ejecutar código JavaScript
            </li>
</ul>
<p>
            Pero firebug lo extiende un poco más, así que en su consola podés hacer cosas mucho más complejas como:
        </p>
<ul>
<li>Registrar errores de Javascript, CSS, XML, XMLHttpRequest (AJAX) y de Chrome (no el browser&#8230; Si no de funcionalidad interna de firefox)
            </li>
<li>Ejecutar JavaScript en la página web actual
            </li>
<li>Usar el objeto console para hacer output desde tu scripts
            </li>
</ul>
<pre class="js" name="code">
    &lt;html&gt;
    &lt;head&gt;
    &lt;script type="text/javascript"&gt;
        console.time(1);
        console.log('la seccion de scripts comenzo a ejecutarse');
        console.warn('mensaje warning');
        console.error('mensaje error');
        console.info('mensaje info');
        console.log(
        'terminando la ejecucion del script\n',
        'la ejecucion tardo:'
        );
        console.timeEnd(1);
    &lt;/script&gt;
    &lt;/head&gt;
    &lt;/html&gt;
</pre>
<p>
            Fijate en el código arriba, tiene algunos ejemplos de uso del objeto console de firebug, imaginate que abrís que ejecutás ese HTML. Eso te va a mostrar algo como esto en la consola:
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/console.png" width="663" height="271" alt="Console" />
        </p>
<h2>
            2. HTML<br />
        </h2>
<p>
            El segundo panel &#8211; y en el que creo que vas a pasar mucho tiempo &#8211; se divide en varias secciónes que vamos a revisar acá.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/html.png" width="664" height="272" alt="Html" />
        </p>
<ol>
<li>Este botón es equivalente al &#8220;Inspect Element&#8221; que aparece en el menú contextual. Aparte de ser muy útil para seleccionar elementos en la página, también destaca el elemento seleccionado con un borde.
            </li>
<li>En esta sección tenemos la jerarquía del elemento que tenemos seleccionado y la habilidad de efectuar una serie de acciones en cada uno de los componentes de la jerarquía como:
<ul class="">
<li>Copiar el inner HTML
                    </li>
<li>Crear expresiones de XPath
                    </li>
<li>Adjuntarle un observador de eventos (y registrarlos en la consola)
                    </li>
<li>Borrar el elemento
                    </li>
<li>Editar el elemento y sus nodos hijos.
                    </li>
<li>Mover el elemento a la pestaña DOM para inspeccionarlo.
                    </li>
</ul>
</li>
<li>Es la ventana principal del panel; util para recorrer todo el html, hacer modificaciónes rápidas al código y encontrar errores (Como cerrar un div muy pronto). El menú contextual tiene las mismas opciones que la sección 2
            </li>
<li>En esta sección se muestran los estilos computados por el browser. La posibilidad de hacer modificaciones en tiempo real al estilo y la habilidad inspeccionar herencias me parecen que son las caracteristicas más importantes.
            </li>
<li>En esta sección podés examinar fácilmente el box model de un elemento: tamaño del contenido, padding, offsets, márgenes y bordes.
            </li>
<li style="list-style: none">
                <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/layout.png" width="655" height="245" alt="Layout" />
            </li>
<li>La sección DOM genera una lista con todos los métodos y propiedades del elemento seleccionado.
            </li>
<li style="list-style: none">
                <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/DOM.png" width="641" height="246" alt="DOM" />
            </li>
</ol>
<h2>
            3. CSS<br />
        </h2>
<p>
            La principal diferencia entre este panel y el que está como sección dentro de la pestaña HTML es que acá podés trabajar con estilos que no han sido interpretados por el browser aún, o sea que no han sido computados. De nuevo voy a destacarte y numerar las secciones (y características esta vez). </p>
<p><img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/css.png" width="700" height="273" alt="Css" />
        </p>
<ol>
<li>Si la página en la que estás trabajando contiene múltiples hojas de estilo podés seleccionar solo la que te interese ver La región principal donde se muestra el código
            </li>
<li>Modifica fácilmente las propiedades del CSS.
            </li>
<li>Podés deshabilitar el CSS desde ahí.
            </li>
</ol>
<h2>
            4. Script<br />
        </h2>
<p>
            A veces, cuando escribís JavaScript tenés que ensuciarte un poco las manos. La mayor parte del tiempo te vas a ver trabajando con la consola; Pero en condiciones extremas vas a tener que pasarte al script panel. Dadas esas condiciones extremas (que ocurren comúnmente), te presento este panel, así te empezás a familiarizar con él.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/script.png" width="699" height="272" alt="Script" />
        </p>
<ol>
<li>Un Dropdown para escoger el script que querés trabajar.
            </li>
<li>Funciones para Debugging: <em>continue, step in, step over y step out</em>. Estas se habilitan solamente cuando el código en ejecución llega a un breakpoint.
            </li>
<li>Sección principal. Acá colocás (y quitás) los breakpoints, también sirve para inspeccionar el código Javascript.
            </li>
<li>Similar al panel DOM panel, la sección Watch muestra los métodos y parametros para el código que se está debuggeando.
            </li>
<li>Muestra el stack de funciones en tiempo real.
            </li>
<li>Lista los breakpoints que se encuentran activos con un link a la línea donde se encuentra. Desde acá solo podés eliminarlos.
            </li>
</ol>
<h2>
            5. DOM<br />
        </h2>
<p>
            Es lo mismo que HTML-&gt;DOM. Dado que nada cambia de lo que te mencioné anteriormente, pasemos a la siguiente sección.
        </p>
<h2>
            6. Net<br />
        </h2>
<p>
            Curioso de cuanto tiempo tarda la página en cargar? O querés saber cual pedido tarda más tiempo en completarse? Afortunadamente, todo eso puede hacerse en el panel Net.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/net.png" width="790" height="270" alt="Net" />
        </p>
<ol>
<li>Los pedidos pueden filtrarse de acuerdo a su tipo.
            </li>
<li>Todo pedido es mostrado en esta sección. Al final de la lista vemos un sumario que contiene: Numero de pedidos, tamaño, cuanto fué guardado en caché y el tiempo total que tomó completarlos.
            </li>
<li>Revela más detalles como: HTTP headers, respuesta y cache.
            </li>
</ol>
<h3>
            Pruebas de desempeño (Performance Testing)<br />
        </h3>
<p>
            Quedés probar el desempeño de una función o un bucle específico? Podés usar el &#8220;timer&#8221; de Firebug.
        </p>
<pre class="js" name="code">
    function medirTiempo(){
        console.time("MiTimer");
        for(x=5000; x &gt; 0; x--){}
        console.timeEnd("MiTimer");
    }
</pre>
<p>
            Tres pasos. Empezá por llamar &#8220;console.time&#8221; y le pasás un único key. Luego de esto ponés el código que necesitás probar. Finalmente, llamás “console.timeEnd”, y de nuevo como único parámetro, le pasás el key que utilizaste anteriormente. Voilá.
        </p>
<h2>
            7. Reference<br />
        </h2>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/reference.png" width="676" height="270" alt="Reference" />
        </p>
<p>
            Este es un panel adicional, un add-on creado por CodeBurner. Como el nombre lo indica, con este panel tenés acceso rápido a las referencias de HTML y CSS. Me parece que el panel se explica solito.
        </p>
<h2>
            8. PixelPerfect<br />
        </h2>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/pixelperfect.png" width="672" height="269" alt="Pixelperfect" />
        </p>
<p>
            Si has hecho slicing de un PSD, ya sabés el tiempo que nos quita en cada elemento de la composición. Y es ahí donde PixelPerfect demuestra su poder. Este add-on te ayudará bastante en esa tediosa tarea mostrandote cómo deben ir colocados los elementos con la ayuda de imagenes superpuestas al html.
        </p>
<ol>
<li>Con este botón podés agregar varias imágenes superpuestas para la página actual.
            </li>
<li>Lista de superposiciones, desde acá podés agregar o quitar las imágenes.
            </li>
<li>Configuración de las superposiciones.
            </li>
</ol>
<h2>
            9. YSlow<br />
        </h2>
<p>
            Un buen add-on creado por Yahoo!. Este te sugiere mejoras basado en una serie de test de velocidad que hace. Con YSlow, podés obtener el grado de desempeño de un website. Podés identificar fácilmente los puntos que pueden ser mejorados, además de una serie de recomendaciones para hacerlo.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/yslow1.png" width="661" height="319" alt="Yslow1" />
        </p>
<p>
            Aparte de las estadisticas que te muestra YSlow, te recomiendo JSLint.com para evaluar el JavaScript y Smush.it para las imágenes.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/yslow2.png" width="659" height="453" alt="Yslow2" />
        </p>
<h2>
            10. FirePHP<br />
        </h2>
<p>
            Y por último, pero no menos importante, FirePHP. Con este add-on, podés enviar información (warnings, errors, logging, info) transparentemente a la consola desde tu código PHP. Un ejemplo sería:
        </p>
<pre class="php" name="code">

            &lt;?php
                FB::log('Log message');
                FB::info('Info message');
                FB::warn('Warn message');
                FB::error('Error message');
            ?&gt;
</pre>
<h2>
            Conclusión<br />
        </h2>
<p>
            Y dale con las conclusiones&#8230; Meh&#8230; Bueno ok&#8230; Va.
        </p>
<p>
            La idea con esta pequeña lista de paneles/add-on es que se te haga la vida como developer un poco más fácil &#8212; tal como me lo ha hecho a mi.
 </p>
<p>Al final, los bugs siempre pasan, lo realmente malo es no estar preparado para resolverlos.</p>
<p> Acá la lista de links para los add-ons:
        </p>
<p>
            <a href="https://addons.mozilla.org/ro/firefox/addon/1843" rel="external">Firebug</a>,<br />
            <a href="https://addons.mozilla.org/ro/firefox/addon/10273" rel="external">CodeBurner</a>,<br />
            <a href="https://addons.mozilla.org/ro/firefox/addon/7943" rel="external">PixelPerfect</a>,<br />
            <a href="https://addons.mozilla.org/ro/firefox/addon/5369" rel="external">YSlow</a>,<br />
            <a href="http://www.firephp.org/" rel="external">FirePHP</a>
        </p>
<p>
            Que te sirva.
        </p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/10-buenas-razones-para-usar-firebug.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Optimizando JavaScript para un rendimiento extremo y bajo consumo de memoria</title>
		<link>http://www.elbleg.com/web-dev/javascript/optimizando-javascript-para-un-rendimiento-extremo-y-bajo-consumo-de-memoria.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/optimizando-javascript-para-un-rendimiento-extremo-y-bajo-consumo-de-memoria.html#comments</comments>
		<pubDate>Sun, 15 Nov 2009 08:07:24 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web Dev]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=244</guid>
		<description><![CDATA[
			En mis muy esporádicos ratos libres estoy haciendo un pequeño juego en JavaScript y he tenido que tomar algunas medidas para agilizar el código. La idea en este post es mostrar algunos trucos que he aprendido en el proceso, algunos no los he visto mencionados en otras partes, así que no está de más compartirlos.
		

			Muchos [...]]]></description>
			<content:encoded><![CDATA[<p>
			En mis muy esporádicos ratos libres estoy haciendo un pequeño juego en JavaScript y he tenido que tomar algunas medidas para agilizar el código. La idea en este post es mostrar algunos trucos que he aprendido en el proceso, algunos no los he visto mencionados en otras partes, así que no está de más compartirlos.
		</p>
<p>
			Muchos de los tips de optimización para JavaScript involucran cosas que se ven más típicamente en otros sitios, como por ejemplo minimizar la cantidad de modificaciones al DOM. Pero en este caso es un poco diferente, ya que era el script por sí mismo era quien debía correr más rápido &#8211; No trabaja con el DOM ni nada, solo procesa muchos datos.
		</p>
<p><span id="more-244"></span></p>
<h2>
			Encontrando la raíz del problema<br />
		</h2>
<p>
			Antes de iniciar cualquier optimización, el código debe ser perfilado para saber qué parte es la que está corriendo despacio. La mejor herramienta para lograr esto, es definitivamente el Profiler de Firebug. Sin este probablemente hubiese tenido muchas más dificultades para encontrar problemas y probar cómo las cosas que cambiaba afectaban la velocidad.
		</p>
<p>
			El Profiler lo encontrás en la consola del Firebug. Solo dale clic en el botón ‘profiler’ una vez para iniciar el <em>perfilamiento (si es que existe la palabra)</em> y clicás de nuevo para detenerlo. Después de detenerlo vas a recibir una lista informativa de las funciones que han sido llamadas y cuanto tiempo tomó cada una en ejecutarse.
		</p>
<h3>
			Problema 1: Iteraciones, cantidad de datos<br />
		</h3>
<p>
			El primer problema que me abofeteó fué la enorme cantidad de datos que se debían de guardar. Un mapa de 128&#215;128 requiere 16,384 iteraciones para ser completamente procesado. A primer vista no parece tanto, pero solamente iterar la data, sin hacer nada más, causaba un golpe mucho mayor del que pasaría en muchos otros lenguajes. Por extraño que pueda parecer, podés usar un do-while invertido para acelerar las iteraciones, o sea en lugar de usar un ciclo con for y contar sumando, usás un ciclo con do-while y contás restando. </p>
<pre class="js" name="code">
			var i = data.length;
			do {
			 /* algo que hacer */
			} while(--i);
</pre>
<p>Por qué es más rápido? Aparentemente el simple hecho de remover la condicion usada para comprobar cuando el loop termine hace gran parte de la diferencia. Hacer -i en vez de i- también ayuda un poco. </p>
<p>El problema con este enfoque es que no siempre es aplicable.</p>
<h3>Problema 2: Llamar funciones</h3>
<p>Fué curioso encontrar que el simple hecho de llamar una función agrega un overhead significativo. Así que llamar una función dentro de uno de esos ciclos grandes en los for puede agregar mucho tiempo de procesamiento.</p>
<p>Como resolverlo? Colocando el código de la función dentro del loop.</p>
<p>Sí, raro. Pero si mueves el código de la función y lo colocas dentro del loop en lugar de llamar la función vas a tener una mejora significativa.  Tiene como gran desventaja que reduce la legibilidad del código, además de que le abre las puertas a la duplicación de código si la función se usa en más de un lugar.</p>
<p>Por raro que sea, esto fué uno de los propulsores más grandes de performance, que en este caso particular, era más importante que un código legible.</p>
<h3>Problema 3: Limitaciones de la memoria</h3>
<p>Dado al bajo monto de memoria disponible en el dispositivo al que va dirigido el juego. La aplicación se quedó sin memoria en varias ocasiones.</p>
<p>Primero, el tamaño del mapa era de 300&#215;300, lo que hacía que el teléfono se quedara sin memoria casi de inmediato. Para esto no hubo más remedio que reducir el tamaño a un 128&#215;128. Usar 300&#215;300 pudo también tener otras repercusiones con el performance, porque la cantidad de data hubiese sido mucho mayor para dibujarlo.</p>
<p>Segundo, cuando implementé la funcionalidad para cargar y salvar el juego, el app de nuevo se quedaba sin memoria. Esto probablemente causado porque el data del mapa era serializado a JSON.</p>
<p>La idea que resolvió esto: Cortar el data en pedazitos pequeños.</p>
<p>Entonces, en lugar de guardar todo el array del mapa de 128&#215;128 de una sola vez, el código lo hace en 8 partes. De este modo el tamaño del JSON serializado se mantiene pequeño y la aplicación no se queda sin memoria.</p>
<p>Lo mismo se hace cuando carga, Como el JSON es guardado en 8 bloques separados, al cargar se meten dentro del array uno por uno.</p>
<h3>Más optimizaciones: Dividir y Flood numbers</h3>
<p>Como parte de la lógica del juego también eran necesario dividir algunos numeros y asegurarme de que los valores eran números enteros.</p>
<p>Típicamente esto requeriría dividir primero y luego aplicar Math.floor. Como mencioné hace un rato. Llamar funciones puede salir caro.</p>
<p>Hay un truco ‘limpio’ para esto. Y limpio entre comillas porque para algunas personas puede ser confuso si no están familiarizadas con la sintáxis, y esto, pues hace el código un poco dificil de leer.</p>
<p>El truco consiste en usar un bit-shift (no conozco el término en español&#8230;):</p>
<pre class="js" name="code">
				var foo = 10;
				//la mayoría de veces, esto es lo mismo que hacer Math.floor(foo / 4)
				var result = foo >> 2;
</pre>
<p>Hacer  <code> >> 2</code> es, como menciona el comentario, practicamente lo mismo que dividir por 4 y despues llamar un <code>Math.floor</code>. Pero en lugar de dos operaciones, tenés solamente una, por lo tanto puede ser un poco más rápido.</p>
<p>Si no entendés de matemática binaria los bitshifts pueden ser un poco enredados. En palabras simples, si hacés  <code>>></code> con 1, es lo mismo que dividir por 2, 2 es dividir entre 4, 3 es dividir entre 8, y 4 es dividir entre 16 y ahí sigue la idea&#8230;</p>
<p>Como es costumbre, <a target="_blank" href="http://en.wikipedia.org/wiki/Bit_shift#Bit_shifts">hay un buen articulo en Wikipedia sobre esto</a>, el cual es un buen recurso si querés leer más información al respecto.</p>
<h3>Más?: Mete el código en funciones anónimas</h3>
<p>Esta es una sugerencia vieja vieja vieja, pero buena buena buena&#8230; Mete el código en funciones anónimas incluso si no son o usan globales.</p>
<p>Por alguna razón que no podría explicar apropiadamente, esto afecta también la velocidad de ejecución de los scripts.</p>
<p>Así que cuando sea que tengas código en JS en un archivo, recuerda envolverla en una función anónima auto ejecutable como esta:</p>
<pre class="js" name="code">
(function(window) {
  /* todo el código va acá!!*/
})(window);
			</pre>
<p>También podés hacer que la función reciba el objeto window como un argumento para una posible pequeña mejora.</p>
<h3>Por último: Reducí el scope</h3>
<p>Esta amarra con la anterior, agregá variables locales dentro de la función anónima para funciones que se usan normalmente, como Math.round or Math.random</p>
<pre class="js" name="code">
(function(window) {
  var round = Math.round;
  var random = Math.random;
  /* todo el código va acá!!*/
})(window);
</pre>
<h3>Conclusión</h3>
<p>Solo porque ya se me hizo costumbre hacer conclusión&#8230;. En fín. La idea detrás de todo esto es mostrar que hay formas de mejorar la velocidad del JavaScript, incluso cuando no tenga nada que ver con el DOM, pero si de igual modo trabajas con el, no está de más agregar unos tips a lo que ya conoces.</p>
<p>Agregando una cosa más a lo anterior. Hay una cosa más que intenté: Probar si había alguna diferencia entre llamar una función objeto vs una función instancia:</p>
<pre class="js" name="code">
				var x = new Foo();
				x.someFunc();
				//or
				bar.someFunc();
</pre>
<p>Yo no ví diferencia alguna, pero si estás usando las clasicas intancias de POO en lugar de funciones estáticas. Puede que te sirva.</p>
<p>Solo recordá que debes perfilar el código siempre antes y después de una optimización. Para ver donde están las partes que realmente necesitan optimizarse y su hubieron mejoras después de algún cambio.</p>
<p>También considerá que muchas optimizaciones pueden hacer que el código sea dificil de mantener. Así que puedes poner en una balanza que tanto necesitas mejorar el performance. Si no es tanto, a veces es mejor no hacerlo.</p>
<p>Espero que te sirva de algo.</p>
<p><a href="http://codeutopia.net/blog/2009/04/30/optimizing-javascript-for-extreme-performance-and-low-memory-consumption/">Fuente</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/optimizando-javascript-para-un-rendimiento-extremo-y-bajo-consumo-de-memoria.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Snippet: Favoritos recientes de Delicious con PHP</title>
		<link>http://www.elbleg.com/web-dev/snippet-favoritos-recientes-de-delicious-con-php.html</link>
		<comments>http://www.elbleg.com/web-dev/snippet-favoritos-recientes-de-delicious-con-php.html#comments</comments>
		<pubDate>Sat, 14 Nov 2009 07:18:26 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Php]]></category>
		<category><![CDATA[Web Dev]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=254</guid>
		<description><![CDATA[Este snippet descarga y guarda en cache los bookmarks más recientes de una cuenta en específico en RSS desde el API de Delicious, luego los muestra en un UL de HTML.



function get_delicious()
{
	$cache = dirname(__FILE__) . '/caches/delicious';
	if(filemtime($cache) < (time() - 300))
	{
		@mkdir(dirname(__FILE__) . '/caches', 0777);
		$url = 'https://api.del.icio.us/v1/posts/recent?count=10';
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
		curl_setopt($ch, [...]]]></description>
			<content:encoded><![CDATA[<p>Este snippet descarga y guarda en cache los bookmarks más recientes de una cuenta en específico en RSS desde el API de Delicious, luego los muestra en un UL de HTML.</p>
<p><span id="more-254"></span></p>
<pre class="php" name="code">

function get_delicious()
{
	$cache = dirname(__FILE__) . '/caches/delicious';
	if(filemtime($cache) < (time() - 300))
	{
		@mkdir(dirname(__FILE__) . '/caches', 0777);
		$url = 'https://api.del.icio.us/v1/posts/recent?count=10';
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
		curl_setopt($ch, CURLOPT_TIMEOUT, 5);
		curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

		// agregá delicious.com tu usuario y password en esta línea:
		curl_setopt($ch, CURLOPT_USERPWD, 'usuario:password');
		$data = curl_exec($ch);
		curl_close($ch);
		$cachefile = fopen($cache, 'wb');
		fwrite($cachefile, $data);
		fclose($cachefile);
	}
	else
	{
		$data = file_get_contents($cache);
	}
	$xml = simplexml_load_string($data);

	$html = '
<ul>';
	foreach($xml as $item)
	{
		$html .= '
<li><a href="' . $item['href'] . '">' . $item['description'] . '</a> ' . $item['extended'] . '</li>

';
	}
	$html .= '
<li><a href="http://delicious.com/yeco">Mis bookmarks recientes</a></li>

';
	$html .= '</ul>

';
	echo $html;
}

// Mostralos
get_delicious();
</pre>
<p>Este snippet usa <a target="_blank" href="http://us.php.net/manual/en/ref.simplexml.php">SimpleXML</a>, propiedad que fué incluida en PHP5 para hacer la lectura de XML mucho más sencilla.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/snippet-favoritos-recientes-de-delicious-con-php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nombres de Funciones dinámicos con JavaScript</title>
		<link>http://www.elbleg.com/web-dev/javascript/nombres-de-funciones-dinamicos-con-javascript.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/nombres-de-funciones-dinamicos-con-javascript.html#comments</comments>
		<pubDate>Tue, 27 Oct 2009 06:01:59 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web Dev]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=236</guid>
		<description><![CDATA[Si te toca hacer aplicaciones un poco avanzadas con JavaScript, vas a toparte con un problema en un punto u otro donde vas a necesitar generar dinámicamente el nombre de una función que quieras llamar. Algo como el equivalente a call_user_func() de PHP.


Algo así es como podés hacerlo:
// Definimos algunas variables
var foo = &#34;Hola&#34;;
var bar [...]]]></description>
			<content:encoded><![CDATA[<p>Si te toca hacer aplicaciones un poco avanzadas con JavaScript, vas a toparte con un problema en un punto u otro donde vas a necesitar generar dinámicamente el nombre de una función que quieras llamar. Algo como el equivalente a <code>call_user_func()</code> de PHP.
</p>
<p><span id="more-236"></span></p>
<p>Algo así es como podés hacerlo:</p>
<pre class="js" name="code">// Definimos algunas variables
var foo = &quot;Hola&quot;;
var bar = &quot;Mundo&quot;;
var nombre_funcion = &quot;decir_&quot; + foo + bar;

/*  Dado que estamos generandolo din&aacute;micamente,
* siempre hay que asegurarse de que la funci&oacute;n
* exista en realidad. */

if (typeof(window[nombre_funcion]) === &quot;function&quot;)
{
	window[nombre_funcion](&quot; Mundo!&quot;);
}
else
{
	throw(&quot;Error.  La funci&oacute;n &quot; + nombre_funcion + &quot; no existe...duh!&quot;);
}

function decir_holaMundo(la_palabra)
{
	alert(&quot;Hola &quot; + la_palabra);
}

// Browser va a alertar un trillad&iacute;simo &quot;Hola Mundo!&quot;</pre>
<p>Cuando lo pensás un rato, tiene mucho sentido considerando que todos los objetos globales en JavasScript son en realidad propiedades del objeto <code>“window”</code>. Fijate en este ejemplo de manzanas y naranjas para entender un poco mejor el concepto.</p>
<pre class="js" name="code">var foo = &quot;manzana&quot;;

function foobar()
{
	var foo = &quot;naranja&quot;;
	alert(window[&quot;foo&quot;]); // alerta &quot;manzana&quot;
	alert(foo); // alert &quot;naranja&quot;
	alert(window[&quot;foobar&quot;]); // alerta la funci&oacute;n foobar
}

foobar();
</pre>
<p>Acá hay otro ejemplo de cuando usar strings para llamar una función puede ser útil. Esta vez llamamos la propiedad de un objeto que hemos creado.</p>
<pre class="js" name="code">function Persona()
{
	this.mensaje = &quot;Hola Mundo!&quot;;
	this.decir_hola = function(a)
	{
		alert(this.mensaje);
	}
}

var Yeco = new Persona();
nombre_funcion = &quot;decir_hola&quot;;
Yeco[nombre_funcion]();</pre>
<p>Ves como es casi lo mismo que el método de arriba usando una función global?</p>
<p>Espero que te sirva en algún momento.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/nombres-de-funciones-dinamicos-con-javascript.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10 formas de escribir un mejor código en jQuery</title>
		<link>http://www.elbleg.com/web-dev/javascript/10-formas-de-escribir-un-mejor-codigo-en-jquery.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/10-formas-de-escribir-un-mejor-codigo-en-jquery.html#comments</comments>
		<pubDate>Sun, 23 Aug 2009 07:14:00 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[chaining]]></category>
		<category><![CDATA[encadenado]]></category>
		<category><![CDATA[jquery data]]></category>
		<category><![CDATA[jquery document ready]]></category>
		<category><![CDATA[optimización]]></category>
		<category><![CDATA[toggleClass]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=227</guid>
		<description><![CDATA[Sin duda alguna, jQuery se ha vuelto la biblioteca de javascript por excelencia, y no lo digo solamente porque me agrade, la gran cantidad de recursos, plugins, tutoriales y documentación, hacen que a muchos les entre la curiosidad y se inicien en javascript aún cuando nunca les atrajo el lenguaje. 
Y bien, ya que la [...]]]></description>
			<content:encoded><![CDATA[<p>Sin duda alguna, jQuery se ha vuelto la biblioteca de javascript por excelencia, y no lo digo solamente porque me agrade, la gran cantidad de recursos, plugins, tutoriales y documentación, hacen que a muchos les entre la curiosidad y se inicien en javascript aún cuando nunca les atrajo el lenguaje. </p>
<p>Y bien, ya que la usamos seguido, o pensamos aprenderla, no nos queda de más conocer unos cuantos tips que nos sirvan para que funcione de un modo más adecuado.<br />
<span id="more-227"></span><br />
Andando por ahí me encontré un post de <a rel="external" href="http://www.myinkblog.com/2009/08/04/10-tips-for-writing-better-jquery-code/">Giulio Bai</a> que aborda este tema en específico y nos dá unas buenas sugerencias al respecto:</p>
<h2>1. $(document).ready (); Siempre</h2>
<p>Todo lo que contenga será ejecutado tan pronto el DOM sea cargado y antes de que los contenidos sean llenados. Te permite agregar eventos a cualquier elemento en la página sin interferir directamente con el markup; todos esos metiches de <code>onload</code>, <code>onclick</code> y <code>onLoQueSea</code> ya no son necesarios, solo escribílos encapsulados ahí.</p>
<p>Un pequeño ejemplo podría ser:</p>
<pre name="code" class="js">$(document).ready(function()
 {
    $(&quot;.dummy&quot;).click(function()
    {
        $(this).css(&#039;color&#039;, &#039;#000000&#039;);
    });
});</pre>
<h2>2. Usá $(window).load ()</h2>
<p>Aunque la vasta mayoría de ejemplos vienen usando el método descrito anteriormente, a veces es mejor evitar poner todo ahí.</p>
<p><code>$(document).ready ()</code> es increíblemente útil, pero ocurre durante el rendering de la página, cuando los objetos aún se están descargando. Por eso las funcionalidades supérfluas como scrollings, arrastrar y soltar, podrían ponerse dentro de una función <code>$(window).load ()</code> ya que esta ejecuta después de que todos los hayan sido descargados y evita que algo se rompa mientras carga la página.</p>
<p>La sintáxis es casi la misma que la de <code>$(document).ready ()</code>:</p>
<pre name="code" class="js">$(window).load (function () {
// métodos de scrolling
});</pre>
<h2>3. Carga sólo lo que realmente necesitas</h2>
<p>Todos han sido tentados a escribir JavaScript que va a ser usado en una sola página de un sitio y luego cargarlo por todas partes, aunque no se use. jQuery se toma el tiempo de revisar todos y cada uno de los elementos que se le dan, y eso pone las cosas un poco lentas.</p>
<p>Hay dos formas que se sugieren para evitar este problema. El más sencillo sería simplemente agregar una clase en el <code>body</code> del html que sea identificador para correr ahí solamente el código necesario.</p>
<pre name="code" class="js">$(document).ready(function()
 {
    if (&#039;body&#039;).hasClass(&#039;home&#039;)
    {
        // home page code
        }
    else if (&#039;body&#039;).hasClass(&#039;blog&#039;)
    {
        // blog code
        }
    // Y as&iacute; sucesivamente
});
</pre>
<p>El otro método, un poco más enredado, sería construir una biblioteca para llamar el código que se necesite desde cada página:</p>
<pre name="code" class="js">var jslib =
{
    home:
    {
        init: function() {
            // home page code
            }
    },

    blog:
    {
        init: function() {
            // blog code
            }
    }

    // Y as&iacute; sucesivamente
}</pre>
<h2>4. Aprende qué es el método &#8216;Data&#8217; y usálo</h2>
<p>Esto es algo muy común, la gente no piensa en ello y siempre escriben cosas como:</p>
<pre name="code" class="js">$('.selector').attr ('alt', 'naranja');</pre>
<p>para guardar y asociar datos misceláneos en el DOM. Esto, es técnicamente incorrecto, además de que es fácil confundirse, sobre todo para las personas que entren al proyecto después.</p>
<p>jQuery ya tiene un método que sirve para guardar datos en el DOM llamado &#8216;data&#8217;. El ejemplo de arriba vendría siendo algo como esto:</p>
<pre name="code" class="js">$('.selector').data ('miColor', 'azul');
// que puede ser pedido con
$('.selector').data ('miColor');</pre>
<p>Este método te permite asociar y guardar datos en cualquier elemento de la página y tener un nombre de referencia.</p>
<h2>5. Usá los selectores personalizados</h2>
<p>Estar familiarizado con los selectores de CSS es util cuando se trata de jQuery. Pero conocer los selectores que trae la biblioteca es de verdad un empujón increíble. Date una vuelta por <a href="http://docs.jquery.com/Selectors">http://docs.jquery.com/Selectors</a> para conocer más de ellos.</p>
<p>Por ejemplo, podrías usar:</p>
<pre name="code" class="js">$("div:contains('hola')").css ('background-color', '#cc0000');</pre>
<p>para pintar de rojo todos los div que contengan la palabra &#8220;hola&#8221; ó</p>
<pre name="code" class="js">$('input:password')</pre>
<p> para obtener todos los campos que sean para password.</p>
<h2>6. Indicadores con clases</h2>
<p>Podés usar indicadores ó flags para monitorear lo que el usuario está haciendo o bien revisar si algo en particular se efectuó o no. El método <code>addClass</code> es bastante útil en este caso ya que provee una forma fácil de agregar una nueva clase css a un elemento. Así que podés chequear la existencia de la clase con la función <code>hasClass</code>.</p>
<p>Un uso muy común de los indicadores se da cuando a aplicación tiene uno o más modos de trabajo; al entrar en el segundo modo, el indicador se fija a un elemento predeterminado y, cuando se necesite, el método <code>hasClass</code> es usado para revisar el modo de trabajo actual. Sencillo no?</p>
<pre name="code" class="js">function editModeOn ()
{
// Inicializa el modo de edición y fija un indicador
$(&#039;#flags&#039;).addClass (&quot;editModeOn&quot;);
// hacer otras cosas
}

function saveData ()
{
// guarda los datos pero primero sale del modo de edición (si está ahí)
if ($(&#039;#flags&#039;).hasClass (&#039;editModeOn&#039;)) {
exitEditMode ();
$(&#039;#flags&#039;).removeClass (&#039;editModeOn&#039;);
}

save ();
}</pre>
<h2>7. No llamés el mismo selector cientos de veces</h2>
<p>De verdad, no lo hagas. Perfectamente en lugar de hacer algo como:</p>
<pre name="code" class="js">$(&#039;p.hola&#039;).css (&#039;color&#039;, &#039;#000000&#039;);
$(&#039;p.hola&#039;).text (&#039;hoola&#039;);
$(&#039;p.hola&#039;).addClass (&#039;parrafo&#039;);
$(&#039;p.hola&#039;).fadeTo (1000, 1);
</pre>
<p>Podés hacer algo como:</p>
<pre name="code" class="js">var $p = $(&#039;p.hola&#039;);
$p.css (&#039;color&#039;, &#039;#000000&#039;);
$p.text (&#039;hola&#039;);
$p.addClass (&#039;parrafo&#039;);
$p.fadeTo (1000, 1);
</pre>
<p>Eso va a mantener la información del selector lista para ser reutilizada.</p>
<h2>8. Encadenando (Casi) todo</h2>
<p>El encadenado, o chaining de jQuery es muy útil.<br />
El código anterior podría ser reescrito como:</p>
<pre name="code" class="js">
$(&#039;p.hola&#039;).css (&#039;color&#039;, &#039;#000000&#039;).text (&#039;hola&#039;).addClass (&#039;parrafo&#039;).fadeTo (1000, 1);</pre>
<p>Eso sí, sin exagerar, es sabido que este patrón puede ser un poco lento.</p>
<h2>9. La utilidad toggleClass</h2>
<p>Podés encender y apagar la clase de un elemento para variar su comportamiento sin mucho esfuerzo. Digamos que tenés una clase <code>.hidden</code> que esconde los elementos que la usen. Fácilmente podrías mostrar los elementos de nuevo usando:</p>
<pre name="code" class="js">
$(&#039;p.hidden&#039;).toggleClass ();
</pre>
<p>Otro punto de <code>toggleClass</code> es que, con el nuevo release de jQuery 1.3.3, el método .toggleClass() va a tener nuevas formas de operar. Va a ser capaz de cambiar multiples clases, además de que podrá quitar y poner todas las clases.</p>
<p>Estás son las formas en que vas a poder usar <code>toggleClass</code>:</p>
<pre name="code" class="js">// Con un elemento dado

	// Cambiar todas las Clases
	$(&#039;div&#039;).toggleClass(); //
	&lt;div&gt;
	$(&#039;div&#039;).toggleClass(); //
	&lt;div class=&quot;a b c&quot;&gt;
	$(&#039;div&#039;).toggleClass( false ); //
	&lt;div&gt;
	$(&#039;div&#039;).toggleClass( true ); //
	&lt;div class=&quot;a b c&quot;&gt;

	// Cambiar m&uacute;ltiples clases
	$(&#039;div&#039;).toggleClass( &quot;a b&quot; ); //
	&lt;div class=&quot;c&quot;&gt;
	$(&#039;div&#039;).toggleClass( &quot;a c&quot; ); //
	&lt;div class=&quot;a&quot;&gt;
	$(&#039;div&#039;).toggleClass( &quot;a b c&quot;, false ); //
	&lt;div&gt;
	$(&#039;div&#039;).toggleClass( &quot;a b c&quot;, true ); //&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;</pre>
<h2>10. Guardá los resultados de jQuery</h2>
<p>Cuando se trata de funciones, podrías querer tener algunos resultados disponibles en otros lugares. Acá hay dos posibilidades.</p>
<p>Una posible solución sería guardar los resultados dentro de objetos dentro de una variable global, así se pueden usar después:</p>
<pre name="code" class="js">// usamos el objeto Window
	window.$resultados = {
	uno : 0,
	dos : 0
	};

	// esta es la funci&oacute;n que podria corre m&aacute;s de una vez
	function getResults (first, second)
	{
	$resultados.uno = first;
	$resultados.dos = second;
	}

	// corre la funcion
	getResults ($(&#039;li.azul&#039;), $(&#039;a.rojo));
	$resultados.uno.hasClass (&#039;azul&#039;); // true
	$resultados.dos.hasClass (&#039;azul&#039;); // false

	// corre de nuevo
	getResults ($(&#039;li.rojo&#039;), $(&#039;a.azul));
	$resultados.uno.hasClass (&#039;azul&#039;); // false
	$resultados.dos.hasClass (&#039;azul&#039;); // true
</pre>
<p>La otra, y a mi parecer la mejor, como se recomienda en el punto 4 es usar el método Data en lugar de crear una variable global.</p>
<pre name="code" class="js">$.data(window, &quot;resultados&quot;, { uno: false, dos: true });

//Para accesar los valores:

$.data(window, &quot;resultados&quot;).uno; // false
$.data(window, &quot;resultados&quot;).dos; // true

// Y para cambiarlos:

$.data(window, &quot;resultados&quot;).uno = true;
$.data(window, &quot;resultados&quot;).dos = false;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/10-formas-de-escribir-un-mejor-codigo-en-jquery.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Singleton en JavaScript, o: Cómo convertir constructores a JSON</title>
		<link>http://www.elbleg.com/web-dev/javascript/singleton-en-javascript-o-como-convertir-constructores-a-json.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/singleton-en-javascript-o-como-convertir-constructores-a-json.html#comments</comments>
		<pubDate>Fri, 24 Jul 2009 07:54:13 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[singleton]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=219</guid>
		<description><![CDATA[Cuando necesités una sola instancia de una clase de JavaScript, no te molestés escribiendo un constructor, escribí un solo JSON.
El gran poder de los objetos es que los datos y las funciones que hacen algo pueden estar encapsuladas en un mismo objeto. Así que aprovechandonos de ello y para seguir buenas prácticas, a veces metemos [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando necesités una sola instancia de una clase de JavaScript, no te molestés escribiendo un constructor, escribí un solo JSON.</p>
<p>El gran poder de los objetos es que los datos y las funciones que hacen algo pueden estar encapsuladas en un mismo objeto. <span id="more-219"></span>Así que aprovechandonos de ello y para seguir buenas prácticas, a veces metemos todas las utilidades necesarias al &#8220;desnudo&#8221; en el namespace global. Algo así:</p>
<p><code>function getElementsByClassName(cssClassName) {...}</code></p>
<p>Aunque en esto veo dos problemas:</p>
<ul>
<li>Uno pequeño: el nombre de la función es extremadamente largo&#8230; que feo</li>
<li>y uno grande: si estás trabajando con alguna librería, es muy probable que colisione con otra función con un nombre similar y que se comporte diferente</li>
</ul>
<h3>Vamos a arreglarlos</h3>
<p>Podemos crear una clase de utilidades que nos sirva para encapsular esta función (y otras) más o menos así:</p>
<pre name="code" class="js">function DomUtilityBag() {
this.getByClass= function(cssClassName) {...}
}</pre>
<p>e instanciarla:</p>
<pre name="code" class="js">var domUtils = new DomUtilityBag();</pre>
<p>Si has usado constructores, parece obvio y familar no?. Pero los constructores fueron hechos para permitir instanciar cualquier número de objetos del mismo prototype. Por qué necesitaríamos hacer eso con un conjunto de utilidades misceláneas? Usualmente no hay razón, porque no hay datos que se diferencien de una instancia a otra.</p>
<p>Acá entra Singleton y es donde JSON se vuelve muy útil. Con él podemos declarar una única instancia y todos sus miembros de una sola llamada, sin meternos con los constructores:</p>
<pre name="code" class="js">var domUtils = {
getByClass: function(cssClassName) {...}
}</pre>
<h3>haciendolo aún mejor</h3>
<p>Mientras estamos haciendo el <code>domUtils</code> asumamos que esa librería de utilidades podría crecer bastante (siempre lo hacen). Así que vamos a seguir la técnica de YUI para el namespacing, categorizando más las utilidades, y como solo necesitamos una copia, utilizamos JSON para hacerlo. Acá está el esqueleto de mi librería, y le vamos a poner&#8230; eeehh, hmm&#8230; ZAQ, sí ZAQ:</p>
<pre name="code" class="js">var ZAQ = {}  //esto crea un objeto namespace vac&iacute;o

ZAQ.util = {} //un sub-objeto para el paquete de utilidades

//lo granulamos m&aacute;s, con utilidades espec&iacute;ficas para el DOM
ZAQ.util.dom = {
getByClass: function(cssClassName) {...},
elemHasClass: function(elem, className) {...}
}

//podemos agregar m&aacute;s tipos de utilidades en sus propias &quot;categorias&quot;
ZAQ.util.array = {
contains: function(theArray, match) {...}
}
ZAQ.util.string = {
startsWith: function(theString, match) {...},
endsWith:   function(theString, match) {...}
}</pre>
<p>Y así sucesivamente.</p>
<h3>Conclusión?</h3>
<p>Necesitamos una?</p>
<p>Ok, ok&#8230; El fín es que podés usar el poderoso patrón singleton en JavaScript, funciona perfecto para este tipo de librerías de utilidades y un sin fín de cosas más en las que solo necesités una copia corriendo. Mantiene el código fácil de leer, mantiene el namespace intacto y ordenado y además previene colisiones con otras funciones cuando estás integrando otras librerías.</p>
<p>Que te sirva de algo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/singleton-en-javascript-o-como-convertir-constructores-a-json.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Snippet: Detectar un bloqueador de pop-ups</title>
		<link>http://www.elbleg.com/web-dev/javascript/snippet-detectar-un-bloqueador-de-pop-ups.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/snippet-detectar-un-bloqueador-de-pop-ups.html#comments</comments>
		<pubDate>Fri, 24 Jul 2009 07:03:21 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=217</guid>
		<description><![CDATA[Algunas veces no tenemos más alternativa que desplegar información utilizando los abominables pop-ups o ventanas emergentes, en casos como esos topamos como obstáculo que si el usuario tiene el bloqueador activado no podrá ver lo que necesitamos desplegar.

Para casos como esos, este pequeño script, que revisa si el blocker está activado o no con la [...]]]></description>
			<content:encoded><![CDATA[<p>Algunas veces no tenemos más alternativa que desplegar información utilizando los abominables pop-ups o ventanas emergentes, en casos como esos topamos como obstáculo que si el usuario tiene el bloqueador activado no podrá ver lo que necesitamos desplegar.<br />
<span id="more-217"></span><br />
Para casos como esos, este pequeño script, que revisa si el blocker está activado o no con la única forma de hacerlo, creando un pop-up, devolviendo un valor booleano dependiendo si tuvo exito o no. Así si falla podemos pedirle amablemente al usuario que habilite los pop ups.</p>
<pre name="code" class="js">function detectarBlocker() {
    var intento = window.open(&quot;about:blank&quot;,&quot;&quot;,&quot;directories=no,height=100,width=100,menubar=no,resizable=no,scrollbars=no,status=no,titlebar=no,top=5000,location=no&quot;);     if(intento) { // no hay bloqueo
        intento.close();
        return 1;
     } else { // est&aacute; bloqueado
        return 0;
     }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/snippet-detectar-un-bloqueador-de-pop-ups.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Snippet: Etiqueta de compatibilidad, Forza a IE8 a renderizar como IE7</title>
		<link>http://www.elbleg.com/web-dev/snippet-etiqueta-de-compatibilidad-fuerza-a-ie8-a-renderizar-como-ie7.html</link>
		<comments>http://www.elbleg.com/web-dev/snippet-etiqueta-de-compatibilidad-fuerza-a-ie8-a-renderizar-como-ie7.html#comments</comments>
		<pubDate>Mon, 13 Jul 2009 07:42:20 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Web Dev]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=211</guid>
		<description><![CDATA[Si, en definitiva más de uno me va a querer patear por esto, pero bueno, de repente sea útil alguna vez. 
Si tu sitio no está mostrandose adecuadamente en IE8, podés obligarlo a comportarse como IE7 solía hacerlo. No digo que IE8 sea malo, pero paga los platos rotos de sus hermanastras malvadas&#8230; digo, de [...]]]></description>
			<content:encoded><![CDATA[<p>Si, en definitiva más de uno me va a querer patear por esto, pero bueno, de repente sea útil alguna vez. </p>
<p>Si tu sitio no está mostrandose adecuadamente en IE8, podés obligarlo a comportarse como IE7 solía hacerlo. No digo que IE8 sea malo, pero paga los platos rotos de sus hermanastras malvadas&#8230; digo, de los IE anteriores.<br />
<span id="more-211"></span><br />
Con este tag podés forzar al rendering engine de Internet explorer 8 para que funcione como Internet explorer 7:</p>
<pre name="code" class="xml">&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=EmulateIE7&quot;&gt;</pre>
<p>O bien, si estás en apache podés hacerlo desde el .htaccess con esta línea:</p>
<pre name="code" class="xml">Header set X-UA-Compatible IE=EmulateIE7</pre>
<p>Podés leer más información al respecto en el <a href="http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx">sitio de Microsoft (en inglés)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/snippet-etiqueta-de-compatibilidad-fuerza-a-ie8-a-renderizar-como-ie7.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Snippet: Arreglar el Z-Index en IE7 con jQuery o MooTools</title>
		<link>http://www.elbleg.com/web-dev/javascript/jquery/snippet-arreglar-el-z-index-en-ie7-con-jquery-o-mootools.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/jquery/snippet-arreglar-el-z-index-en-ie7-con-jquery-o-mootools.html#comments</comments>
		<pubDate>Mon, 13 Jul 2009 07:01:53 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[snippet]]></category>
		<category><![CDATA[z-index]]></category>
		<category><![CDATA[Zindex]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=208</guid>
		<description><![CDATA[Por alguna razón malvada, Internet Explorer 7 hace algunas cosas raras  (además de tener una larga lista bugs conocidos en su motor) que siempre se las ingenian para volver a los web developers locos. Mientras algunos errores ocurren de forma oscura y dificil de notar, hay algunos que causan que pasemos horas tratando de [...]]]></description>
			<content:encoded><![CDATA[<p>Por alguna razón malvada, Internet Explorer 7 hace algunas cosas raras  (además de tener una larga lista <a href="http://www.quirksmode.org/bugreports/archives/explorer_7/index.html">bugs conocidos</a> en su motor) que siempre se las ingenian para volver a los web developers locos. Mientras algunos errores ocurren de forma oscura y dificil de notar, hay algunos que causan que pasemos horas tratando de arreglarlos. La forma en que IE7 renderiza el orden del z-index es una de ellas. </p>
<p>Una de las formas de arreglarlo es cambiando dinámicamente el orden por default de los elementos de la página. Esto asegura que los elementos en el código HTML tengan el índice adecuado, resolviendo la mayoría de los problemas que causa IE7. </p>
<p>El modo de hacerlo usando jQuery sería algo como:</p>
<pre name="code" class="js">$(function() {
	var zIndexNumber = 1000;
	$(&apos;div&apos;).each(function() {
		$(this).css(&apos;zIndex&apos;, zIndexNumber);
		zIndexNumber -= 10;
	});
});</pre>
<p>Con esto básicamente lo que hacemos es comenzar con un z-index de 1000 y decrementar el indice de cada div de la página en tractos de 10, es decir, el primer elemento tendrá un z-index de 1000, el segundo 990 el tercero 980 y así sucesivamente. Notá que el selector de jQuery encuentra todos los divs con el codigo “<code>$(’div’)</code>”, usando la misma syntaxis que los selectores de CSS, nada dificil.</p>
<p>Ah&#8230; y así se hace lo mismo pero con MooTools, por si estás usando esa biblioteca:</p>
<pre name="code" class="js">if(Browser.Engine.trident){
	var zIndexNumber = 1000;
	$$(&apos;div&apos;).each(function(el,i){
		el.setStyle(&apos;z-index&apos;,zIndexNumber);
		zIndexNumber -= 10;
	});
};</pre>
<p>Saluuú.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/jquery/snippet-arreglar-el-z-index-en-ie7-con-jquery-o-mootools.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Generador de Bookmarklets [actualizado]</title>
		<link>http://www.elbleg.com/web-dev/javascript/generador-de-bookmarklets.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/generador-de-bookmarklets.html#comments</comments>
		<pubDate>Mon, 06 Jul 2009 22:01:30 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[Web Dev]]></category>

		<guid isPermaLink="false">http://eldomo.net/yeco_blog/archives/generador-de-bookmarklets</guid>
		<description><![CDATA[Como últimamente los bookmarklets se han puesto muy de moda, no está de más publicar uno que sirva en el trabajo.
La idea con este es ayudar con los forms, evitandonos el engorroso trabajo de llenarlos una y otra vez para probarlos.
El generador toma el form en que estás trabajando y  crea un bookmarklet específico [...]]]></description>
			<content:encoded><![CDATA[<p>Como últimamente los bookmarklets se han puesto muy de moda, no está de más publicar uno que sirva en el trabajo.</p>
<p>La idea con este es ayudar con los forms, evitandonos el engorroso trabajo de llenarlos una y otra vez para probarlos.</p>
<p>El generador toma el form en que estás trabajando y  crea un bookmarklet específico para los campos que necesitas, con la info que necesitas.<br />
<span id="more-69"></span></p>
<h3>Cómo se usa?</h3>
<p>Simple, solo agregas un bookmark y a este lo editas y le cambias la url colocando en su lugar este script.<br />
<!-- ALERTA: hay estilos incrustados en el textarea!!, perdon perdon!! --><br />
<textarea wrap="on" class="js" style="width: 100%; height: 100px; font-size: 8pt;">javascript:var fz=new Array();var z=new Array();function F(p){var m=new Array();for(n=0;n
<p.length;n++){var q=new Array();for(ind=0;ind<p[n].length;ind++){q.push('\''+p[n][ind]+'\'')}m[n]=eval('['+q.join(',')+']');}return m;}function C(n,cz){var i=-1;for(ab=0;ab<cz.length;ab++){if(cz[ab][1]==n)i=ab;}return i;}function B(){fz.length=0;if(!document.forms.length){alert('There are no forms in this page.');return;}for(fi=0;fi<document.forms.length;fi++){z.length=0;f=document.forms[fi];for(i=0;i<f.length;i++){ip=f.elements[i].type;iv=f.elements[i].value;ix=f.elements[i].name;if(!iv){continue;}if(ip=='text'||ip=='textarea'||ip=='select-one'||ip=='password')z.push(['d',ix,iv]);if(ip=='radio'||ip=='checkbox'||ip=='select-multiple'){x=C(ix,z);if(x==-1){if(ip=='select-multiple'){iv=%22%22;for(g=0;g<f.elements[i].length;g++){if(f.elements[i][g].selected){iv+=f.elements[i][g].value+%22|%22;}}z.push(['s',ix,iv]);}if(ip=='radio'){if(f.elements[i].checked){z.push(['c',ix,iv]);}}else{if(f[ix].length){if(f.elements[i].checked){z.push(['c',ix,iv]);}}else{if(f.elements[i].checked){z.push(['n',ix,'']);}}}}else{if(f.elements[i].checked){z[x][2]+=%22|%22+iv;}}}}fz.push(F(z));}bms=new Array();for(f=0;f<fz.length;f++){if (!fz[f].length){continue;}bm=%22java%22+%22script:function D(a,b){c=b.split('|');d=false;for(q=0;q<c.length;q++){if(c[q]==a)d=true;}return d;}%22;bm+=%22function E(){f%22+f+%22=document.forms[%22+f+%22];%22;for(k=0; k<fz[f].length; k++){if(fz[f][k][0]==%22d%22){bm+=%22f%22+f+%22['%22+fz[f][k][1]+%22'].value='%22+fz[f][k][2]+%22';%22;}if(fz[f][k][0]==%22n%22){bm+=%22f%22+f+%22['%22+fz[f][k][1]+%22'].checked=true;%22;}if(fz[f][k][0]==%22c%22){bm+=%22for(i=0;i<f%22+f+%22['%22+fz[f][k][1]+%22'].length;i++){if(D(f%22+f+%22['%22+fz[f][k][1]+%22'][i].value,'%22+fz[f][k][2]+%22')){f%22+f+%22['%22+fz[f][k][1]+%22'][i].checked=true;}}%22;}if(fz[f][k][0]==%22s%22){bm+=%22for(i=0;i<f%22+f+%22['%22+fz[f][k][1]+%22'].length;i++){if(D(f%22+f+%22['%22+fz[f][k][1]+%22'][i].value,'%22+fz[f][k][2]+%22')){f%22+f+%22['%22+fz[f][k][1]+%22'][i].selected=true;}}%22;}}bm+=%22}E()%22;bms.push(bm);}w= window.open('','','toolbar,width=150,height=100');for(f=0;f<bms.length;f++){w.document.write(%22<a href=\%22%22+bms[f]+%22\%22>Form #%22+(f+1)+%22</a><br />%22);}w.document.write(%22Arrastra el link a tu toolbar.%22);w.document.close();}B();</textarea></p>
<p>Luego, llenas los campos del form en que estás trabajando, das click en el generador y este abre un popup con un link al bookmarklet generado. Arrastrás el link a tu barra de bookmarks y listo, cada que lo actives te llena los campos solo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/generador-de-bookmarklets.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
