Un nuevo acercamiento al DOM

UPDATE: Cuando publiqué esto inicialmente olvidé mencionar de donde ha venido la idea. Creo que es importante mencionarlo. La idea de este nuevo acercamiento al DOM viene de un post de john acosta (a.k.a. jSeros), en el cual habla sobre acceso a elementos mediante literales de cadena. El post parece no estar disponible, o por lo menos no lo encontré en la página de monoku.

Bueno, esto es solo una probadita de lo que estoy cocinando en mis tiempos libres. Que les parecería poder manipular el DOM de esta forma:

"ul".create([
 'a bird'
 , 'two birds'
 , 'three birds'
],{
 style: 'color: #00F'
}).into('exaple'.id());

Se mira bien no? Con la API normal del DOM ofrecida por javascript necesitaríamos hacer lo siguiente:

var ul = document.createElement("ul");
var li1 = document.createElement("li");
var li2 = document.createElement("li");
var li3 = document.createElement("li");
var example = document.getElementById('example');
li1.appendChild(document.createTextNode("a bird");
li2.appendChild(document.createTextNode("two birds");
li3.appendChild(document.createTextNode("three birds");
ul.appendChild(li1);
ul.appendChild(li2);
ul.appendChild(li3);
ul.style.color = '#00F';
example.appendChild('ul');

Hasta ahora nada está escrito en piedra y hay algunas cosas que podrian cambiar en la sintaxis, pero ya tengo un buen número de lineas de código que hacen tediosos procesos mucho más sencillos. Mira abajo por ejemplos de code que ya tengo funcionando en local.

Por que una nueva librería?

Es cierto que la web no necesita mas librerías javascript. Por que no simplemente usar jQuery, Mootols, YUI, o cualquier otra de las librerías que hay por ahí? La respuesta es muy sencilla: Me gusta controlar y entender lo que hago. Si bien esta librería, a la que  temporalmente llamo SimpleDom, será puesta a disposición pública, no se está desarrollando con el objetivo de competir en el mercado de las librerías. Es más bien un proyecto personal que he decidido poner a disposición de cualquiera que quiera usarla. En un momento pensé en desarrollar la primer librería en español de modo que pudieras hacer cosas como:

"p".crear(["Este es mi texto"]).insertarEn("miElemento".encontrar());

Sin embargo, ya llevaba un buen avance y no quice ir y traducir todo de nuevo. Devo confesar que aun me gusta la idea.

Algo que quiero enfatizar es el uso de funciones especificas. Si sigues el blog regularmente ya sabrás que tengo la idea de que una función debería hacer una cosa y hacerla bien. En un momento quice implementar algo como: “a[href=’someURL’]”.find();

Lo cual funcionaría como $() en jQuery. Quizá incluso incluiría el mismo motor de selectores CSS que jQuery, pero pensándolo bien prefiero usar funciones especificas como:

id()
className()
attr()

Las cuales busquen por id, nombre de clase o atributo. Aquí estamos dejando fuera muchos selectores CSS como selector de hijos, o los selectores :first, :hover, etc. Por ahora no tengo planes de implementar dichos selectores, aun que no descarto la posibilidad de implementarlos en un futuro.

Por ahorita todo está en proceso de desarrollo con apenas unas 400 lineas de código, pero ya podemos hacer cosas como:

window.onload = function(){
"p#myId".create(['Hola Mundo']).into('prueva'.find());
'ul'.create([
 'hola',
 'mundo',
 'p'.create(['hola mundo again'])
]).into('prueva'.find());
'ol'.create([
 'hola',
 'mundo',
 'p'.create(['hola mundo again'])
]).into('prueva'.find());

//dl example
'dl'.create([
 'Definition Term => Definition description',
 'Definition term 2 => Definition description 2'
 ]).into('prueva'.find());

//dl example 2
'dl'.create([
 'Definition Term => Definition description',
 ['def term', 'def desc'],
 ['def term2', 'p'.create(['bobobobo'])]
 ]).into('prueva'.find());
}

y tenemos algunos efectos como pulsate(), fadeIn() y fadeOut(), y algunas utilildades como: setAttributes(), attr(), css(), getStyle(), write() y writeIn().

La librería se basa en un objeto DOMElem el cual es extendido para crear un objeto diferente por cada uno de los diferentes elementos existentes en XHTML. Para ello usamos un diccionario interno con todos los elementos. Les dejo el diccionario para que revisen si hay alguno faltante:

var dictionary = {
 a : 'a'
 , abbr : 'abbr'
 , acronym : 'acronym'
 , address : 'address'
 , area : 'area'
 , b : 'b'
 , base : 'base'
 , bdo : 'bdo'
 , big : 'big'
 , blockquote : 'blockquote'
 , body : 'body'
 , br : 'br'
 , button : 'button'
 , caption : 'caption'
 , cite : 'cite'
 , code : 'code'
 , col : 'col'
 , colgroup : 'colgroup'
 , dd : 'dd'
 , del : 'del'
 , dfn : 'dfn'
 , div : 'div'
 , dl : 'dl'
 , dt : 'dt'
 , em :'em'
 , fieldset : 'fieldset'
 , form : 'form'
 , h1 : 'h1'
 , h2 : 'h2'
 , h3 : 'h3'
 , h4 : 'h4'
 , h5 : 'h5'
 , h6 : 'h6'
 , head : 'head'
 , hr : 'hr'
 , html : 'html'
 , i : 'i'
 , img : 'img'
 , input : 'input'
 , ins : 'ins'
 , kbd : 'kbd'
 , label : 'label'
 , legend : 'legend'
 , li : 'li'
 , link : 'link'
 , map : 'map'
 , meta : 'meta'
 , noscript : 'noscript'
 , object : 'object'
 , ol : 'ol'
 , optgroup : 'optgroup'
 , option : 'option'
 , p : 'p'
 , param : 'param'
 , pre : 'pre'
 , q : 'q'
 , rb : 'rb'
 , rbc : 'rbc'
 , rp : 'rp'
 , rt : 'rt'
 , rtc : 'rtc'
 , ruby : 'ruby'
 , samp : 'samp'
 , script : 'script'
 , select : 'select'
 , small : 'small'
 , span : 'span'
 , strong : 'strong'
 , style : 'style'
 , sub : 'sub'
 , sup : 'sup'
 , table : 'table'
 , tbody : 'tbody'
 , td : 'td'
 , textarea : 'textarea'
 , tfoot : 'tfoot'
 , th : 'th'
 , thead : 'thead'
 , title : 'title'
 , tr : 'tr'
 , tt : 'tt'
 , ul : 'ul'
 , bar : 'var' //definition with b so it doesn't conflict with the javascript var
}

Para que se den una idea del petencial de esta libreria les dejo este ejemplo del uso de pulsate():

'p#parrafo'.create(['soy parrafo'], {style : 'color: red;'}).into('prueva'.find()).pulsate(5, function(original){original.write('Finish!')}, {
 'n!' : function(o, step){
 if(step!=5){
 //alert('c');
 }
 }
 , 'n' : function(o, step){
 o.write(step);
 }
 , 1 : function(o){
 o.write('First');
 }
 , 2 : function(original){
 original.write('Second');
 }
 , 3 : function(o){
 o.write('third');
 }
 , 5 : function(o){
 o.write('I\'m unique');
 }
 }).css('color:#000');

En este ejemplo vemos pulsate en su maxima expresion. Pulsate simplemente desvanece y vuelve a mostrar un elemento de modo que podamos llamar la atención del usuario. En este caso vemos que pulsate toma 3 parametros.

El primer parametro es 5, este especifica el numero de pulsaciónes. Podemos incluso hacer que un elemento pulse indefinidamente.

El segundo parametro es una función la cual será llamada una vez se hayan completado todas las pulsaciones. Es lo que se conoce como un callback.

El tercer parametro, el más interesante, es un objeto que nos permite haceer una accion diferente en cada pulsación. El uso de este objeto lo voy a explicar mejor cuando escriba la documentación de la libreria, pero por ahora me gustaria comentar que podemos especificar la acción para cada pulsación por número y tambien podemos usar n y n! para lograr que una accion se ejecute en cada pulsación. Existe una diferenecia importante entre n y n!, pero eso lo dejo para otra ocación.

Bueno, espero que algunos se interesen en este proyecto y lo esperen. No tengo fecha de lanzamiento por que, como he dicho, lo estoy haciendo en mis tiempos libre, pero me gustaría ver algo aun que fuera beta para inicios de 2011.

5 thoughts on “Un nuevo acercamiento al DOM

  1. Coincido con que “Me gusta controlar y entender lo que hago”, pero en mi caso que aún soy noob en javascript, opté un día por jQuery para el tema de los efectos visuales… al fin que me quedó gustando por su simplicidad y hasta el día de hoy lo uso para mucho más.

    No entiendo bien la idea del diccionario, pero no encuentro elementos faltantes. ¿No conciderarás elementos del HTML5?

    Buena iniciativa de tu librería!

    • Sabia que alguien preguntaría sobre HTML5😉. Por el momento no lo he considerado por una razón, no conozco el lenguaje tan a fondo como para implementar un sistema como el que estoy haciendo. Con esto quiero decir que no sabría con exactitud como implementar por ejemplo los métodos para etiquetas de audio y video. Puede ser que no haya diferencia, puede ser que sea muy sencillo, pero mientras no conozca el lenguaje a fondo, no trataré de implementarlo. Lo único peor que un componente faltante es un componente mal implementado.

      En cuanto al diccionario, es muy simple, ese diccionario sirve principalmente a dos motivos:
      El primero es determinar que objetos vamos a crear y extender. Cada objeto en la librería tiene como base DOMElement, pero por ejemplo, el método create de un objeto UL es diferente al de la base DOMElement.
      El segundo objetivo del diccionario es permitir la creación de elementos válidos y nada más.
      La librería extiende el objeto string de Javascript, por lo que en teoría podrías hacer esto:
      “elementoNoValido”.create()
      Eso es precisamente lo que se pretende evitar mediante el diccionario.

      Esta librería terminará siendo de código abierto, por lo que si no te quedan claras las cosas, en cuanto sea liberada puedes ir y ver el code, aun que quizá necesites un poquito más de nivel en javascript para entenderlo.

      En el post iba a poner una parte del core de la librería, pero lo olvidé. Ya lo estaré compartiendo en otro post.

      Gracias por visitar el blog🙂

  2. A mi me gusta la idea. Extender un objeto nativo como String y usarlo para hacer algo interesante con las cadenas de texto es un patrón que siempre me ha gustado, e incluso alguna vez escribí un post donde hablaba al respecto.

    Un saludo y muy buena iniciativa😉

    • Olvidé comentar esto en el post, pero de hecho esta iniciativa se inspira en tu post en monoku sobre acelerar el acceso mediante literales de cadena en jQuery.

      Cuando libere el code a ver si tu y el gran amigo panino tuvieran tiempo de darle una leidita😉

Comments are closed.