Uf, esto va a ser como un record de errores que he aprendido a la mala. Han sido un montón, pero apenas pensé en iniciar esta serie. Ayer estaba muy tranquilo esperando que se llegara la hora de ir al trabajo. De repente me puse a pensar el cual sería la razón por la que una de mis amigas a quien invite a mi nuevo proyecto, el xismografo, no había escrito uno a pesar de haber contestado el mio sin demora. Era una de dos, o no lo había hecho, o no me había invitado a contestarlo. Ambas eran muy improbables. Decidí ir y revisar los últimos ximografos y me di cuenta que en efecto si había creado un xismografo. Entonces pensé, por que no me invito. Revise la lista de invitados y me di cuenta que sí había intentado invitarme. El problema es que todos los correos los había encerrado en un paréntesis. Por ejemplo, (uncorreo@unsitio.com). La parte de la app que envía los correos simplemente envió las invitaciones a las direcciones tal y como estaban, con paréntesis. Como es de esperarse, esas invitaciones no son validas, y aun que lo fueran, no son las correctas.
Me tocó modificar manualmente una de las tablas en mi base de dato, algo que nunca debe hacerse, pero que esta vez no tenía otra opción. Lo peor de todo es que esa posibilidad de error yo ya la había pensado, pero preferí confiar en que el usuario haría bien las cosas.

Modificar manualmente las bases de datos me trajo otro problema que aun estoy tratando de resolver. El problema no es grabe y es solo con uno de los registros anteriores. Podría decirse que puedo simplemente olvidarme del problema y que no me afectara realmente mucho, pero esa no es una opción cuando quieres que un proyecto tenga éxito.

Otro de los problemas en lo que ya había pensado, pero que también, tontamente, preferí confiar en el usuario, es que a la hora de presionar enter en un formulario, este se envía automáticamente. Por muchos tiempo estuve pensando en cancelar esa acción por que me podría causar resultados no deseados. Por ejemplo el envío de un formulario cuando aun no está completo. Me he dado cuenta que eso fue lo que le pasó a mi amiga.

Estos dos errores me parecieron poco probables que aparecieran, pero al final son los dos errores que presenta la primera persona que intenta crear un xismografo y distribuirlo. Por eso cuando piense en una posibilidad de error en algún sitio o app en la que estés trabajando. O cuando estés organizando cualquier cosa, no te dejes convencer por ti mismo pensando que es muy poco probable que pase. Mejor ponte a trabajar en prevenir y asegurar que efectivamente no pase. Generalmente soy un programador muy negativo. Siempre pensando que mis usuarios van a tratar de hackearme el sitio, que no van a saber ni como prender una compu, que no van a tener javascript activado, que no van a tener imágenes disponibles o css disponible. Trato de prevenir cualquier disfuncionalidad en mis proyectos, pero esta ves simplemente me dejé llevar por el conformismo y un poco de flojera y ahora he tenido que pagar el precio.

Hace ya un buen tiempo que dejé inconclusa una serie de artículos sobre Programación Orientada a Objetos en Javascript. Bueno, aquí traigo esta última entrega, y aun que en la anterior prometí que en esta entrega haríamos una librería, creo que eso quedará más bien fuera del contexto ya que dicha librería no usa mucho los conceptos de POO de los que hemos estado hablando. Sin embargo, ya abriré otra serie para ir creando dicha librería. Más que por el gusto de crear la librería, por el gusto de tocar algunos temas en Js que no se tocan mucho.  Bueno, pero eso será en un futuro. Por ahora me limitaré a hablar sobre cuatro tipos de métodos que pueden ser usados especialmente cuando estamos programando basados en constructores do objetos.

Dependiendo de lo que queramos lograr y de la accesibilidad que queramos darle a los métodos de nuestros objetos podemos usar uno de cuatro tipos de métodos: públicos, privado, privilegiados y estáticos. Empecemos analizando de adentro a afuera, es decir, con métodos privados.

Métodos privados:

Lo métodos privados no son accesibles desde fuera del objeto. Como su nombre lo dice, estos métodos son privados. Nos interesa usar métodos privados por ejemplo cuando queremos darle a nuestro objeto una funcionalidad que no nos interesa o que no nos conviene que sea posible acceder desde fuera del objeto. Consideremos el siguiente ejemplo:

Nota: también hay propiedades privadas y son más comunes que los métodos privados.

function miObj(){
    var nombre =  'Nombre Privado';//propiedad privada
   function privada(){//Método privado
       alert('función privada');
    }//fin del método privado
}

En este caso, el método privada() no puede ser accedido desde ningún lugar fuera de miObj();, es decir que:

var obj = new miObj();
obj.privada();//tira un error.

No es valido por que no hay nada que ligue privada() con el exterior. Pero entonces por que querías un método que no se puede llamar desde ningún lado? Una de las razones es para mantenerte organizado y seguir una de las mejores prácticas de la programación. Me refiero a que cada función tiene que tener solo un trabajo. Por ejemplo:

function miObj(){
    function mostrarOpciones(){
       //Codigo para mostrar opciones
    }
    function crearCanvas(){
       //Código para crear canvas
    }
    mostrarOpciones();
    crearCanvas();
}

Esas dos funciones se ejecutan al mismo tiempo por lo que daría igual hacer lo siguiente:

function mi Obj(){
    //Código para mostrar opciones
    //Código para crear canvas
}

Sin embargo, es mucho más fácil y legible una función que tiene un solo objetivo ya que 1) todo el código está relacionado entre sí, y 2) hay menos lineas de código. Además de que al haber más funciones hay más probabilidades de que un error sea identificado con mayor precisión.

Métodos privilegiados.

