Contenido

Detectar el tipo de una variable en Javascript

13 ene

+ 3

Cuando intentamos detectar si una variable que estamos usando en nuestros scripts Javascript podemos usar operadores como typeof que nos devolverá el tipo de variable que estamos usando, pero ¿es la forma correcta?

typeof null; // "object"
typeof []; // "object"

instanceOf / .constructor

Por desgracia typeof es un operador ya bastante viejo y nos arroja resultados un poco ambiguos y en ocasiones nos hacen ir hacia atrás en lugar de avanzar. Las nuevas revisiones de Javascript, arrojan un poco de luz en la detección del tipo de variables usados mediante 1 operador y/o una propiedad de las variables.

Operador instanceof

Nos permite comprobar si un elemento es de un tipo concreto informándolo previamente.

var a = [];
a instanceof Array; // True
a instanceof String; // False

De esta forma podremos validar más certeramente el tipo que estamos esperando para una variable de nuestro script.

Propiedad .constructor

También podemos preguntarle a la variable que constructor ha sido empleado con ella, para ello deberemos hacer uso de la propiedad constructor de la propia variable.

var a = [];
a.constructor == Array;

¿Cual es mejor?

Ambos métodos nos ayudan a detectar, mucho más fiablemente, el tipo de variable que estamos usando pero una es más rápida que otra.

Para probarlo, como casi todas las pruebas de este tipo he creado un pequeño script que lanza 10.000 y 100.000 consultas de cada uno de los métodos a 2 variables iguales y los resultados hablan por si solos.

La prueba:

var t = new Date().getTime();
for (var x =0; x<10000; x++){
    var a = [];
    a instanceof Array;
}
console.log(new Date().getTime() - t);

var t = new Date().getTime();
for (var x =0; x<10000; x++){
    var b = [];
    b.constructor == Array
}
console.log(new Date().getTime() - t);

Los resultados

10.000 100.000
instanceof 32 351
.constructor 82 813

¿Problemas?

Pues claro, no iba a ser todo tan fácil como parecía :D

Aparecen problemas cuando se crean multiples entornos DOM mediante el uso de frames. En pocas palabras, los arrays creados dentro de un <iframe /> no son iguales que los contenidos en otro <iframe />, sus constructores son diferentes por lo tanto ambas propiedades fallan.

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]  

// Boom!
arr instanceof Array; // false  

// Boom!
arr.constructor === Array; // false

Douglas Crockford lo comentó por allá sobre el 2003 y como solución propuso que se comprobara alguno de los métodos del Array para detectar si este es una función o no.

typeof myArray.sort == 'function'

En Prototype.JS 1.6.0.3 usan un método parecido para detectar si se trata de un Array usando este sistema.

function isArray(object) {
  return object != null && typeof object === "object" &&
    'splice' in object && 'join' in object;
}

Aunque esto nos vuelve a generar otra problemática, las variables de tipo “object” también poseén esos métodos y si comparamos un objeto con isArray() técnicamente devolverá un TRUE como una casa. Por ello Perfection Kills propone una solución más sencilla con la que detectar un Array y dejar de tener problemas con los multiframes.

function isArray(o) {
  return Object.prototype.toString.call(o) === '[object Array]';
}

Personalmente no me gusta, ya que dependemos de una cadena que los desarrolladores del motor JS del navegador del usario para detectar el tipo de variable que estamos usando, si por algún motivo alguien usó [object array] en lugar de [object Array] ya volvemos a tener uno de los problemas que typeof nos ha estado dando hasta hace poco.

iMeneame.net ahora más móvil que nunca

12 ene

+ 2

Ayer le dediqué unas horas a depurar el código de iMeneame.net para que se adaptar más a los dispositivos móviles. Ya que gracias a Lucas tenemos tenemos un aspecto mejorado y especificado para el iPhone, creía necesario efectuar un cambio para otros dispositivos con pantallas más pequeñas.

Convierte tu Windows XP en Windows 7

12 ene

+ 6

