Contenido

Los usuarios me avisan

29 Jun

+ 2

Via email he recibido un par de artículos interesantes que me parece interesante compartir:

  1. Pautas de diseños en Photoshop [peivem.com]
  2. Ventanas gelatinosas con Javascript y CSS Transformations [Turleando.com.ar]
  3. Honda Insight [Vimeo] (Via Hans Christian)

Si quieres compartir algo, solo tienes que hacermelo saber :D

Evita SPAM invirtiendo tu email con CSS

23 Jun

+ 21

Via Sentido Web descubro un artículo muy interesante que nos muestra como el ingenio puede ayudarnos a solucionar problemas. En este caso, mediante el uso de la propiedad direction del CSS invertimos nuestro email para mostrarlo correctamente por pantalla.

<style type="text/css">
span.test { direction: rtl; unicode-bidi:bidi-override; }  
</style>
<p><span class="test">moc.liamg@5k2oteina</span></p>

Interesante técnica para evitar el SPAM. Quizás como recomendación recomendaría email con algún punto en el nombre para hacer más dificil la lectura del mismo (xxx.yyy@zzzz.aaa). Incluso deberíamos tener en cuenta a los visitantes que no tengan activas las CSS e informar que ese correo está al revés aunque despues ocultemos el texto mediante CSS para los que si lo tengan activado.

8 innovaciones de los navegadores gracias a Opera

12 Jun

+ 21

El otro día nos preguntábamos por que Opera, pese a ser uno de los navegadores más innovadores disponibles era tan poco usado. Al parecer la gente de Geek Technica se pregunta lo mismo y además recuerda 8 de las novedades que Opera introdujo en el mundo de los navegadores web.

  1. SpeedDial: El marcado rápido de los marcadores. Hasta 9 páginas a las que podrás acceder con un simple click.
  2. Tabs: La famosa y tan aclamada navegación por pestañas.
  3. Sesiones: Gestión de diferentes sesiones que permite que diferentes usuarios gestionen el navegador a su antojo.
  4. Bloqueo de Pop-up: Esa maravilla que hizo que al entrar en una página dejaramos de cruzar los dedos por si aparecían miles de ventanas.
  5. Zoom: Opera comenzó haciendo zoom a la página completa y no solo al texto.
  6. BitTorrent: Quizás la más tonta de todas, pero también ha dado lugar a la integración por parte de otros navegadores.
  7. Borrar información privada: La capacidad de eliminar la información almacenada durante la navegación.
  8. Gestos de ratón: Yo no la he usado nunca, pero la gente que lo ha hecho está encantadísima.

En fín, un sin fín de novedades que poco a poco los demás navegadores las van incorporando a sus núcleos.

Interesante curiosidad javascript

10 Jun

+ 35

Esta mañana he encontrado un artículo, que esta noche publicaré, en el que me he encontrado una interesante curiosidad javascript, os la dejo y a ver si alguien lo encuentra :D


var divs = document.getElementsByTagName("div");
for (var i=0; i < divs.length; i++) {
       var div = document.createElement("div");
       document.body.appendChild(div);
}

Primero, y sin probar el código intenta comprender que es lo que hace el script, una vez visualizado y comprobado que no haya errores, pruebalo, ya sea en Firebug, o en una página aposta. ¿A ver si alguien me sabe decir por que ocurre esto? Esta noche, o mañana por la mañana pondré la solución y el enlace donde lo ví, pero seguro que lo sacáis antes :D …. tiempo!!

Intenta no leer los comentarios y contestar lo que has pensado.

Actualización

Bueno, los comentaristas están mucho más puestos que yo en Javascript, y nos han deleitado con comentarios explicativos imposibles de mejorar, así que si quieres saber algo más sobre los HTMLCollection, NodeList y demás, lee los comentarios. El código lo he sacado de un artículo de Nicholas C. Zakas sobre optimización Javascript y me ha parecido muy curioso :D