Hace un rato vimos los métodos privados. Pero si tienes ojo de debugger, seguro que te diste cuenta que también hemos puesto una propiedad privada (nombre). Al igual que el método privado, la propiedad privada no puede ser recuperada desde fuera del objeto. Es decir que si hace:

alert(obj.nombre);

te va a dar como resultado una alerta que dice undefined. No es un error del navegador. Es simplemente que no tienes los permisos necesarios para acceder a esa  propiedad, porque está “encerrada” dentro de las fronteras de miObj(). El uso de propiedades privadas es muy útil cuando quieres establecer valores que no quieres que sean modificados desde fuera del objeto. Por ejemplo, una velocidad que quieres que se mantenga constante cuando realizas una animación, o algún valor que no quieres que sea modificado. Considera el siguiente ejemplo:

function animador(){
    var velocidad =  .1;
}

var animcion = new animador();

En este caso hemos creado un constructor (animador()) que contiene una propiedad privada (velocidad). Esta propiedad la hemos puesto privada por que no queremos que la velocidad de animador pueda ser cambiada usando:

animacion.velocidad = .5;

ya que probablemente eso causaría resultados inesperados.

Pero entonces si no se puede acceder a la propiedad, para que nos sirve? Bueno, en realidad para nada, por lo  que es necesario encontrar una forma de poder acceder a la propiedad. Para eso están los método privilegiados.

Como su nombre lo indica, estos métodos tiene privilegios especiales. Piensa en ellos como si tuvieran su propia puerta para entrar y salid del contexto de su contenedor, en este caso miOBj();

Volvamos a nuestro ejemplo el cual hasta ahora va así:

function miObj(){
    var nombre =  'Nombre Privado';//propiedad privada
    function privada(){//Método privado
       alert('función privada');
    }//fin del método privado
}

var obj = new miObj();

Hagamos uno cambios en miObj():

function miObj(){
var nombre =  ‘Nombre Privado’;//propiedad privada
function privada(){//Método privado
alert(’función privada’);
}//fin del método privado
//agregamos método privilegiado
this.obtenerNombrePrivado = function(){
return nombre
}
}

El método obtenerNombrePrivado() es privilegiado, lo cual quiere decir que puede acceder a los métodos y propiedades privados declarados dentro de miObjt(). Esto tiene que ver con lo que se conoce como scope. Trataré de explicarlo:

Al ser declarada dentro de miObj(), otenerNombrePrivado() tiene acceso a las variables locales de miObj(), en nuestro caso solo tenemos una variable local (nombre). Esto por que al ejecutarse obtenerNombrePrivado() se ejecuta dentro del contexto y las fronteras de miObj() en donde nombre si existe.

Ahora podemos acceder a nuestra propiedad privada (nombre) sin ningún problema, pero sigue siendo imposible cambiarla:

function miObj(){
    var nombre =  'Nombre Privado';//propiedad privada
    function privada(){//Método privado
       alert('función privada');
    }//fin del método privado
    //agregamos método privilegiado
    this.obtenerNombrePrivado = function(){
       return nombre
    }
}
var obj = newObj();
alert(obj.obtenerNombrePrivado());//regresa Nombre Privado

Cabe aclarar que los métodos privilegiados siguen siendo métodos públicos, razón por la cual se pueden acceder desde fuera del objeto.

Métodos Públicos

Los métodos públicos están disponibles desde fuera del objeto. Es decir que son accesibles. Su uso es prácticamente para poder brindar formas de manipular el objeto o de acceder a sus funciones y ejecutar sus comandos. He visto a muchos que hacen lo siguiente para declarar método públicos:

function otroObj(){
    this.publico1 = function(){
       //código de publico1
    }
    this.publico2 = function(){
       //código de publico2
    }
    this.publico3 = function(){
       //código de publico3
    }
    this.publico4 = function(){
       //código de publico4
    }
}

Esto, aun que parezca correcto, es una forma ineficaz de hacerlo. Tener en cuenta que estos no son métodos privilegiados, es decir que no tiene que acceder a ninguna propiedad privada del objeto.

La razón por la que ésta forma de hacer las cosas no es la mejor es por que con cada copia que hagamos de nuestro objeto, estamos “clonando” todas esa funciones y podemos llegar a sobre cargar la memoria. Una de las grandes bondades de Js, es que es un lenguaje basado en prototipos.

Que es un prototipo?
Un prototipo es la forma en que Js nos brinda la oportunidad de extender un objeto. Es decir, a través de un prototipo podemos agregar funcionalidad a un objeto que de otro modo sería poco posible. Al inicio, la palabra prototipo puede sonar un poco intimidatoria. Sin embargo, no hay nada del otro mundo envuelto en esta palabra.

Creando métodos públicos usando prototipos
Para crear un método público de una forma más eficaz, es necesario usar el prototipo de nuestro objeto:

otroObj.prototype.publico1 = function(){
    //código de público 1
}

De esta manera evitamos clonar publico1 cada vez que creamos una nueva copia de otroObj ya que el prototipo no se clona. El prototipo más bien permanece al alcance de los objetos creados a partir del objeto base (otroObj) pero no está contenido dentro de ellos. Piensa en el prototipo como una caja de herramientas que es compartida por un numero determinado de carpinteros. Sin importar cuantos carpinteros agregues, siempre va a seguir habiendo una caja de herramientas y todos los carpinteros tendrán acceso a ella.

Una vez que actualices el prototipo de un objeto, todos los objetos creados a partir de dicho objeto tendrán acceso al prototipo actualizado y no al prototipo existente al momento de ser creados. Volviendo a nuestra analogía con los carpinteros, supongamos que al principio ponemos un carpinteros y una caja de herramientas. La caja de herramientas contiene un serrucho y un martillo. nuestro carpintero puede hacer uso de cualquiera de ellos. Después ponemos otro carpintero, quien a su vez puede hacer uso tanto del martillo como del serrucho. Después “actualizamos” la caja de herramientas y agregamos una lijadora. Ambos carpinteros siguen teniendo acceso a las tres herramientas aun que la caja solo tuviera dos herramientas cuando los carpinteros fueron agregados. Esa es mas o menos la forma en que trabajan los prototipos.

