Document Object Model, o DOM, o Modelo en Objetos para representar Documentos es una modelo en que los scripts pueden acceder y modificar dinámicamente el contenido, la estructura o los estilos de documentos HTML. A través del manejo del DOM se permiten las actualizaciones en tiempo real de contenidos, envío de formularios asincrónicamente, etc. O sea, es la base del funcionamiento de los rollovers, del onclick, de AJAX.. Se utilizó por primera vez en Netscape Navigator 2.0.
El entendimiento del DOM es la base para entender la programación web.
Aunque el desarrollo del DOM es responsabilidad de la W3C, como todo lo que sale de ahí, ha habido discrepancias en su implementación. Aunque todos los navegadores usan Javascript como lenguaje de programación, los objetos no se comportan de la misma manera, lo que se traducía en diferentes maneras en que había que programar para IE, Netscape, Firefox… (ya no nos bastaba tener que hacer que los estilos funcionaran parecidos entre navegadores… ¡ahora con el DOM tambiém!). Eso lo puedes notar en sitios donde el onclick sólo funciona en IE6 y no en Safari, por ejemplo. Gran ayuda son los frameworks de Javascript, que ponen todos sus esfuerzos en lograr que sus fantásticas funcionalidades sean crossbrowser.
Objetos en un sitio web tienen propiedades, así como en la vida real una piedra tiene peso, color y textura:
Para el siguiente modelo:
<div id="texto">lorem Ipsum</div>
El objeto puede ser <div> o su identificador, el id="texto". La propiedad puede ser el color del texto, o su tamaño. Juguemos con su color. El valor, será el valor del color en hexacromía:
Objeto.propiedad = valor
Texto.color = #f00;
$("#texto").css(color: "#f00");
&("#texto").setStyle(‘color’, ‘#f00′);
Un evento se define cuando alguna situación cambia en el comportamiento del sitio web: cuando se presiona alguna tecla, el click del mouse, la posición del cursor; o sea, la interacción del usuario con el sitio web. Estos eventos también son objetos (que responden a eventos) y se pueden manejar mediante Javascript.
Para el mismo modelo anterior, mediante un MouseOver:
$("#texto").mouseover(function() {
alert("Mouse sobre el div#texto");
});
$("#texto").addEvent(‘mouseover’, function() {
alert("Mouse sobre el div#texto");
});
Siento que me faltó un importante tópico que tratar en este breve paso por el DOM. Se trata del evento que gatilla las acciones de la página, más precisamente el anticuado onLoad, v/s el moderno onDomReady.
El problema de onLoad es que espera que toooda la página, y toooooodos sus elementos estén cargados para ejecutarse. Su nombre lo dice, cuandoCargue (onLoad). Imagínate: primero cargas el HTML y sus elementos, luego los scripts, las imágenes… puede demorarse un montón. Cuando recién termina todo eso ejecuta algún evento determinado por onLoad.
Aquí es cuando viene al rescate onDomReady. Este evento creado por los frameworks (Mootools y YUI lo tienen implementado) ejecuta sus comandos justo cuando los elementos HTML de la página están renderizados, o sea, justo lo necesario para comenzar a manipularlos como objetos. Genial, mientras aún siguen cargando el resto de las imágenes, swf’s, etc.
<a href="" id="comienza">Rescata la info</a>
<div id="traelo_aqui">
<p>Trae aquí la info</p>
</div>
Básicamente es un botón que al ser presionado cargará la info desde una página determinada por nosotros mediante JS hasta el div que definimos. Ahora, mediante Mootools crearemos el evento:
$(‘boton’).addEvent(‘click’, function(e) {
e = new Event(e).stop();
var url = "http://www.csslab.cl/ejemplos/ajax_mootools/lipsum.html";
$(‘traelo_aqui’).empty().addClass(‘cargando’);
new Ajax(url, {
method: ‘get’,
update: $(‘traelo_aqui’),
onComplete: function() {
$(‘traelo_aqui’).removeClass(‘cargando’)
}
}).request();
});
Al elemento con id="boton" (o sea, <a id="boton">) le agregamos un evento de ‘click’ (addEvent). De ahí, comenzamos una función que a través del método ‘get’, trae lo que esté en la variable url (var url) y refresca lo que esté adentro del id="traelo_aqui" (o sea <div id="traelo_aqui">). Además, agregaremos una class="cargando" al contenedor mientras se está rescatando la información por si se demora mucho (addClass(‘cargando’);) y cuando termine todo, sacaremos esa class (removeClass). Básicamente esa es la explicación.
]]>Precisamente me gustaría comentar sobre las librerías javascript con que he estado jugando. Pasé por las más importantes, y perdí unas buenas horas tratando de que funcionen como quiero. La que más me impresionó fue Mootools, nunca había trabajado con él y es bastante interesante (no dejen de visitar su sección de downloads, lo que demuestra su potencial). Luego, pasé a Jquery con el que había tenido unos roces antes, y sabía que tenía algunos efectos que necesitaba (pero por alguna razón que desconozco hacía que se cayera Safari). Conocí a Interface, una librería sólo de efectos similar a Script.aculo.us para Prototype. Precisamente con ésta me quedé al final, la que más de trabajado y la que más me gusta, por la fácil implementación y configuración de efectos que posee. Los invito a probarr un poco de todas y hacerse de su propia opinión.
]]>
Bien, para el ejemplo específico del efecto del menú de este sitio, se utilizó Effect.toggle(), el que permite con un sólo onclick() (en un <a>, <span>, etc) mostrar y esconder el div con el id que necesitamos. En el fondo se trata de eso, tenemos un div, le damos un id específico y único, el que a través del onclick le decimos que muestre ese div si está escondido, o que lo esconda si está visible. Para que el div esté escondido desde un inicio, le damos un display: none; en el mismo HTML o en una hoja de estilos externa, como prefieras. Como la mayoría de las veces, muestro un ejemplo visual y código utilizado explicado. Primero, el código HTML:
<a onclick="new Effect.toggle($(‘cajatexto’),’blind’)">Mostrar y Esconder Texto</a>
<div id="cajatexto" style="display: none;">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris eget ante. Integer sollicitudin urna eget est. Phasellus pharetra rutrum erat. Phasellus non augue et sapien nonummy……………..</p>
</div>
Fijarse que al onclick se le agregó el id cajatexto, al igual que el div que queremos que se vea el efecto aplicado.
Debemos agregar 2 elementos JavaScript a la página que queremos que ocurra el efecto: prototype.js y scriptaculous.js (en ese mismo orden).
<script src="include/prototype.js" type="text/javascript"></script>
<script src="include/scriptaculous.js" type="text/javascript"></script>
Como dije, script.aculo.us ofrece muchas más funcionalidades, además de efectos. Chequeen su sitio para más información.
]]>En el OBJECT debemos aplicar un parámetro y un valor para la película Flash: wmode="opaque". Es conocida por muchos el parámetro wmode="transparent", pues ésta nos permite que las zonas que no tienen fondo en la película Flash se transparente, dejando ver el fondo del HTML que lo contiene (sea éste color plano, o una gradiente, o una foto, etc), similar a una película PNG Transparente (precisamente trabajando con el canal de transparencia, el canal alpha). Con opaque, la película Flash se esconderá detrás de cualquier elemento, sea éste HTML o controlado por Javascript. Por lo tanto, el HTML que llama el SWF sería:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="300" height="200">
<param name="movie" value="csslab.swf" />
<param name="quality" value="high" />
<param name="wmode" value="opaque" />
<embed src="csslab.swf" width="300" height="200" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="opaque"></embed>
</object>
Como mencioné, se creará un DIV que contiene nuestra película Flash. Este DIV contendrá, en este caso, un z-index=-999; Para quienes no conocen, la propiedad z-index determina el orden, o relevancia en que un elemento designado tendrá sobre otro, por ejemplo, cuando una imagen pasa por debajo de un texto (el <img> tiene un z-index inferior al <p> del texto), o si queremos que la imagen pase por encima del texto (el z-index del <img> será superior al z-index del <p> del texto). ¿Se entiende? Ojalá que sí, aquí pueden ver un ejemplo gráfico de ello. bueno, lo que haremos entonces es reforzar el wmode="opaque" que debería pasar ya detrás del Lightbox, con el z-index (exagerado) de -999, y el CSS del Lightbox ya viene con un z-index de 100; El CSS del DIV contenedor del SWF sería:
#flash {
z-index: -999;
}