for reverso para grandes interaciones en Javascript

28 May

+ 20

Luigi, me muestra hoy un artículo muy interesante sobre optimización de Javascript. En él encontramos un ejemplo de como mejorar nuestras iteraciones en nuestro código. Simplemente debemos pensar en decrementar la variable que estamos iterando. He montado un pequeño ejemplo para testear 50.000, 500.000 y 5.000.000 de iteraciones simples. Los resultados hablan por si solos:

[increment]50.000 iteraciones: 11ms. (50000)
[decrement]50.000 iteraciones: 2ms. (50000)
[increment]500.000 iteraciones: 115ms. (500000)
[decrement]500.000 iteraciones: 19ms. (500000)
[increment]5.000.000 iteraciones: 1188ms. (5000000)
[decrement]5.000.000 iteraciones: 181ms. (5000000)

Funciones

El código del ejemplo es muy sencillo y como se puede ver, únicamente se encarga de incrementar la variable y, en ambas.

	var fors = {
		increment: function(iterations){
				var y = 0;
				for (var i=0;i<iterations;i++){
					y++;
				}
				return y;
		},
		decrement:function (iterations){
			var y = 0;
			for (var i=iterations;i>0;i--){
				y++;
			}
			return y;
		}
	}

Como podemos ver, un pequeño cambio puede significar reducir entre un 200 y un 600% el tiempo de procesamiento de nuestros scripts. ¿Alguna optimización más?

Explicación

El motivo de esta diferencia de tiempo, es debido a que increment() debe realizar una revisión del valor de iterations por cada pasada por el bucle. De esta forma, se realiza un acceso a memoria para solicitar el valor de la variable, algo que no pasa en decrement() que al comparala con 0, nos ahorramos dicha consulta.

Extiende Google Analytics con jQuery

18 May

+ 10

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

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

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

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

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

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

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

Tambien puedes descargarlo para usar en tu aplicación.

Multilíneas en Javascript

5 May

+ 5

Siempre que intentamos escribir un script en Javascript que requiere un string de varias líneas conseguimos un error de que el código está mal formado. Eso es un problema para estos scripts que generar contenido HTML, ya que al tenerlo en una línea perdemos claridad y no vemos exactamente lo que estamos pintado.

Hoy en Snook.ca, nos muestra un sistema para conseguir Strings en Javascript con saltos de línea, lo que nos permite hacer cosas así:

$('#ID').append(
   '<div id="page"> \
      <p class="texto">bla bla bla</p> \
    </div>'
);

La clave está en usa (\) para indicar el salto de línea, esto, misteriosamente, hace que el navegador detecte que se trata de una sola línea, haciendo el trabajo de unirlas por nosotros.

Una curiosidad más de esta lenguaje que nos ayuda a hacer las cosas más fáciles y sobretodo claras.

Instala TODAS las versiones de Internet Explorer en tu PC

29 Abr

+ 40

Esperemos que estas herramientas desaparezcan de una vez por todas, por que además de aberrante es muy molesto. Imagina, tener todas las versiones de Internet Explorer instaladas en tu máquina. Si esta no se cuelga voluntariamente y decide darte la posibilidad de probar el Internet Explorer 1.5 e ir viendo la evolución de las diferentes versiones verás que tus aplicaciones no se verán igual en ninguna de ellas.

iecollection_setup_02_components1
(Ver Imagen)

Con Internet Explorer Collection podrás instalar:

  • Internet Explorer 1.0 (4.40.308)
  • Internet Explorer 1.5 (0.1.0.10)
  • Internet Explorer 2.01 (2.01.046)
  • Internet Explorer 3.0 (3.0.1152)
  • Internet Explorer 4.01 (4.72.3110.0)
  • Internet Explorer 5.01 (5.00.3314.2100)
  • Internet Explorer 5.5 (5.51.4807.2300)
  • Internet Explorer 6.0 (6.00.2800.1106)
  • Internet Explorer 6.0 (6.00.2900.2180)
  • Internet Explorer 7.0 (7.00.5730.13)
  • Internet Explorer 8.0 (8.00.6001.18702)
  • Internet Explorer Developer Toolbar 1.00.2188.0