Una forma de hacer uso del prototipo de un objeto es mediante OLN.

otroObj.prototype = {
    publico1: function(){
       //...
    },
    publico2: function(){
      //...
    }
}

De esa manera podemos organizar los prototipos de una mejor manera y ahorramos algunos cuantos caracteres.

Métodos estáticos

Por último hablemos de uno de los tipos de métodos menos comunes, los métodos estáticos. Los métodos estáticos no son de ayuda en la mayoría de los casos. La razón de esto es por que no pueden ser usados más que por el objeto base.  Estos métodos son más bien de utilidad cuando estamos creando un objeto y no un constructor. Ejemplo:

var obj = new Object();

obj.método1 = fucntion(){...}

pero también se pueden usar cuando se están creando constructores:

function miObj(){
    var nombre =  'Nombre Privado';//propiedad privada
    function privada(){//Método privado
       alert('función privada');
    }//fin del método privado
    //agregamos método privilegiado
    this.obtenerNombrePrivado = function(){
       return nombre
    }
}
miObj.estatico = function(){
 alert('estatico');
}
var obj = newObj();

miObj.estatico();// da una alerta: estatico

obj.estatico();// Causa erro: obj.estatico() is not a function

A diferencia del ejemplo que vimos anteriormente en el que con cada copia del objeto clonabamos todos sus métodos públicos, los métodos estáticos no se copian y pertenecen solo al objeto base. Por lo que en nuestro ejemplo, obj.estatico() nos tira un error ya que no hay ninguna función que se llame estatico() relacionada con obj. Por el contrario, miObj.estatico() funciona perfectamente.

Esto nos puede ser útil en algunas ocasiones, especialmente cuando queremos extender un objeto sin afectar a todos los demás que hayan sido creados a partir del mismo objeto.

Hay más cosas que decir en cuanto a los Métodos de un objeto y todavía se nos a quedado en el teclado conceptos como herencia en Js, pero por ahora me despido esperando que haya sido una buena lectura.

Pues hace ya un rato desde el último articulo. Hoy me he inspirado y he hecho algunas pruebas de funciones en Javascript. Básicamente de diferentes forma de crear funciones, he aquí mis resultados no tan científicos y no tan estudiados ^-^.

Formas de crear funciones:

Hay diferentes formas de crear funciones, y dependiendo de lo que quieras hacer quizá quieras usar una o otra. Aun que generalmente no importa como declares tu función, nada mal hace el saber.

Lo más conocido:

La forma más sencilla y conocida de declarar funciones es la siguiente:

function alertar(){
     alert('ups!');
}

De esta manera hemos creado una función, y para llamarla solo necesitamos hacer referencia a ella:

alertar();

Así que, que hay de especial con esta forma de declarar funciones? Probablemente no mucho, excepto claro que te deja llamar a la función aún antes de que esta sea declarada:

alertar();
function alertar(){
   alert('ups!');
}

Pero probablemente eso ya lo sabias. Lo que es más, probablemente pensabas que es la forma en que todas las funciones reaccionan. Sin embargo no es así.

Otro metodo:

La siguiente es otra forma también muy conocida de crear funciones, pero que se comporta de forma un poco diferente a la forma que hemos visto anteriormente.

Se puede asignar una función a una variable:

var alertar = function(){
   alert('ups!');
}

Solo que a diferencia de la forma que hemos visto anteriormente, esta no te deja llamar funciones que no hayan sido declaradas previamente. Es decir que lo siguiente:

alertar();
var alertar = fucntion(){
   alert('ups!');
}

nos tira un error. La razón de esto tienes que ver con la declaración de las variables, pero en este post no voy a entrar en detalles con respecto a ese asunto. Así que si esta forma de declarar funciones tiene ese “problema” por que querríamos usarla? bueno, hay momentos en los que esa es la forma en que queremos declarar una función. Por ejemplo, cuando agregamos métodos a un objeto como veremos más adelante, o cuando queremos crear funciones auto ejecutables.

Funciones auto ejecutables

También se pueden crear funciones que se auto ejecutan al momento de ser leídas.

var alertar = function(){
   alert('ups!');
}();

Los paréntesis al final de la función le dicen al motor de javascript que la función debe ser ejecutada tan pronto sea leída. Esto probablemente no parezca útil al principio ya que la función deja de existir al momento en que se ejecuta, pero hay ocasiones en las que eso es lo que queremos hacer. Para comprobar esa temporalidad de la función puedes intentar lo siguiente:

var alertar = function(){
   alert('ups!');
}();
alertar();

Para poder crear funciones auto ejecutables es necesario usar la sintaxis:

var variable = function(){}

ya que si queremos usar la sintaxis del primer ejemplo (function funcionName(){}) obtenemos un error. Esta es una de las ocasiones en que queremos usar esta sintaxis que parece tener una desventaja al no dejarnos llamar a las funciones antes de que sean declaradas.

Pero ya en serio, por que queríamos hacer una función que se va a perder en el limbo tan pronto sea leída, lo que quiere decir que no la podemos volver a llamar en ningún otro momento? Una de las utilidades que yo le he encontrado es para solucionar problemas con el ámbito de las variables mediante closures, pero ese es otro tema. Lo único que voy a dejar es el siguiente ejemplo:

var alertar = function(){
   return function(){
      alert('ups!');
   }
}();
alertar();