Si estás harto de tu Windows XP/Vista y te gustaría ver el aspecto de Windows 7 en tus manos. Puedes hacerlo con este pack (Se7en) que te permite cambiar el aspecto del sistema operativo y así capear la rutina.

veaxaq

El pack contiene:

  • Windows Se7en Visual Style
  • Windows Se7en Start Menu
  • Windows Se7en Styler TB
  • Windows Se7en Pie Dock
  • Windows Se7en Wallpapers

IMPORTANTE:

Mariano me avisa de que el pack contiene un trojano.

Pseudo-ajax para leer ficheros locales

12 ene

+ 7

CSSGalery.info nos muestra una solución para leer fichero cuando ejecutamos HTML desde nuestro local. Detectando si la página está siendo ejecutado en un entorno local mediante el protocolo file: de la URL decide como actuar ante una llamada a la función get_content().

function get_content(url,update) {
	if ( document.location.protocol == "file:" ) {
		// console.log("local");
		var ifr = new IFrame({
		src:url,
		events:{
		load: function() {
				$(update).set("html", this.contentWindow.document.body.innerHTML );
			}
		}
		}).inject(document.body);
	}else {
		// console.log("server");
		var myHTMLRequest = new Request.HTML({
		update:update,
		}).get(url);
	}
}

La función get_content(), a la que le pasamos la ruta y donde queremos descargar el cotenido se encarga de hacer todo el trabajo por nosotros. Para los que no usamos MooTools he montado una versión en JS sin necesidad de trabajar con ningún framework.

function get_content(url,update) {
  if ( document.location.protocol == "file:" ) {
    var ifr = document.createElement("iframe");
    ifr.src = url;
    ifr.onload = function() {
	document.getElementById(update).innerHTML = this.contentWindow.document.body.innerHTML;
    }
    document.getElementsByTagName("body")[0].appendChild(ifr);
  }else {
    var ajax = (XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
    ajax.open('GET', URL);
    ajax.onreadystatechange = function(){
		document.getElementById(update).innerHTML = ajax.responseText;
    };
    ajax.send(null);
  }
}

Desde CSSGallery.info podemos testear la versión online y/o descargar un zip para probarlo en nuestro local.

Sistema solar a escala con Javascript

12 ene

+ 10

El otro día estuve viendo un documental sobre el sistema solar, he de decir, que los documentales de astronomía son mi otra pasión. Después de verlo y de escuchar las increibles distancias y medidas que el cosmo nos ofrece pensé…¿Como sería el sistema solar en una página web?

sistemasolar

Se que no podía hacer algo tan chulo como este, pero podía hacer aún más geek, en JS :D

Sistema solar a escala en Javascript.

Aclaraciones

  1. He quitado Plutón, por el tamaño  no por su denominación.
  2. Las medidas usadas como base son: El diámetro de la tierra para el diámetro de los planeta y la distancia de la tierra al sol como distancia entre planetas.
  3. Existe una limitación de tamaño de fuente por el navegador, por ese motivo Betelgeuse es una O, su tamaño no está a escala ya que es imposible representar ese tamaño con un carácter a escala y que los demás planetas (mercurio y marte) se vea.
  4. Me aburría mucho y no invertí más de 30 minutos en desarrollarlo :P

La página más visitada de aNieto2k (opensearch.php)

11 ene

+ 10

OpenSearch es un estandard que nos permite añadir motores de busqueda a aplicaciones como por ejemplo Firefox, IE7,… Gracias a este estandard es posible hacer que nuestras aplicaciones estén interconectadas con estas aplicaciones de forma fácil y rápida.

wp-opensearch.jpg

En aNieto2k esta opción da lugar a la página más visitada del blog. Siendo el mes pasado (Diciembre de 2008) un 15% más visitada que el index.php (el fichero encargado de mostrar el contenido de blog en formato HTML). Pero ¿como lo integré en WordPress?

WP-OpenSearch

Para WordPress podemos usar este plugin que hice y que nos permitirá disponer de OpenSearch en nuestro WordPress muy fácilmente. Como con todos los plugins de WordPress. [Descargar]

Manualmente

Para las aplicaciones web que no estén basadas en WordPress podemos implementar un sistema muy sencillo basado en 1 fichero .php y la insercción de una línea en el <head /> de nuestro HMTL.

1) Modificamos el header de nuestro HTML