Y se el más guay de tu clase, además podrás desarrollar para todos ellos si aún lo sigues haciendo. Realmente imprescindible para todos aquellos puristas que desean que sus aplicaciones lleguen a todos, sin excepción :D

Descargar (55,4MB)

getCommentsFromPingbacks(), trae los comentarios de tus pingbacks

28 Abr

+ 7

La proliferación de blogs ha hecho que le contenido esté muy distribuido por Internet y de un artículo pueden llegar a salir miles de links (pingbacks) en los que puede haber debate sobre el mismo contenido inicial.

Imagina que pueda estar vinculado con todos los blogs (Wordpress) que han hecho un ping a tus artículo, y que en tu blog puedas mostrar los comentarios de estos blogs (siempre y cuando estos lo permitan).

getCommentsFromPingbacks() es una función que he montado que permite mostrar de los pingbacks encontrados por cada post, un listado de comentarios sobre esa anotación en cada uno de los anteriores pingbacks.

El código

<?php
include_once(ABSPATH . WPINC . '/rss.php');
function getCommentsFromPingbacks($postID = 0, $limit = 5, $propios = false){
  global $wpdb;
  // Obtenemos la dirección de nuestro blog
  $localhost = '';
  if ($propios)
  	$localhost = "AND comment_author_url NOT LIKE '".get_option("siteurl")."%";

  // Lanzamos petición
  $urls = $wpdb->get_results("SELECT comment_author, comment_author_url FROM $wpdb->comments WHERE comment_post_ID = ".intval($postID)."  $localhost AND comment_type = 'pingback' AND comment_agent LIKE '%WordPress%' LIMIT ".intval($limit));

  // Sinó hay pingbacks, salimos
	if (!$urls) return;

	// Recorremos los pingbacks
	foreach($urls as $url) {
		// Parátro RSS de comentarios
		if (strpos($url->comment_author_url,'?') === false) $actual = $url->comment_author_url.'?feed=comments-rss2';
		else $actual = $url->comment_author_url.'&feed=comments-rss2';

   // Leemos comentarios
    $rss = fetch_rss($actual);

    // Si no hay $rss o items seguimos con el siguiente.
    if (!$rss || !$rss->items) continue; 

	$items = array_reverse($rss->items);

	echo '<h3>'.$url->comment_author.'</h3><ul class="external_comments">';
	for($id = count($items); $id>0; $id--){
        $item = false;
        // Datos basicos
        $item->comment_author = $items[$id]['dc']['creator'];
        $item->comment_author_url = $items[$id]['link'];
        $item->comment_date = $items[$id]['pubdate'];
        $item->comment_content = $items[$id]['content']['encoded'];

        // comment_ID
        $item->comment_ID = 'external-'.$id;
        $item->comment_type = 'external';

	// Pintamos el comentario
        createComments($item);
    }
    echo '</ul>';
  }
}
/*
   Pintamos el comentario
*/
function createComments($com) {
	echo '<li>
		<h4>'.$com->comment_author.'</h4>
		<small>'.$com->comment_date.'</small>
		<div class="comment_content">
			'.$com->comment_content.'
		</div>
	</li>';
}

// Solicitamos los comentarios del post
getCommentsFromPingbacks($post->ID);
?>

El código, se encarga de buscar pingbacks en el post indicado como parámetro. Además podemos indicar un límite de sitios que comprobar, por defecto le he puesto 5 (hay que tener en cuenta el tiempo de carga de la página) y despues como tercer parámetro podemos indicar si queremos que aparezcan los comentarios enlazados de nuestro propio blog.