De esta manera la función auto ejecutable puede ser llamada en cualquier momento, aun que al ejecutarse al inicio, cuando es leída, no ejecutará el alert ya que esta en la función que es regresada al ejecutarse la función exterior. Este es otro ejemplo que se ve sin sentido, pero sin embargo, es muy útil en ciertas ocasiones.

Funciones anónimas

También se pueden crear funciones anónimas de la siguiente manera:

(function(){
   alert('ups!');
});

Solo que como esta función es anónima no hay forma de llamarla después, por lo que la única forma de poder usarla es haciéndola auto ejecutable:

(function(){
   alert('ups!');
})();

Esta sintaxis es especialmente útil cuando queremos crear pseudo namespaces para evitar problemas de compatibilidad cuando usamos diferentes librerías. Aún que no es la única forma de lograr esto, si es una forma elegante y que a más de un novato lo hará verse como un “pro”.

El constructor

Por último veamos la forma menos recomendable, pero probablemente más poderosa, de crear funciones. Esta función es usando el operador new para crear un objeto Function. Esta es una  bestia peligrosa y recomiendo que sea evadida, pero de cualquier modo vamos a tocarla por el simple gusto de hablar de ella.

Para declarar una función de esta manera se hace de la siguiente forma:

var alertar = new Function('arg1','arg2','alert("ups1");');

en donde arg1 y arg2 son los argumentos que le queramos pasar a la función. Se pueden pasar tantos como se desee. El motor de Js sabe que el último set de comillas es el que contiene las instrucciones a ejecutar. Esta sintaxis es especialmente útil cuando se quieren crear funciones al vuelo o dar la oportunidad al usuario de crear sus propias funciones. Como dije, esto es una bestia y es mejor alejarse de ella a menos que sepas lo que estas haciendo y no tengas otra opción.

Ys estaré escribiendo un poco más sobre funciones ya que hay un par de cosas que se quedan pegadas al teclado por el momento. Espero sus comentarios.

Actualización: ejemplo en funcionamiento.

Hace ya algunos días @vochomaster me sugirió explicar como hacer un slideshow y me puso como ejemplo uno hecho en flash. A el no le gusta flash, por lo que me pidió que explicara como hacerlo pero en Javascript.

Hace un rato terminé el slide show, aun que la verdad no me convence ya que he usado OLN (Object Literal Notation) para construir el objeto que le da vida al slideshow. @jseros me sugiere que use constructores en lugar de OLN lo cual es una idea genial, y que ya había probado. De hecho el primer prototipo que hice del slideshow estaba basado en constructores y una mezcla entre métodos privados, privilegiados y públicos, pero no me gusto el rumbo que estaba tomando ni la complejidad que estava agarrando. Además, la razón por la que usar constructores es una buena idea, es por que eso nos agrega un punto en reusabilidad, pero al final eh decidido que rehusabilidad no es algo que quiero lograr en este caso debido al consumo de recursos que el efecto genera.

El efecto usa “fuerza bruta” para funcionar y si se abusa puede terminar colgando el navegador. Por supuesto que esto puede mejorarse e implementar mejores métodos para animación en lugar de un simple (y flojo) temporizador, pero este efecto, junto con el de alertas tipo twitter son simplemente propuestas aventadas al aire para servir como inspiración o modelo base de otros proyectos, o simplemente como ejercicios para intermedios en el uso de Js.

Bueno, sin más este es el código:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
 <title>..::**SlideShow**::..</title>
 <script type="text/javascript">
 var ss = {
 body : null,
 trueStop: false,
 intervalo : null,
 velocidad : 1,
 playing : true,
 init: function(){
 ss.body = document.getElementsByTagName('body')[0];
 if(ss.compatible()){
 ss.crearMarco();
 }else{
 alert('Tu navegador sucks!');
 }
 },
 compatible : function(){
 if(document.getElementById && document.getElementsByTagName && document.createElement && document.appendChild && document.removeChild){
 if(ss.body.setAttribute){
 return true;
 }else{
 return false;
 }
 }else{
 return false;
 }
 },
 crearMarco : function(){
 var marco = document.createElement('img');
 marco.setAttribute('src', 'FrameFotografico.gif');
 marco.style.position = 'absolute';
 marco.style.top = document.getElementById('ss').offsetTop + 'px';
 marco.style.left = document.getElementById('ss').offsetLeft + 'px';
 marco.onmouseover = ss.stopSS;
 marco.onmouseout = function(){if(!ss.trueStop){ss.playSS()} };
 ss.body.appendChild(marco);
 ss.crearControles();
 },
 crearControles : function(){
 var controles = document.createElement('div');
 var menos = document.createElement('img');
 var stop = document.createElement('img');
 var mas = document.createElement('img');
 menos.setAttribute('src', 'icon-menos-silver.gif');
 stop.setAttribute('src', 'icon-stop-silver.gif');
 mas.setAttribute('src', 'icon-mas-silver.gif');
 menos.onclick = ss.desacelera;
 stop.onclick = ss.playPause;
 mas.onclick = ss.acelera;

 controles.appendChild(menos);
 controles.appendChild(stop);
 controles.appendChild(mas);
 ss.body.appendChild(controles);

 ss.prepararSS();
 },
 playPause : function(){
 if(ss.playing){
 ss.stopSS();
 this.src = 'icon-play-silver.gif';
 ss.trueStop = true;
 }else{
 ss.playSS();
 this.src = 'icon-stop-silver.gif';
 ss.trueStop = false;
 }
 },
 desacelera : function(){
 if(ss.velocidad > 1){
 ss.velocidad --;
 }
 },
 acelera : function(){
 ss.velocidad++;
 },
 prepararSS : function(){
 document.getElementById('ss').style.overflow = 'hidden';
 document.getElementById('ss').style.position = 'relative';
 ss.lis = document.getElementById('ss').getElementsByTagName('li');
 for(i=0; ss.lis[i]; i++){
 ss.lis[i].style.position = 'absolute';
 ss.lis[i].style.left = i*400 + 'px';
 }
 ss.playSS();
 },
 playSS : function(){
 ss.intervalo = setInterval(function(){
 ss.lis[0].style.left = parseInt(ss.lis[0].style.left) - ss.velocidad +'px';
 for(i=1; ss.lis[i]; i++){
 ss.lis[i].style.left = i*400 + (parseInt(ss.lis[0].style.left)) + 'px';
 }
 if(parseInt(ss.lis[0].style.left) <= -405){
 lisActual = ss.lis[0];
 document.getElementById('ss').removeChild(ss.lis[0]);
 document.getElementById('ss').appendChild(lisActual);
 }
 }, 100);
 ss.playing = true;
 },
 stopSS : function(){
 clearInterval(ss.intervalo);
 ss.playing = false;
 }
 }

 window.onload = function(){
 ss.init();
 }

 </script>
 <style type="text/css">
 ul
 {
 height: 250px;
 width: 400px;
 overflow: scroll;
 padding: 0;
 }
 ul li{
 width: 400px;
 height: 250px;
 float: left;
 border:1px #000 solid;
 list-style-type: none;
 }
 </style>