<head>
...
<link rel="search" type="application/opensearchdescription+xml" title="Buscador de SITIO_WEB" href="RUTA_DEL_FICHERO/opensearch.php" />
...
</head>

Añadimos en nuestro <head /> la línea que dirigirá al fichero opensearch.php encargado de gestionar OpenSearch. En el tag <link /> debemos modificar SITIO_WEB la ruta del sitio web y RUTA_DEL_FICHERO por la ruta que nos llevará hasta opensearch.php

2) Creamos el fichero opensearch.php

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
  <ShortName>NOMBRE_DEL_SITIO</ShortName>
  <Description>DESCRIPCION_DEL_SITIO</Description>
  <Tags>TAG TAG2 TAG3</Tags>
  <Contact>EMAIL_ADMIN</Contact>
  <Url type="TYPE_RESPUESTA"
       template="PATRON_DEL_BUSCADOR"/>
<!-- http://example.com/?q={searchTerms}&amp;pw={startPage?}-->
</OpenSearchDescription>

El fichero opensearch.php basta que tango estas líneas para funcionar, aunque el estandar ofrece una gran cantidad de tags que permiten personalizar más la búsqueda. Para adaptarlo a nuestra aplicaciones deberemos reemplazar lo que nos encontramos en negrita.

  • NOMBRE_DEL_SITION: Nombre del sitio que aparecerá en agregador de buscadores.
  • DESCRIPCION_DEL_SITIO: Descripción de la aplicación web
  • TAG…: Tags que ayudarán a catalogar el sitio web.
  • EMAIL_ADMIN: Email del administrador del sitio.
  • TYPE_RESPUESTA: Tipo de respuesta que vamos a devolver la busqueda. (application/rss+xml, text/html,…)
  • PATRON_DEL_BUSCADOR: Url que nos vincula el OpenSearch con el buscador interno de nuestra aplicación.

La Url que introducimos posee unas variables que pueden ser usadas y se reemplazarán por el valor que se envie en la consulta.

  • searchTerms: Hace referencia a los términos de busqueda.
  • count: Número de resultados deseados por el usuario
  • startIndex: Posición inicial desde la que mostrar los resultados.
  • startPage: Página inicial desde la que mostrar los resultados.
  • language: Lenguaje de solicitud de la busqueda.
  • inputEncoding: Codificación de entrada.
  • outputEncoding: Codificación de salida.

Evidentemente estos parámetros no tienen por que ser tenidos en cuenta en nuestras aplicaciones, pero montando url’s como estas obtenemos más datos de la consulta.

http://example.com/?q={searchTerms}&amp;count={count}&amp;output={outputEncoding}

En Javascript

window.external.AddSearchProvider(engineURL);

En Javascript, tambien podemos añadir el motor de busqueda al navegador del usuario (FF2+, IE7, …) mediante esta pequeña línea, a la que reemplazando engineURL por la ruta donde encontrar el fichero opensearch.php nos vinculará nuestra aplicación con el motor de busquedas del usuario.

Más Información

Si quieres ampliar esta información dispones de mucho en OpenSearch.org

  1. Página del proyecto
  2. Mozilla Developer Center

Firebug1.3.0 disponible

8 ene

+ 7

Si amas a Firebug estás de enhorabuena, por fín tenemos la versión 1.3.0 disponible para instalar en nuestro Firefox.

Interesante forma de mejorar los comentarios con jQuery

7 ene

+ 4

Jim Jeffers ha publicado un artículo a modo de ejemplo para mostrar una forma de mejorar la legibilidad de los comentarios de su blog.

encouraged-commentary