Una vez localizadas las url’s de los pingbacks, procedemos a solicitar los comentarios, para ello usamos el parámetro de Wordpress feed=comments_rss2, que nos devolverá un RSS con los comentarios del post. Esto implica una limitación de tamaño (sinó recuerdo mal, no he podido probarlo) y que el blog externo debe tenerlo activo. Mediante el uso de fetch_rss() podremos realizar la petición y además recibir el comentario como un objeto fácil de iterar y procesar.

El código está pensado para usarse en el sistema de comentarios de Wordpress 2.7, creando un comentario virtual con los datos necesarios para que el callback de wp_lists_comments() pueda procesarlo como un comentario.

Por defecto, indicará el atributo class de cada comentario, como “external”, esto es debido al comment_type que lo informamos en la función.

Para el ejemplo, he montado createComments() que recibe un parémtro $com, que es el comentario con los datos necesarios.

¿Donde iría este código?

Pues este código solo necesita que se cumpla una premisa y es que el ID del comentario esté informado. Realmente puede ir cualquier parte de Wordpress siempre y cuando se pase el ID de un artículo de nuestro Wordpress. Si usamos el ejemplo tal cual, debería estar dentro del Loop y más concretamente en el fichero comments.php de nuestro theme, pero lo mejor es ir probando y ubicarlo en el sitio que creamos más acertado.

¿Que os parece?

Opiniones, impresiones, se agredecen.

Dojo es el framework Javascript más rápido

31 Mar

+ 11

Hoy Ajaxian, publica un artículo que yo quería haber escrito hace unas semanas. TaskSpeed es una aplicación que usar SlickSpeed para testear los principales frameworks JS en acciones DOM básicas. Los resultados obtenidos han declarado a Dojo como el framework JS más rápido, seguido de MooTools 1.2.1 y jQuery 1.3.2.

frameworks_speed_test
(Ver Imagen)

Estos resultados puedes comprobarlos directamente en el propio test.Es interesante ver como estos resultados son similares a los obtenidos en el Framework Speed Test, una aplicación que monté con la ayuda de todos los que me ayudaron a montar los ficheros de pruebas de cada uno de los frameworks.

frameworks_speed_test3
(Ver Imagen)

framework_speed_test2
(Ver Imagen)

En todos los test, vemos que sorprendentemente jQuery es excesivamente lento y Ext.js impresionantemente rápido. En las pruebas que realicé tenía miedo de lo contrario, ya que al usar el selector CSS (Sizzle) podría beneficiar a jQuery en estos puntos. Lamentablemente esto no le ha servido para nada, principalmente por la generación de DOM que lo hace de una forma diferente a los demás.

jQuery

La función html() de jQuery, genera los elementos DOM y los injecta en el elemento seleccionado, algo más laborioso que los innerHTML que hacen los demás frameworks. Esto no debe servir de excusa, ya que en una versión con innerHTML que monté para igualar los frameworks jQuery no llegaba a despuntar frente a los otros, aunque si que mejoraba algo.

Ext.js

Por otro lado en Ext.js, me ha sido imposible encontrar algo que permita hacer un fireEvent(), bueno miento, monté un sistema que funcionaba, pero era el proceso más lento de los testeados y no me parecía justo implementarlo, así que aparece como Error, pero no es que se haya producido un fallo, sinó es que no está desarrollado.

También me parece interesante destacar los 500kb necesarios para ejecutar Ext.js.(Es un merge de 2 ficheros del framework)

Bueno, si consigo añadir Dojo sería interesante verlo frente a frente a Ext.js.

Proyecto

El proyecto está disponible en GitHub.

Agradecimientos

  1. Jota y Jose Antonio por aguantarme en la infinidad de mails que hemos cruzado.
  2. John Resig, por contestar a un mail sobre la optimización de las pruebas de JS.
  3. Paul Bakaus, por la ayuda ofrecida en la optimización.
  4. JuanPe, Kike, Jordi y Luigi por debatir conmigo los resultados.
  5. A todos vosotros por leerme cada día. ;)