</head>
<body>
 <ul id="ss">
 <li><br /><br />texto1</li>
 <li><br /><br />texto2</li>
 <li><br /><br />texto3</li>
 <li><br /><br />texto4</li>
 <li><br /><br />texto5</li>
 </ul>
</body>
</html>

Para usar el efecto solo basta con crear una lista desordenada (<ul>) y darle como id el valor “ss”. Después llamar ss.init() al cargar la página.

No me tomo el tiempo para explicar lo que el javascript hace por que creo que es totalmente lineal y entendible, pero si alguien tiene dudas solo pregunteme, o si considera que es necesaria una explicación de código, diganme.

Notar que si el navegador no soporta los métodos necesarios para que el slideshow funcione, el efecto se degradará mostrando un feo pero accesible recuadro con scrolls para ver el contenido de la lista desordenada.

Espero sus comentarios.

Pues ayer me aventé un mensaje en twitter preguntando sobre que les gustaría que hablara en mi Blog relacionado con Javascript. El único que respondió fue el usuario Calizman y me sugería que explicara como hacer el alerta que usa twitter cuando actualizas los “settings” en tu cuenta. El efecto cociste en un mensaje que sale de la parte superior de la ventana del navegador, se despliega por unos segundos y luego se vuelve a ocultar. Hoy me puse a desarrollar el efectillo y aquí está el resultado:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
 <title>mensaje estilo twitter</title>
 <script type="text/javascript">
 var mensaje = {
 init: function(mensaje){
 var elem = document.createElement('h1');
 elem.appendChild(document.createTextNode(mensaje));
 document.getElementsByTagName('body')[0].appendChild(elem);
 elem.setAttribute('style', 'position: absolute; margin: 0; background-color: #99F; width: 100%;top: -40px; text-align: center;');
 elem.setAttribute('id', 'msj');
 },
 activar: function(){
 intervalo = setInterval(function(){
 m = document.getElementById('msj');
 viejoTop = parseInt(m.style.top);
 if(viejoTop <= 0){
 nuevoTop = viejoTop+2;
 m.style.top = nuevoTop + 'px';
 }else{
 m.style.top = '0px';
 clearInterval(intervalo);
 setTimeout(function(){
 intervalo = setInterval(function(){
 m = document.getElementById('msj');
 viejoTop = parseInt(m.style.top);
 if(viejoTop >= -50){
 nuevoTop = viejoTop-2;
 m.style.top = nuevoTop + 'px';
 }else{
 m.style.top = '-50px';
 clearInterval(intervalo);
 }
 },10);
 }, 3000);
 }
 }, 10);
 },
 cambiarMensaje: function(mensaje){
 document.getElementById('msj').innerHTML = mensaje;
 }
 }

 window.onload = function(){
 mensaje.init('HolaMundo');
 }
 </script>
</head>
<body style="margin: 0;">
 <a href="#no" onclick="mensaje.activar();">Hola Mundo</a>
 <a href="#no" onclick="mensaje.cambiarMensaje('Mundo Hola'); mensaje.activar();">Mundo Hola</a>
</body>
</html>

Como pueden ver, he creado un miniobjeto que es el que hace todo el chistesito. Este miniobjeto cuenta con tres funciones:

init() que crea el elemento. init() recibe un único parámetro que es el texto con el que se inicializará el mensaje. En este caso  ‘Hola Mundo’. Yo estoy llamando init() al cargar la ventana, pero puede llamarse en cualquier momento, siempre y cuando 1) el documento esté totalmente cargado y 2) la llamada se haga antes de hacer cualquier llamada a uno de los otros dos métodos del objeto.

activar() es la función que se encarga de hace la animación. El código es realmentes sencillo utilizando animaciones de la vieja escuela. Pueden lograrse animaciones más sofisticadas utilizando métodos distintos, pero teniendo en cuenta que Calizman es relativamente nuevo en el mundo de Javascript, he decidido dejarlo lo más simple posible.

Por último, cambiarMensaje() se utiliza para asignar un mensage diferente al objeto y de esta forma poder usarlo para enviar distintos mensajes al usuario.

Este objeto no ha sido creado para motivos de distribución por lo que se tiene poco cuidado al momento de optimizar su comportamiento y su compativilidad. Sin embargo, unos cuantos toques por aquí y por alla y tienes un objeto totalmente transportable, aun que no realmente reusable en toda su extención.