Como podemos ver en la imagen se añaden una serie de opciones que enlazan un comentario con otro dentro del mismo hilo, estos comentarios son respuestas a este y nos ayudarán a seguir el hilo de los mismo más fácilmente. Tambíen nos ofrece la posibilidad de citar una porción del texto del comentario seleccionando el texto que queremos citar, una vez seleccionado nos mostrará un botón para responder dicho comentario.

encouraged-commentary2

Una propuesta interesante de la que disponemos el código fuente para implementarlo en nuestros proyectos (requiere bastante modificaciones).

Detecta que hacen tus usuarios con Twitter

7 ene

+ 2

Via Ajaxian, descubro un método de obtener el estado de tus usuarios al entrar en tu página mediante sus cuentas de Twitter. Si estos están logueados en Twitter podrás obtener información de su último tweet y mostrarlo en tu página.

<div id="twitteruser"></div>
<script type="text/javascript">
  function ohaitwitter(data){
    var container = document.getElementById('twitteruser');
    out = '<ul>'+
          '<li>'+
          '<img src="' + data[0].user['profile_image_url'] + '"'+
               'alt="' + data[0].user.name + '"><strong>'
           + data[0].user.screen_name +
           '</strong></li>'+
           '<li>' + data[0].user.name + '</li>' +
           '<li>' + data[0].user.location + '</li>' +
           '<ul>' +
             '<li>' + data[0].text +'</li>' +
          '</ul></li></ul>';
    container.innerHTML = out;
  }
</script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline.json?count=1&amp;callback=ohaitwitter"></script>

La llamada al timeline de Twitter viene condicionada por el parámetro count, el que podemos alterar y recibir X últimos tweets del usuario. Como parámetro, la función que indicamos en callback recibirá el objeto json procedente de Twitter.

Detectar si el usuario dispone de Twitter sería tan sencillo como esto:

function hasTwitter(data){
  if(data.error){
    // No tiene Twitter
  } else {
    // Si tiene Twitter
  }
}

Veamos algunos de los parámetros disponibles.

data.in_reply_to_user_id
data.truncated
data.created_at
data.user
data.followers_count
data.profile_image_url
data.url
data.name
data.protected
data.screen_name
data.location
data.id
data.favorited
data.in_reply_to_screen_name
data.text
data.in_reply_to_status_id
data.source

La posibilidad de obtener datos datos procedentes de twitter ha abierto muchos hilos de discusiones entre los desarrolladores ya que atenta contra la privacidad de los usuarios de Twitter.

El problema reside en que para obtener estos datos, el usuario debe estar loguado en Twitter lo que permite cargar el script desde nuestra página, si el usuario no está logueado en Twitter nos saltará un error indicando que este no está loguado.

¿Cuando nuestro javascript está demasiado tiempo ejecutándose?

7 ene

+ 3

¿Cuantas veces nos hemos encontrado con una ventana como la de abajo al ejecutar un bucle realmente largo?

firefox_dialog

Seguramente muchas, pero ¿alguna vez te habías planteado que criterios iba a usar el navegador para lanzar dicho mensaje? Pues al parecer hay gente que si lo ha hecho y ha sacado las siguientes conclusiones:

  • Internet Explorer salta si se sobrepasan los 5 millones de declaraciones javascript. Puede modificarse directamente desde el registro de Windows.
  • Firefox interpreta que un script se ha vuelto inestable a los 10 segundos de ejecución. También podemos cambiarlo desde about:config.
  • Safari/WebKit indica en su código que el mensaje nos lo mostrará tras 5 segundos de ejecución de un script. Podemos incrementar este tiempo desde el menú desarrollo.
  • Chrome no especifica un tiempo concreto, pero se ha detectado que está entre los 5 y los 10 segundos de ejecución. Además es el más salvaje de todos ya que en lugar de parar el script no cierra la página completa.
  • Opera no tiene limitación de tiempo de scripts, algunas pruebas alcanzaron minutos de ejecución y Opera seguía ejecutando el script.