Si tienen sugerencias sobre algo que les gustaría que explicara en un futuro, no duden enviarme un twitt a @ImBuzu o dejar la sugerencia a modo de cometario aquí en el blog.

El 7 de mayo me decidí ir un paso más en mi gusto por el software libre instalando uno de los sistemas operativos con los que había estado titubeando: Ubuntu. Ubuntu es totalmente gratuito, lo que lo pone de inmediato arriba, sino de las preferencias, por lo menos de las capacidades de compra de muchos usuarios. Con los OS de calidad, como lo es MacOSX de apple, siendo tan caros, muchos optan por piratear o por simplemente tomar un rumbo más saludable e irse para el lado creciente del software libre. Para mi no fue la escasés de papel verde lo que hizo probar Ubuntu, fue simplemente la aventura de rodar mis dedos sobre el mismo teclado, pero diferente SO. Actualmente mi mac sigue siendo mi computadora principal, pero prendo mi Dell más seguido que cuando la tenía con Windowx XP, del que por cierto no quedó ni rastro (odio las particiones, prefiero comprar otro equipo).

Bueno, sin más, mi experiencia en Ubuntu ha sido muy placentera. El SO es totalmente simple de usar, aun que al principio tuve problemas tratando de hacer funcionar mis dispositivos wireless para poder tener acceso a la red, pero al final decidí dejar de seguir los manuales que encontraba en internet al pie de la letra y usar la lógica logrando al fin configurar mi antena. Creo que muchos pueden sentirse intimidados por que cuando buscas en internet como hacer esto o aquello, siempre encuentras cosas como abre Terminal e ingresa lo siguiente, seguido por una linea de comando. Sin embargo, el SO tiene una interfaz gráfica a través de la cual se pueden hacer muchas de esas cosas de manera simple y cuando no es así, escribir comandos en el terminal realmente no es nada de que asustarse.

Lo primero que hice después de instalar el SO fue eliminar todo el software que no me sirve, programas que se instalan por defecto y que no necesito. No me gusta meterle basura a mis computadoras, no instalo mouses, reproductores de música o video, salva pantallas o efectos como el del desktop 3D. Son cool, pero simplemente innecesarios y aburridos a la larga. Así que me quedo solo con lo escencial. Actualmente me encuentro usando solamente bluefish. Decidí que para poner a prueba Ubuntu, desarrollaría un proyecto en él, y es lo que estoy haciendo. También instalé inkscape y pienso provarlo y ver si puedo ir haciendo una tansición desde Illustrator a inkscape, pero lo veo dificil.

Lo que me gusta de Ubuntu es que es veloz y minimalista. No tiene ese windows like apariencia que pensé que tendría. Es má bien muy parecido al OSX de apple. Tiene diferentes areas de trabajo para organizar tus ventanas y, pues, tus areas de trabajo. Por ejemplo, puedes poner todas tus ventanas donde tienes tu layout para un sitio web en un area de trabajo, y en otra todas tus ventanas en las que estás trabajando el código, de esa manera te evitas tener tanto en un solo lugar.

Hasta ahora he sentido el sistema operativo bastante estable y no desespera como lo hacía el XP. Me agrada el hecho de que los desarrolladores y los diseñadores pongan atención al detalle en la parte grafica e interactiva del sistema.

Por ahora uso el Ubuntu 9 y me ha dejado totalmente convencido que no tiene nada que envidiarle al MacOSX. Además, teniendo en cuenta el avance que ha tenido el software libre frente al propietario, no me queda duda que pronto el software libre tendrá mucho mejor calidad y muchas mejores carácteristicas que el software de paga. Una de las razones de esto, es que al software libre no lo maneja esa insana ambición monetaria, sino el deséo de brindar por y para la comunidad lo que la comunidad necesita.

Sin más, si me preguntas si te recomiendo que te cambies a de windows a Ubuntu, mi respuesta es SI!.

últimamente en el twitter todo lo que veo tiene relación con el llamado #escandalogt, más concrétamente con el caso de jeanfer. Para quienes no sepan de dicho caso, la cosa es simple; Jean Ramses Anleu Fernández fue detenido tras publicar en twitter una nota relacionada con lo hechos acontecidos en Guatemala los días pasados. La nota, según Prensa libre (1) dice, “Primera acción real “sacar el pisto de Banrural” Quebrar al banco de los corruptos”.

Lo que me llama la atención en el caso, no es la nota en si, sino la reacción de las autoridades en Guatemala. Como dice el título del post, estoy poco informado sobre el caso, por lo que más que hablar del caso de jeanfer, me limitaré a dar mis pensamientos generales sobre un sistema que oprime a aquellos que levantan la voz.

Como dice el último post que he publicado a través de twitter, “Y la libertad de expresión que se valla al carajo. Eres libre, siempre y cuando tus twitts no afecten mis intereses económicos enfermizos.”  Es lamentable ver como en pleno siglo XXI la represión y el control abusivo de la “libertad” de expresión siguen siendo un problema en muchos de los países latinos. Claro, que puedes decir e incluso acusar a Jean Ramses de sabotaje en contra de Banrural, alegando que el único motivo de su twitt, como se lee explicito, era “quebrar al banco de los corruptos”. Entonces, entran los intereses económicos y políticos de aquellos quienes están siendo “atacados”, y como estos son los que manejan la plata, también son los que manejan el poder; otro caso más de “gigantes en tronos [pisando] nomos”, pero que se puede esperar de un sistema que basa su supervivencia en la corrupción, la ambición y el deseo de poder.

La reacción por supuesto que no se hizo esperar. Ahora, un grupo de guatemaltecos apoya a Jean Ramses y se unen a su causa. Lo que me llama la atención es la reacción que están tomando. Simplemente están siguiendo las reglas del sistema. En mi muy humilde opinión y probablemente carente de información, yo creo que más aya de comenzar un movimiento financiero para cubrir el costo de la libertad de Jean,  los “chapines” deberían estar haciendo retwits del mensaje de Jean Ramses. Al gobierno de Guatemala no le convendría arrestar a tanta gente una vez que el movimiento tome fuerza. Claro, esto podría iniciar un conflicto aún más grande y afectar a más personas de las que ya han sido afectadas, pero es la única forma de demostrar al sistema que no es posible seguir abusando de los individuos que forman la sociedad a la que dichos sistema se supone debe servir.

Desgraciadamente vivimos en una sociedad victima de su propia ambición. A diario tenemos que soportar el abuso, la represión y los atropellos de un sistema que fomenta la inseguridad social y el abuso del poder a través de los métodos más deplorables y los hechos más descarados.

Ahora, me tomo nuevamente la libertad de citar directamente de Prensa libre.

La ley establece que comete delito de pánico financiero quien elabore, divulgue o reproduzca por cualquier medio o sistema de comunicación, información falsa o inexacta que menoscabe la confianza de los clientes, usuarios, depositantes o inversionistas de una institución sujeta a la vigilancia e inspección de la Superintendencia de Bancos.

Leyendo dichas lineas no me queda la menor duda de que las leyes han sido elaboradas por y para los ricos y poderosos. Entonces me pregunto, que habría sido de Rodrigo Rosenberg a causa de sus declaraciones acerca de Banrural si no hubiera sido asesinado? Estaría en la misma situación? y por que Jean es el único que ha sido detenido a pesar de no ser el único que ha publicado mensajes de ese tipo? Además, cual pánico financiero? No creo que las declaraciones hechas por Jean sean capaces de provocar pánico a la comunidad guatemalteca. Por el contrario, creo que son capaces de crear pánico en los banqueros, y ese es precisamente el problema. Jean: te has metido con los gigantes y en esa tierra todo se maneja a su antojo.

Que le queda al pueblo de Guatemala? Sin duda le queda la plena certidumbre de que la ley favorece a los mejor parados, que el sistema va a exprimir a aquellos a quienes oprime hasta dejarlos en cascara, que viven en una sociedad que es victima del abuso de poder de aquellos que controlan el sistema, y sobre todo, le queda la amarga sensación de tener que cuidar lo que dicen en una red social en menos de 140 caracteres por miedo a ser sorprendidos, aprendidos y  totalmente abusados, privados de sus derechos y puestos ante un tribunal para ser juzgados por el simple hecho de ejercer su derecho de expresión.

1.- http://www.prensalibre.com/pl/2009/mayo/14/314279.html

Frameworks o Frameworst

April 20, 2009

“Y a mi que rayos me importa si Google está usando jQuery? Yo soy un programador javascript de la vieja escuela…”

Nunca he tenido la oportunidad de explicar el por que ese rechazo hacia los frameworks. Algunas veces me siento a pensar y tratar de convencerme a mi mismo que si tanta gente, incluyendo a google, dell, bank of America, las grandes ligas, digg, nbc, cbs, netflix, technorati, mozilla, wordpress, Drupal entro otros según el sitio oficial de jQuery, usa dicho framework tiene que se ser por que tiene algo bueno. La verdad es que nunca he encontrado una buena razón para agregar una capa de abstracción a un lenguaje de programación.

El beneficio de los frameworks, según aquellos que defienden su uso, reside en el hecho de que se logra compatibilidad por lo menos en los navegadores más populares, aparte de lograr hacer más con menos. Yo me pregunto, no saben acaso que se puede lograr compatibilidad entre los navegadores con simple Javascript? y eso de lograr más con menos; que no se dan cuenta que están cargando una librería que por si sola ya pesa más de lo necesario para lograr todas aquellas  cosas tan “cool” para las que se usan principalmente los frameworks? Realmente se me hace difícil entender esas cosas.

Pero esa no es la razón por la que odio los frameworks. La verdadera razón por la que odio los frameworks es por que han lanzado un sin numero de pseudo programadores al mundo que en realidad no saben ni lo que hacen, y lo peor de todo, cuando preguntan no saben ni de lo que hablan. Seguido me encuentro con gente que llega desesperada a pedir ayuda por que su menú desplegable, que usa mootools, deja de funcionar cuando “instalan” un slideshow que usa jQuery. Entonces yo me digo, “Date un tiro y hazles saber que has muerto”. La vida es simple, Javascript es más simple aún. Por que rayos ese afán de hacerlo más complicado?

El otro día me encontré con un script para greasemonkey  en el que se había cargado todo el jQuery. Me digo, hasta que punto ha llegado la dependencia en ese framework? especialmente cuando greasemonkey es uno de los mejores clientes para escribir Javascript.  Cuestiones como esa simplemente me hacen sentir desconcertado.

Lo pero del caso es que ahora en muchos lugares de trabajo te piden experiencia en Mootool y jQuery y no mencionan nada de Javascript. Eso, y el hecho de que muchos de esos “programadores” están cobrando por proveer soluciones que han adquirido de un verdadero programador de Javascript, me hace sentir que este mundo es totalmente injusto. Pero ya en serio, que alguien me diga por que los Frameworks se han hecho tan populares. Bueno, si no mal recuerdo he odio de verdaderos héroes de la programación las siguiente razones:

La gente es mediocre y prefieren usar un framework a tener que asegurarse ellos mismos de que su código funciona bien.
Las compañías prefieren pagar (menos) a un pseudo programador que a un verdadero programador
Las compañías aprecian mucho el tiempo que se ahorra al escribir código usando un framework, sin tomar en cuenta el tiempo que perderán después tratando de actualizar y optimizar su código.
La gente prefiere aprender algo fácil aun que después tengan que venir a molestar a otros cuando no saben que es lo que un getElementById() hace en el código bien escrito de otra persona.

Creo que en realidad nunca alcanzaré a entender la mente de alguien que prefiere cargar una librería y un objeto aparte de tener que insertar código en linea para lograr un simple rollover a simplemente desarrollar el suyo propio.

Estoy seguro que me he olvidado de escribir las verdaderas razones de mi “no a los frameworks” y que no he escrito lo que en realidad quería decir. Cuando me acuerde probablemente lo haga, pero por ahora, el simple hecho de pensar que hay sitios, como nettuts, tan orientados a los frameworks y que los publican como lo mejor del mundo de la programación me hace sentir totalmente desganado.

Hace un año todavía me importaban cositas como el CSS Naked Day y la 100% validación el w3C. Hace un año hice un post sobre el CSS Naded Day, una iniciativa que al parecer es de Dustin Diaz. Ayer, fue ese naked day y yo no vi realmente que muchos de los sitios que visito, a excepción de FDW y MDW, hayan aplicado el jueguito al que hasta hoy no le veo utilidad para el usuario común, y es esa precisamente la razón por la que no me uno a el.

Al usuario común no le interesa en absoluto saber el efecto que tienen las hojas de estilo sobre nuestro sitio web. No le importa si las usas o sigues con las viejas etiquetas de formato y las tablas. Al usuario común lo único que le interesa es ver el sitio de tal forma que no le parezca un dolor de cabeza. Entonces, por que rayos molestar al usuario mostrando un sitio “desnudo”. Para mi, y desde mi muy particular punto de vista, no tiene sentido.

Como dije, hace un año creia en esas cosas. Hace un año era un poco más iluso que ahora, y por lo tanto me enfocaba en una web orientada a desarrolladores. Pero abramos los ojos y démonos cuenta que la web está plagada de usuarios comunes a los que estas cosas no les interesan. Aún creo en los estándares, y en la correcta creación de un sitio web, pero que mi sitio valide ante los ojos de la w3c ya no me quita el sueño, hoy me importa más que valide ante los ojos del usuario. Hoy estoy más enfocado en crear sitios que vallan dirigidos hacia el usuario y no hacia exaltar mi ego por los cielos al poder decir que mis sitios validan y poder poner una estampita de la w3c. Sin embargo, mis sitios muestran una barrita verde que indica que son 100% estandar cuando los corres por el validador de la w3c; producto de un cuidadoso desarrollo.

Dentro de un año, quizá mi visión del mundo haya cambiado, y eso es bueno, eso indica que he seguido madurando y experimentando más el mundo; observándolo y apreciando las diferentes corrientes, causas y efectos que hoy no alcanzo a ver. Dentro de un año quizá, pero por el momento no me uno a juegitos como el CSS Naked Day, o el NO IE day (una actitud aún más reprobable que el CSS Naked Day). Por ahora, para mi, el usuario es quien lleva las de perder en este tipo de cositas (lease tonterias) y por mucho que use IE, que lo siga usando, amando, adorando, idolatrando o lo que sea, no merece que le aventemos un pastel en la cara para reclamarle que por su culpa no podemos lograr un rollover con CSS en un lugar en el que para empezar un rollover no tiene sentido.

Leyendo algunos comentarios en la web me despertó el deseo por escribir este articulo. Quizá te parezca un poco exagerado afirmar que la carrera por el #1 en google es insana. Sin embargo, desde mi muy particular punto de vista sí lo es. He aquí el porque.

En nuestra carrera por llegar al #1 en Google nos hemos orientado mucho, demasiado diría yo, hacia el SEO y lo hemos adoptado como una de las principales herramientas para popularizar nuestros sitios web. Sin embargo, SEO debe ser solo un complemento en nuestros sitios web.

No es novedad que como lector apasionado me encanta defender el contenido en la web por sobre todas las cosa. Cuando me pongo en linea estoy en busca de contenido, pero no me conformo con cualquier tipo de contenido. A mi me gusta el contenido de calidad. Tristemente, entre más se popularizan ciertas técnicas eficaces del posicionamiento web, también se popularizan los resultados #1 basura en google, resultados con contenidos pobremente redactados que están en el primer puesto de google solo gracias a un buen trabajo de SEO, pero que al leerlos no aportan nada que sea realmente satisfactorio.

Puedo deducir que una de las principales causas de ese decaimiento en la calidad del contenido que se encuentra en la web es el gran esfuerzo empleado en encontrar, aplicar y mejorar las técnicas SEO para lograr una mejor posición en google el cual ha reducido el tiempo que se empleaba para revisar, corregir y editar el contenido que estamos publicando. Tristemente esta carrera por la primera posición esta dejando como resultado contenidos cada vez más pobres, pero que gracias al buen trabajo de SEO logran colocarse en las primeras posiciones en google y otros buscadores. Desgraciadamente el hecho de que un elemento esté en primera posición no nos garantiza calidad. Para mi es preferible crear contenido que sea de ayuda a mis 10 visitantes (tengo más no se crean que solo 10) que una basura que solo le quite el tiempo a 10,000 googlers quienes llegaron solo por que mi sitio es el numero 1 en google, al final de cuentas si mi contenido es de calidad tengo visitantes que vuelven y me recomiendan. Son ellos mismos quienes me hacen escalar en google y el SEO ¿que se valla al cuerno? En realidad no, pero un buen contenido, con redacción de calidad y excelentes títulos es tu primer arma en esta guerra por el número 1.

Que hacer? Muchos pensarán que empezar a evangelizar a otros es la solución. En realidad no lo es, si dar sermones fuera una solución, el mundo sería un lugar perfecto. Simplemente escribe con calidad y cuida tu contenido.

[Gracias a Panino5001 por la correción otrográfica]