<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-22501941</id><updated>2012-02-03T20:01:24.204-03:00</updated><category term='Mootools'/><category term='Ajax'/><title type='text'>Pinien</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-22501941.post-2969685555929894803</id><published>2012-02-03T20:01:00.001-03:00</published><updated>2012-02-03T20:01:24.224-03:00</updated><title type='text'>Lesson Plan - Lesson exmaple</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;iframe src='https://lrn.cc/SG' frameborder='0' height='640' width='520'/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-2969685555929894803?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/2969685555929894803/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=2969685555929894803' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/2969685555929894803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/2969685555929894803'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2012/02/lesson-plan-lesson-exmaple.html' title='Lesson Plan - Lesson exmaple'/><author><name>Damian Suarez</name><uri>http://www.blogger.com/profile/04393216503371957176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://lh5.google.com/image/rdsuarez/RcONjCjR_WI/AAAAAAAAADc/3ETM2H-CbQQ/croataverde80.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-7449003068396225234</id><published>2012-01-19T21:55:00.001-03:00</published><updated>2012-01-19T21:55:49.066-03:00</updated><title type='text'>Lesson Plan - para shaerar</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;iframe src='https://lrn.cc/NJ' frameborder='0' height='640' width='520'/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-7449003068396225234?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/7449003068396225234/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=7449003068396225234' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/7449003068396225234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/7449003068396225234'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2012/01/lesson-plan-para-shaerar.html' title='Lesson Plan - para shaerar'/><author><name>Damian Suarez</name><uri>http://www.blogger.com/profile/04393216503371957176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://lh5.google.com/image/rdsuarez/RcONjCjR_WI/AAAAAAAAADc/3ETM2H-CbQQ/croataverde80.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-8339085672228193202</id><published>2007-03-07T17:15:00.000-03:00</published><updated>2007-03-07T18:24:48.907-03:00</updated><title type='text'>Actualización de Medidor de progreso de subida de archivos en Ajax</title><content type='html'>Este artículo es la traducción del este &lt;a href="http://blog.joshuaeichorn.com/archives/2006/03/14/php-ajax-file-upload-progress-meter-updates/"&gt;PHP AJAX File Upload Progress Meter Updates&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Durante el fin de semana mi código de medidor de subida de archivos tuvo mucho tráfico. Parece que está en la lista de populares de del.icio.us y tambien está obteniendo un montón de votos en digg. Para celebrar esto actualicé el código.&lt;br /&gt;La nueva característica mas importante es que devuelve información sin tener  que parchear PHP. Ahora la versión parcheada te da mas información como velocidad de subida y tiempo estimado de finalización. Pero igual damos devolución al usuario sin usarlo.&lt;br /&gt;También creé algunas páginas wiki para empezar el proceso de documentación&lt;br /&gt;Acá están los demos:&lt;br /&gt;&lt;a href="http://php5.bluga.net/UploadProgressMeter/demo.php"&gt;Con el Parche y la extensión&lt;/a&gt;&lt;br /&gt;&lt;a href="http://bluga.net/projects/uploadProgressMeter/demo/demo.php"&gt;Sin el parche&lt;/a&gt;&lt;br /&gt;Para tener la velocidad de subida vas a necesitar descargar e instalar el  parche y extensión &lt;a href="http://pdoru.from.ro/"&gt;PHP Upload Progress.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si queres usar el codigo necesitas:&lt;br /&gt;Instalar &lt;a href="http://htmlajax.org/"&gt;HTML_AJAX&lt;/a&gt; (pear install HTML_AJAX-alpha)&lt;br /&gt;Descargar &lt;a href="http://websvn.bluga.net/wsvn/HTML_AJAX/UploadProgressMeter/trunk/?op=dl&amp;rev=0&amp;amp;isdir=1"&gt;PAFUPMU&lt;/a&gt; e instalarlo en algún lugar accesible.&lt;br /&gt;Agregar el código a tu página usando &lt;a href="http://websvn.bluga.net/wsvn/HTML_AJAX/UploadProgressMeter/trunk/demo.php?op=file&amp;rev=0&amp;amp;sc=0"&gt;demo.php&lt;/a&gt; como un ejemplo.&lt;br /&gt;&lt;br /&gt;La forma básica en que trabaja el código es: tomamos un formulario que contiene una subida de archivo y un aceptar con un objetivo (target) en un iframe oculto.  Hacer esto permite que la subida pase en el fondo. Entonces consultamos al servidor en lapsos regulares (digamos intervalos de 2 segundos) preguntando para actualizar el estado. Si tenés el parche+extensión instalado te da la velocidad de subida del archivo, etc. Si no tenés la extensión paramos de hacer llamadas AJAX y solo animamos la barra de estado hasta que la subida termine  en el iframe  y nos diga que terminamos.&lt;br /&gt;En demo.php nos encargamos de generar la página vigente y manejamos la subida en la misma página. Entonces empezamos gestionado la actualización.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;include ‘UploadProgressMeter.class.php’;&lt;br /&gt;$fileWidget = new UploadProgressMeter();&lt;br /&gt;if ($fileWidget-&gt;uploadComplete()) {&lt;br /&gt;    // output javascript to the iframe to send a final status to the main window&lt;br /&gt;    // this will catch error conditions&lt;br /&gt;    echo $fileWidget-&gt;finalStatus();&lt;br /&gt;    // move the file(s) where they need to go&lt;br /&gt;    exit;&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Este código solo funciona cuando estas subiendo por eso no veras nunca una salida de este.  Esto puede hacer problemático el seguimiento de errores. Por otro lado esto se puede resolver haciendo el iframe no oculto.&lt;br /&gt;Luego montas el Javascript necesario, primero HTML_AJAX y después los subidores JS.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;    &amp;lt;script type=’text/javascript’ src=’demoserver.php?client=main,request,httpclient,dispatcher,json,util’&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;script type=’text/javascript’ src=’demoserver.php?stub=UploadProgressMeterStatus’&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;?php echo $fileWidget-&gt;renderIncludeJs(); ?&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;demoserver.php está incluido en la fuente, puede ser que quieras nombrarlo de otra manera si realmente usas este código.Es solo una página usando HTML_AJAX_Server para registrar la clase UploadProgressMeterStatus.&lt;br /&gt;También necesitás algo de CSS para darle estilo a la barra de progreso. Lo único importante es que .progressBar y . progressBar.bar estén posicionadas relativamente.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;.progressBar {&lt;br /&gt;            position: relative;&lt;br /&gt;            padding: 2px;&lt;br /&gt;            width: 300px;&lt;br /&gt;            height: 40px;&lt;br /&gt;            font-size: 14px;&lt;br /&gt;    }&lt;br /&gt;    .progressBar .background {&lt;br /&gt;            border: solid 1px black;&lt;br /&gt;            width: 270px;&lt;br /&gt;            height: 20px;&lt;br /&gt;    }&lt;br /&gt;    .progressBar .bar {&lt;br /&gt;            position: relative;&lt;br /&gt;            background-color: blue;&lt;br /&gt;            width: 0px;&lt;br /&gt;            height: 20px;&lt;br /&gt;    }&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Finalmente termina las cosas construyendo un formulario. Fijate que podés incluir otros elementos en el formulario, pero si necesitan producir una salida vas a tenés que manejar rellamadas en la pagina padre desde la salida del iframe.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;form action="demo.php" enctype="multipart/form-data" method="post" &amp;lt;?php echo $fileWidget-&gt;renderFormExtra(); ?&amp;gt;&amp;gt;&lt;br /&gt;&amp;lt;?php echo $fileWidget-&gt;renderHidden(); ?&amp;gt;&lt;br /&gt;&amp;lt;label&amp;gt;Select File: render(); ?&amp;gt;&lt;br /&gt;&amp;lt; ?php echo $fileWidget-&gt;renderProgressBar(); ?&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-8339085672228193202?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/8339085672228193202/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=8339085672228193202' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/8339085672228193202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/8339085672228193202'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2007/03/actualizacin-de-medidor-de-progreso-de.html' title='Actualización de Medidor de progreso de subida de archivos en Ajax'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-687175044842906105</id><published>2007-03-06T15:00:00.000-03:00</published><updated>2007-03-08T13:40:46.720-03:00</updated><title type='text'>Progreso del upload de un archivo en AJAX</title><content type='html'>Este artículo es la traducción del este &lt;a href="http://blog.joshuaeichorn.com/archives/2005/05/01/ajax-file-upload-progress/"&gt;AJAX File upload Progress&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pinien.blogspot.com/2007/03/actualizacin-de-medidor-de-progreso-de.html"&gt;El ejemplo de como usar la versión mas nueva está disponible en otro post&lt;/a&gt;.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Actualización&lt;/span&gt;&lt;br /&gt;Hay una nueva versión de este código que sigue la misma premisa pero usa HTML_AJAX en vez de JPspan.&lt;br /&gt;Podes ver el nuevo demo y ver el código en websvn.&lt;br /&gt;Notar también que el servidor no está configurado para aceptar archivos mayores de 8 Mb. Si es así el script va a fallar.&lt;br /&gt;También estoy buscando a alguien que me ayude a mejorar el manejo de errores, si estas interesado en participar y hacer algunas actualizaciones de código nuevo házmelo saber.&lt;br /&gt;&lt;p&gt;Sigue el artículo Original&lt;br /&gt;&lt;/p&gt;Un par de días atrás, encontré un &lt;a href="http://sean.treadway.info/demo/upload"&gt;proyecto interesante de ruby on rails&lt;/a&gt;. Usa Ajax para actualizar una barra de progreso mientras sube un archivo. Este truco es un parche para rails para obtener el estado de subida y hacer la subida en un iframe para que la pagina principal siga activa.&lt;br /&gt;Entonces para implementar esto solo tenía que encontrar el parche que provee el estado de la subida en PHP y luego implementarlo en mi pequeño iframe accesorio de subidas.&lt;br /&gt;Encontré el código PHP con un poco de trabajo en Google: &lt;a href="http://pdoru.from.ro/"&gt;Barra de progreso de subida&lt;/a&gt;&lt;br /&gt;Primero necesitas instalar el parche y la extensión, las instrucciones incluidas son fáciles de seguir. El único problema que encontré es que hay que configurar: upload_progress_meter.store_method = “file” en mi php.ini en primera instancia antes de probar los scripts.&lt;br /&gt;También tuve un problema con JPSpan, si estas teniendo problemas de red el llamado de estado puede tomar mas de un segundo y vas a tener un alerta de error de llamada en progreso. Esto puede ser resuelto con la versión actual de JPSpan pero me gustaría ver alguna api agregada para ayudar. Los objetos con Proxi necesitan algún tipo de llamada en progreso para hacer un arreglo fácil.&lt;br /&gt;Un ítem notable es que la extensión provee información de la transferencia total de manera que solo se implementa una barra por formulario sin importar cuantos archivos tenga. El código Javascript esta programado para varios formularios en una página y que suban al mismo tiempo, pero no ha sido testeado.&lt;br /&gt;&lt;a href="http://php5.bluga.net/progressDemo/demo.php"&gt;Acá está el demo&lt;/a&gt; que estabas esperado, para la mayoría de la conexiones un archivo de 250k va a ser suficiente para apreciar algo además de conectar y completar.&lt;br /&gt;Además si alguno tiene el tiempo y las habilidades para revisar el parche php y ver que necesitaría para estar integrado,por favor haganmelo saber. No se nada del autor por eso no sé por que no está integrado pero parece medio loco tener un parche de 3k tan útil solamente disponible para aquellos que estar dispuestos a parchear.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Detalle del código&lt;/span&gt;&lt;br /&gt;EL flujo básico sucede así:&lt;br /&gt;Muestra una página con un formulario:&lt;br /&gt;Esta página tiene un iframe oculto, un div de progreso oculto, y algun código javascrip extra.&lt;br /&gt;Selección del archivo para subir y acepto el fomulario:&lt;br /&gt;El formulario tiene un objetivo (target) en el iframe oculto, por esto aún cuando icono indicador de actividad del navegador empiece funcionar, la pagina principal no va a tener nuevo contenido cuando el upload haya terminado.&lt;br /&gt;El evento onclick del formulario dispara una función determinada:&lt;br /&gt;La función encuentra el div de progreso y lo muestra, también registra una función para actualizar el estado cada segundo.&lt;br /&gt;La función actualización dispara cada segundo:&lt;br /&gt;Esta función controla un contador para ver si hay algun div mas para actualizar, si el contador es cero detiene la función actualización desde el disparo otra vez.&lt;br /&gt;La función crea un objeto proxy remoto para la clase php UploadProgressMeterStatus si aún no ha sido creado.&lt;br /&gt;La función llama al método get_status en el objeto proxy con un lista de todos los divs de progreso y una de los UPLOAD_IDENTIFIER que necesitamos los estados.&lt;br /&gt;La función existe.&lt;br /&gt;El método get-status en la clase de php es llamado.&lt;br /&gt;El método llama a upload_progress_meter_get_info() para cada uno pasado en el indentificador, la información es formateada a un porcentaje y un mensaje que es devuelto.&lt;br /&gt;La funcion de rellamada para get_status se llama cuando laclases PHP devuelve información.&lt;br /&gt;La rellamada actualiza el div de progreso.&lt;br /&gt;Si estubiera al 100% decrementamos nuestro contador de div de progreso y lo removemos de la lista de divs para ser actualizados.&lt;br /&gt;El iframe puede tambien cargar una página una vez que la carga haya terminado, actualmente no hace nada.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Código de ejemplo&lt;/span&gt;&lt;br /&gt;Este es realmente el único código PHP interesante en el proyecto, y no tan interesante. Cuando tenés instalada la extensión de medidor de progreso de subida todo formulario que este haciendo una subida de archivo y tenga una barra oculta que se llame UPLOAD_IDENTIFIER puede ser seguido. El identificador tiene que ser pasado en la función upload_progress_meter_get_infopor eso tenés que hacer el seguimiento del mismo del lado de Javascript. Acá solo pasamos eso identificadores, hacemos un grupo de ellos en el array de resultado y devolvemos los resultados. Notar que el array devuelto no esta documentado en ningún lado por lo que este código y el código en el ejemplo de php provisto con la extensión es el mejor lugar para empezar si querés.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;?php&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;      * Obtener el estado de todas las subidas que se pasen.&lt;br /&gt;      */&lt;br /&gt;     function get_status($ids) {&lt;br /&gt;             $ret = array();&lt;br /&gt;             foreach($ids as $id =&gt; $upId) {&lt;br /&gt;                     $ret[$id] =  new stdClass();&lt;br /&gt;&lt;br /&gt;                     $tmp = upload_progress_meter_get_info($upId);&lt;br /&gt;                     if (!is_array($tmp)) {&lt;br /&gt;                             $ret[$id]-&gt;message = “Complete”;&lt;br /&gt;                             $ret[$id]-&gt;percent = “100″;&lt;br /&gt;                             break;&lt;br /&gt;                     }&lt;br /&gt;&lt;br /&gt;                     if ($tmp[‘bytes_total’] &lt; percent =" 100;" percent =" round($tmp[‘bytes_uploaded’]" percent ="="&gt;message = “Complete”;&lt;br /&gt;                     }&lt;br /&gt;&lt;br /&gt;                     $eta            = sprintf(“%02d:%02d”, $tmp[‘est_sec’] / 60, $tmp[‘est_sec’] % 60 );&lt;br /&gt;                     $speed          = $this-&gt;_formatBytes($tmp[’speed_average’]);&lt;br /&gt;                     $current        = $this-&gt;_formatBytes($tmp[‘bytes_uploaded’]);&lt;br /&gt;                     $total          = $this-&gt;_formatBytes($tmp[‘bytes_total’]);&lt;br /&gt;&lt;br /&gt;                     $ret[$id]-&gt;message = “$eta left (at $speed/sec) $current/$total($percent%)”;&lt;br /&gt;                     $ret[$id]-&gt;percent = $percent;&lt;br /&gt;             }&lt;br /&gt;             return $ret;&lt;br /&gt;     }&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;En el lado de JavaScript hay un poco mas de código, pero no es para nada complejo.Este código es usado para mostrar la barra de progreso y darle algunos valores iniciales. Las cosas mas importantes para resaltar son que hay agregado un método de actualización al div, este es un lindo truco por que permite la extensión en tiempo de ejecución de los objetos en DOM, y va a hacer actualizar las cosas agradable y fácil en otras funciones. También agregamos un método getFirstDivByClass al div, hago esto para no tener tantos div para seguir, las clases solo tienen que ser únicas dentro de la barra de proceso para que ande y eso es mucho mas fácil de lograr&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;/**&lt;br /&gt;* Muestra una barra de progreso y la establece a 0&lt;br /&gt;*/&lt;br /&gt;function UploadProgressMeter_EnableProgress(progress_id) {&lt;br /&gt;       var progress = document.getElementById(progress_id);&lt;br /&gt;       progress.style.display = ‘block’;&lt;br /&gt;       progress.percent = 0;&lt;br /&gt;       progress.message = "Connecting";&lt;br /&gt;&lt;br /&gt;       progress.update = function() { this.getFirstDivByClass(‘bar’).style.width = this.percent+‘%’; this.getFirstDivByClass(‘message’).innerHTML = this. message; }&lt;br /&gt;&lt;br /&gt;       progress.getFirstDivByClass = function(className) {&lt;br /&gt;               var nodes = this.getElementsByTagName(‘div’);&lt;br /&gt;               for(var i = 0; i &lt; classname ="=""&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;El código siguiente llama a un proxy remoto y crea una función de rellamada para gestionar el resultado. Hay un área donde se pueden hacer mejoras. Primero debería haber un control de si hay actualmente una llamada en progreso. Luego, sería inteligente llamar al servidor menos (especialmente en archivos grandes) y solo generar las estadísticas del índice de descarga actual.Esto va a agregar un poco de complejidad pero permitiría a la barra de progreso actualizar suavemente y permitiría que las llamadas al servidor bajar a una vez cada 5 o 10 segundos&lt;br /&gt;Si no haces mucha programación javascript no vale la pena el uso de for(var prop in result) en delete UploadProgressMeter_active[prop];&lt;br /&gt;for(var prop in result) es como iteras en las propiedades de un objeto, esto te permite usarlas como arreglos asociativos (solo mira los métodos en los objetos  ya que vas a iterar en ellos también).&lt;br /&gt;delete UploadProgressMeter_active[prop] es el equivalente de unset($array[’key’]);&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;/**&lt;br /&gt;* Actualizar las barras de progreso de todas las barras vigentes&lt;br /&gt;*/&lt;br /&gt;function UploadProgressMeter_Update() {&lt;br /&gt;      if (UploadProgressMeter_count == 0) {&lt;br /&gt;              clearInterval(UploadProgressMeter_intervalId);&lt;br /&gt;              UploadProgressMeter_intervalId = false;&lt;br /&gt;              return;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      if (UploadProgressMeter_remote == false) {&lt;br /&gt;              var callback = {&lt;br /&gt;                      get_status: function(result) {&lt;br /&gt;                              for(var prop in result) {&lt;br /&gt;                                      if (prop != "toString") {&lt;br /&gt;                                              document.getElementById(prop).percent = result[prop].percent;&lt;br /&gt;                                              document.getElementById(prop).message = result[prop].message;&lt;br /&gt;                                              document.getElementById(prop).update();&lt;br /&gt;&lt;br /&gt;                                              if (document.getElementById(prop).percent == 100) {&lt;br /&gt;                                                      UploadProgressMeter_count–;&lt;br /&gt;                                                      delete UploadProgressMeter_active[prop];&lt;br /&gt;                                              }&lt;br /&gt;                                      }&lt;br /&gt;                              }&lt;br /&gt;                      }&lt;br /&gt;              }&lt;br /&gt;              UploadProgressMeter_remote = new uploadprogressmeterstatus(callback);&lt;br /&gt;      }&lt;br /&gt;      UploadProgressMeter_remote.get_status(UploadProgressMeter_active);&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Code List&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bluga.net/projects/uploadProgressMeter/UploadProgressMeter.tar.gz"&gt;Tarball&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bluga.net/projects/uploadProgressMeter/code/UploadProgressMeter.class.phps"&gt;Código principal del coso php&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bluga.net/projects/uploadProgressMeter/code/UploadProgressMeter.jss"&gt;Código del coso de Javascript&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bluga.net/projects/uploadProgressMeter/code/demo.phps"&gt;Página demo html/php&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bluga.net/projects/uploadProgressMeter/code/demoserver.phps"&gt;Página del servidor Demo JPSpan&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Actualizaciones&lt;br /&gt;Te habras dado cuenta que el demo dejo de andar un par de veces. Esto está relacionado con dos cosas y hay cosas que puede ser que quiera pensar si vas a usar el parche. Primero escribe archibos tmp y falla sileciosamente si no existe más (scripts que limpian los tmp). Segundo, esta en my servidor php5 que tiene algunos usuarios que estan presionando para que me actualice a php 5.1 beta y me olvide de reparchear. Reparchear no fue un gran problema aunque tube que mover donde una funcion fue declarada para obtener la extensión para compilar en gcc 4 (me actualice a fedora core 4 también)&lt;br /&gt;De todos modos el demo está trabajando y debería seguir trabajando siempre y cuando me acuerde de reparchear con cada actualización.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Nueva versión&lt;/span&gt;&lt;br /&gt;Este código ha sido actualizado para trabajar con HTML_AJAX y para manejar mejor las condiciones de error. No he hecho un lanzamiento oficial paro podes tomarlo del svn.&lt;br /&gt;Ver en: http://svn.bluga.net/HTML_AJAX/UploadProgressMeter/trunk/&lt;br /&gt;O usar websvn para obtener un tarball: http://websvn.bluga.net/wsvn/HTML_AJAX/UploadProgressMeter/trunk/?rev=0&amp;amp;sc=0&lt;br /&gt;También si estas interesado en ayudar con la medición de progreso de subida, haganmelo saber.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-687175044842906105?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/687175044842906105/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=687175044842906105' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/687175044842906105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/687175044842906105'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2007/03/progreso-del-upload-de-un-archivo-en.html' title='Progreso del upload de un archivo en AJAX'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-1700340463137652188</id><published>2007-01-13T11:22:00.000-03:00</published><updated>2007-01-24T13:09:04.934-03:00</updated><title type='text'>Mootools Introducción/Tutorial - Native</title><content type='html'>El grupo de scripts Native son extensiones básicas de los objetos por defecto en javascript (actualmente Mootools tiene código nativo para Array, Element, Function y String) Esos archivos modifican la manera en que esos elementos y toda instancia de ellos trabajan. Como es posible crear arrays o strings antes de que este código se ejecute, tienen típicamente un significado por el cual  aplican estas funciones a los strings existentes. Por ejemplo, $A(myArray) solo te devuelve myArray con todas las extensiones aplicadas.&lt;br /&gt;Acá hay un resumen de las funciones disponibles para esos objetos; la mayoría de ellos pueden ser ejecutados haciendo click "ejecuta este código".&lt;br /&gt;&lt;h1&gt;String.js - Extensiones String, Numer.toInt()&lt;/h1&gt;&lt;br /&gt;Acá esta la &lt;a href="http://docs.mootools.net/files/Native/String-js.html"&gt;página de documentación de String.js&lt;/a&gt;.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;span style="font-weight: bold;"&gt;String.test()&lt;/span&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"I like cookies".test("cookie"); // devuelve ["cookie"]&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;//ignora la distinción de mayúsculas y minúsculas&lt;br /&gt;"I like cookies".test("COOKIE", "i")&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;//ignora la distinción de mayúsculas y minúsculas&lt;br /&gt;"I like cookies because cookies are good".test("COOKIE", "ig");&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;//no devuelve nada&lt;br /&gt;"I like cookies".test("cake");&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;//este es un ejemplo de como probablemente lo usarias en realidad&lt;br /&gt;if("I like cookies".test("cake")) alert ('you like cake');&lt;br /&gt;else alert("you don't like cake (what's wrong with you?)");&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;String.toInt()&lt;/span&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"10".toInt(); // el valor es 10&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"10px".toInt(); // el velor es 10&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"-10".toInt(); // el valor es -10&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"px10".toInt(); // no devuelve nada&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;String.camelCase()&lt;/span&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"I-like-cookies".camelCase(); //"ILikeCookies"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;String.capitalize()&lt;/span&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"i like cookies".capitalize(); //"I Like Cookies"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;String.trim()&lt;/span&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"    i like cookies     ".trim() //"i like cookies"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;String.clean()&lt;/span&gt;&lt;br /&gt;hace lo mismo que trim y ademas elimina todos los doble espacios del string&lt;br /&gt;JavaScript:&lt;br /&gt;" i      like     cookies      \n\n".clean() //"i like cookies"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;String.rgbToHex()&lt;/span&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"rgb(17,34,51)".rgbToHex(); //"#112233"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"rgba(17,34,51,0)".rgbToHex(); //"transparent"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"rgb(17,34,51)".rgbToHex(true); //[11,22,33]&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;String.hexToRgb()&lt;/span&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;"#112233".hexToRgb(); //"rgb(17,34,51)"&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight: bold;"&gt;Number.toInt()&lt;/span&gt;&lt;br /&gt;Number.toInt() solo devuelve el número; útil porque toInt debe trabajar en ambas Strings y Números.&lt;br /&gt;&lt;h1&gt;Array.js&lt;/h1&gt;&lt;br /&gt;Acá está la &lt;a href="http://www2.blogger.com/img/gl.link.gif"&gt;documentación de Array.js&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Array.each()&lt;/span&gt;&lt;br /&gt;Array.each() itera en el Array ejecutando la funcion especificada para cada ítem del array. La funcion anonymous pude pasar dos argumentos (opcionales) - el ítem y el índice:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;["one", "two", "three"].each(function(number){&lt;br /&gt;alert(number);&lt;br /&gt;});&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;["one", "two", "three"].each(function(number, index){&lt;br /&gt;if(index == 0) alert(number); //solo vamos a mostrar el primero&lt;br /&gt;});&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Array.copy()&lt;/span&gt;&lt;br /&gt;Copia el array y lo devuelve.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;var letters = ["a","b","c"];&lt;br /&gt;var copy = ["a","b","c"].copy();&lt;br /&gt;alert(copy);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Array.remove()&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;["1","2","3"].remove("2") // ["1","3"];&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Array.test()&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;["a","b","c"].test("a"); // true&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;["a","b","c"].test("d"); // false&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Array.extend()&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;var Animals = ['Cat', 'Dog', 'Coala'];&lt;br /&gt;Animals.extend(['Lizard']); //Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard'];&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Array.associate()&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;var Animals = ['Cat', 'Dog', 'Bird', 'Lizard'];&lt;br /&gt;var Speech = ['Meow', 'Bark', 'Chirp', 'Mute'];&lt;br /&gt;var Speeches = Animals.associate(speech);&lt;br /&gt;//Speeches['Meow'] is now Cat.&lt;br /&gt;//Speeches['Bark'] is now Dog.&lt;br /&gt;//...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$A()&lt;/span&gt;&lt;br /&gt;$A() aplica esas funciones a cualquier objeto iterable. Ejemplo:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;function myFunction(){&lt;br /&gt;$A(arguments).each(argument, function(){&lt;br /&gt; alert(argument);&lt;br /&gt;});&lt;br /&gt;};&lt;br /&gt;//the above will alert all the arguments passed to the function myFunction.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h1&gt;Function.js&lt;/h1&gt;&lt;br /&gt;Acá está la &lt;a href="http://docs.mootools.net/files/Native/Function-js.html"&gt;documentación de Function.js&lt;/a&gt;.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Function.pass(arguments, bind(optional))&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;//syntax: Function.pass(arguments, bind)&lt;br /&gt;//bind es opcional; mas sobre bind mas tarde&lt;br /&gt;//ejemplo: myFunction.pass([arg1, arg2], myElement);&lt;br /&gt;function say(msg){&lt;br /&gt;alert(msg);&lt;br /&gt;};&lt;br /&gt;say.pass('hello world')();&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Te preguntarás porqué hacer esto, pero vas a ver el porqué en ejemplos mas adelante. Basicamente,  no siempre queres ejecutar una funcion inmediatamente, y sin algo como el método .pass() no tenes manera de pasar variables a esa funcion sin ejecutarla. myFunction(value) ejecuta muyFunction. myFunction.pass(value) configura myFunction para poder ejecutarla mas tarde.&lt;br /&gt;Vamos a decir que tenés un efecto que va a hacer que algo se desvanezca. Cuando está hecho, queres ejecutar un callback de algun orden. Tu efecto tiene una opción para que le entregues una función para que la ejecute cuando termine, pero necesitas pasarle a esa función algunas variables. Si haces algo como:"onComplete: myFunction(value)" vas a ejecutar tu función inmediatamente  y onComplete sera equivalente a lo que sea devuelto, lo cual no es lo que querés.  Si en cambio haces "onComplete: myFunction.pass(value)" obtendras lo que querìas. myFunction.pass(value) devuelve una instancia de esa función con el parámetro establecido, entonces cuando ejecutes onComplete() va a estar ejecutando realmente myFunction(value)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Function.bind(object)&lt;/span&gt;&lt;br /&gt;La palabra reservada "this" dentro de un objeto (como una función) refiere a la instancia de ese objeto. Es realmente muy útil para un montón de cosas, no solo las que están referidas a otras funciones en el mismo objeto o estado de cierta variable. El problema es que puede ser que seas autor de la funcionalidad que necesita poder referir a variables en el objeto que lo está llamando. Abajo hay un ejemplo simple de esto, pero cuando escribes clases y funciones más complejas  vas a encontrar que esta habilidad para definir que "this" es, en un contexto dado, una necesidad.&lt;br /&gt;Este ejemplo debe cambiar este párrafo a que tengo un borde alrededor de él.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;function myFunction(){&lt;br /&gt;this.setStyle('border', '1px solid black');&lt;br /&gt;//notar que 'this' acá refiere myFunction, no a un elemento&lt;br /&gt;//vamos a necesitar unir esta funcion con el elemento que queremos alterar&lt;br /&gt;};&lt;br /&gt;//Unir el elemento que quiero aplicar el efecto con la función&lt;br /&gt;//Notar que una función es devuelta, no ejecutada&lt;br /&gt;var myBoundFunction = myFunction.bind($('bindExample'));&lt;br /&gt;//ejecutar esa nueva función con el objeto bound&lt;br /&gt;myBoundFunction();&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Function.bindAsEventListener();&lt;/span&gt;&lt;br /&gt;Una función con el parámetro bind como su "this" y como un evento de argumento pre-pasado o window.event, dependiendo del navegador.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;function myFunction(event){&lt;br /&gt;alert(event.clientx) //devuelve las coordenadas del mouse&lt;br /&gt;};&lt;br /&gt;myElement.onclick = myFunction.bindAsEventListener(myElement);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Function.delay(milliseconds, bind(optional))&lt;/span&gt;&lt;br /&gt;Si, puedes establecer demoras con setTimeout, pero a veces es enrrollado y complicado. Adicionalmente, la demora te permite unir un elemento con la función que va a se demorada&lt;br /&gt;El ejemplo que sigue debe dibujar un borde alrededor de este párrafo después de un segundo de espera.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;function myFunction(){&lt;br /&gt;  this.setStyle('border', '1px solid black');&lt;br /&gt;};&lt;br /&gt;myFunction.delay(500, $('delayExample'));&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Acá hay un gran ejemplo de vinculación. Si el elemento fuera un argumento para la función, no podría llamar la función con un argumento sin ejecutarla. Este tipo de sintaxis no funcionaría:&lt;br /&gt;&lt;br /&gt;myFunction($('delayExample')).delay(500);&lt;br /&gt;&lt;br /&gt;...no podría funcionar, porque ejecutarías la función inmediatamente y .delay() intentaría ejecutarse como un método de lo que haya sido devuelto.&lt;br /&gt;Podrías hacer esto sin embargo:&lt;br /&gt;myFunction.pass($('delayExample')).delay(500);&lt;br /&gt;Está también .periodical(), que periódicamente ejecuta tu función&lt;br /&gt;&lt;br /&gt;There's also .periodical(), which repeatedly executes your function.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La clase cadena (chain)&lt;/span&gt;&lt;br /&gt;Encadenar es una manera bastante inteligente de establecer una lista de funciones que quieras ejecutar en un orden dado sin ejecutarlas todavía. Luego, cada vez que llames el método .callChain() la próxima función de ejecutará.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;var x = new Chain();&lt;br /&gt;var one = function(){alert('1')};&lt;br /&gt;var two = function(){alert('2')};&lt;br /&gt;x.chain(one);&lt;br /&gt;x.chain(two);&lt;br /&gt;x.callChain();&lt;br /&gt;x.callChain.delay(2000);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$clear() - liberando esperas&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;var myTimer = (function() {alert('1 second!');}).delay(1000);&lt;br /&gt;  //espera 5 segundos y ejecuta mi función&lt;br /&gt;myTimer = $clear(myTimer); //no importa&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight: bold;"&gt;$type() - Obtener el tipo de un elemento&lt;/span&gt;&lt;br /&gt;$type devuelve el tipo de un objeto ("function" o "string", etc.) o nada si el objeto es nulo (o una cadena vacía). &lt;span style="font-weight: bold;"&gt;(Nota: esto está cambiando en la próxima versión de mootools; si le das a $type un boolean= false en mootools versión 84 vas a obtener un falso, no un "boolean"; esto está cambiando para devolver el tipo real del objeto, y solo devolver falso si el objeto es nulo o indefinido, por esto usar con precaución).&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;$type('hi'); //"string"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;$type(function(){});//"function"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;$type({});//"object"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;$type([]);//"array"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;var x = null;&lt;br /&gt;$type(x);//nothing returned&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h1&gt;Element.js&lt;/h1&gt;&lt;br /&gt;Acá está la &lt;a href="http://docs.mootools.net/files/Native/Element-js.html"&gt;documentación para Elements.js&lt;/a&gt;.&lt;br /&gt;El objeto Element consigue mucho amor en Mootools. La mayoría de las funciones en el objeto Element son bastante auto-explicativas.  Element.getTag() hace lo que piensas que podría hacer. Element.remove() no tiene sorpresas. Acá hay algunos ejemplos de las funciones más útiles y menos obvias, pero realmente deberías leer la página de &lt;a href="http://docs.mootools.net/files/Native/Element-js.html"&gt;documentación de Element.js&lt;/a&gt; para el detalle completo.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Element.initialize()&lt;/span&gt;&lt;br /&gt;Este solo crea un nuevo objeto elemento - lo mismo que document.createElement, pero también aplica las extensiones de Mootools a ese elemento.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;var img = new Element("img");&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$()&lt;/span&gt;&lt;br /&gt;Cansado de escribir "document.getElementById('blah')"? no hay problema. Esto también aplica todas esas extensiones de Element al objeto.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;$('getElementByIdExample');&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Element.injectInside, Element.injectBefore, Element.injectAfter&lt;/span&gt;&lt;br /&gt;Mucho más de lo que parece. Inyecta el elemento relativo a el que sea pasado como argumento.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;HTML:&lt;br /&gt;&amp;lt;div id="myElement"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div id="mySecondElement"&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;$('mySecondElement').injectBefore('myElement');&amp;lt;/script&amp;gt;&lt;br /&gt;resulting html:&lt;br /&gt;&amp;lt;div id="mySecondElement"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div id="myElement"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;injectInside usa appendChild en el elemento provisto:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;html:&lt;br /&gt;   &amp;lt;div id="myElement"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;   &amp;lt;div id="mySecondElement"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;   &amp;lt;script&amp;gt;$('mySecondElement').injectInside('myElement');&amp;lt;/script&amp;gt;&lt;br /&gt;   resulting html:&lt;br /&gt;   &amp;lt;div id="myElement"&amp;gt;&amp;lt;div id="mySecondElement"&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.adopt&lt;/span&gt;&lt;br /&gt;Este es tal como injectInside, pero al revés (añande el elemento provisto al que se aplica):&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;HTML:&lt;br /&gt;&amp;lt;div id="myElement"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div id="mySecondElement"&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;$('mySecondElement').adopt('myElement');&amp;lt;/script&amp;gt;&lt;br /&gt;resulting html:&lt;br /&gt;&amp;lt;div id="mySecondElement"&amp;gt;&amp;lt;div id="myElement"&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.replaceWith&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;$('myOldElement').replaceWith($('myNewElement'));&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;$('myOldElement') no está mas, y $('myNewElement') está en su lugar.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.appendText&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;HTML:&lt;br /&gt;&amp;lt;div id="myElement"&amp;gt;hey&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;$('myElement').appendText(' howdy');&lt;br /&gt;//myElement innerHTML es ahora "hey howdy"&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.add/removeClass/hasClass/toggleClass&lt;/span&gt;&lt;br /&gt;Estos hacen bastante más de que aparentan hacer.&lt;br /&gt;&lt;br /&gt;Este parrafo tiene id=cssClassesExample para el ejemplo siguiente.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   //tiene el párrafo de arriba el className blue?&lt;br /&gt;   $('cssClassesExample').hasClassName('blue');&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   //se lo agregamos&lt;br /&gt;   $('cssClassesExample').addClassName('blue');&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   //ahora lo borramos&lt;br /&gt;   $('cssClassesExample').removeClassName('blue');&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   //ahora vamos a prenderlo y a apagarlo&lt;br /&gt;   $('cssClassesExample').toggleClass('blue');&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.getStyle, Element.setStyle, Element.setStyles&lt;/span&gt;&lt;br /&gt;Bastante directo:&lt;br /&gt;Este párrafo tiene id = getStyleExample para el ejemplo siguiente.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('getStyleExample').getStyle('width'); //returns something like "528px"&lt;br /&gt;&lt;/div&gt; &lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('getStyleExample').getStyle('width').toInt(); //returns 528 (an integer)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;setStyle te permite establecer una única propiedad css:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('setStyleExample').setStyle('border', '1px solid black');&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;setStyles tiene una sintaxis levemente diferente y te permite establecer todas las que quieras: &lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('setStylesExample').setStyles({&lt;br /&gt;       'border':'1px solid yellow',&lt;br /&gt;       'background':'#666',&lt;br /&gt;       'color':'#fff'&lt;br /&gt;   });&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.setProperty, setProperties&lt;/span&gt;&lt;br /&gt;Trabaja bastante similar a setStyle(s) excepto que puedes establecer las propiedades de un elemento:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   var img = new Element('img');&lt;br /&gt;   img.setProperty('src', http://clientside.cnet.com/wp-content/themes/clientside/art/logo.gif');&lt;br /&gt;   img.setProperty('id', 'logoExample');&lt;br /&gt;   img.injectInside($('setPropertiesExample'));&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Vamos a asignar algunas propiedades más:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('logoExample').setProperties({&lt;br /&gt;       'alt':'clientside',&lt;br /&gt;       'title':'clientside'&lt;br /&gt;   });&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.getProperty()&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('logoExample').getProperty('src');//gets the img url&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.getTop(), getLeft()&lt;/span&gt;&lt;br /&gt;Este devuelve el offset de la parte de arriba del elemento y la parte de arriba de la ventana (o la izquierda del elemento y la izquierda de la ventana)&lt;br /&gt;Este párrafo se usa en el ejemplo siguiente.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('topAndLeftExample').getTop() //returns an integer&lt;br /&gt;&lt;/div&gt; &lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('topAndLeftExample').getLeft() //returns an integer&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.getValue()&lt;/span&gt;&lt;br /&gt;Devuelve el valor de un campo de entrada de un formulario. Ejemplo:&lt;br /&gt;&lt;div class="simple_box"&gt; &lt;br /&gt;   JavaScript:&lt;br /&gt;   $('getValueInputExample').getValue() //devuelve algun valor&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt; &lt;br /&gt;   JavaScript:&lt;br /&gt;   $('getValueSelectExample').getValue() //devuelve 'value 1'&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.setHTML()&lt;/span&gt;&lt;br /&gt;Vamos a cambiar este contenido...&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('setHTMLExample').setHTML('ves? cambió!');&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Te preguntaras porqué usar esto o algo como getProperty cuando javascript tiene métodos para hace es el mismo; estamos solo cambiando una sintaxis por otra. Podes tan fácilmente hacer:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('setHTMLExample').innerHTML = 'ves? cambió!';&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;entonces, por que hacerlo? Bueno, haciendo esta función disponible podes hacer cosas como .delay() y .pass() en aplicaciones mas complejas. Tambien permite encadenar cosas juntas como:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;$('myExample').setHTML('example').addClass('something').removeClass('somethingElse').addEvent(....) etc.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.getTag()&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('logoExample').getTag() // returns 'img'&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.setOpacity&lt;/span&gt;&lt;br /&gt;Opacity toma un valor entre cero (transparente y 1 (opaco)&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('setOpacityExample').setOpacity(0); //ahora no lo ves&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('setOpacityExample').setOpacity(.5); //se ve a medias&lt;br /&gt;&lt;/div&gt; &lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('setOpacityExample').setOpacity(1); //se ve 100%&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.addEvent&lt;/span&gt;&lt;br /&gt;Aquellos que estén familiarizados con el objeto Event de Prototype.js van a reconocer este concepto; solo hay una diferencia de sintaxis. notar que el nombre del evento que le des ("click" o "mouseover") no tiene el prefijo "on".&lt;br /&gt;Este párrafo se usa en el ejemplo siguiente&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('addEventExample').addEvent('click', function() {&lt;br /&gt;       alert('click!');&lt;br /&gt;   });&lt;br /&gt;&lt;/div&gt; &lt;br /&gt;Porque usar esto en ves de hacer $('addEventExample').onclick = alert('click');? Bueno, usar capturadores de eventos como este te permite tener mas de uno. si haces .onclick=myFunction podes tener solo un evento esperando ese click. Click puede no ser un gran ejemplo, pero ciertamente algo como window.onload vas a querer tener numerosos eventos monitoreando. &lt;br /&gt;También podes usar Element.removeEvent() para remover un capturador de evento&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Element.getNext, getPrevious, getLast&lt;/span&gt;&lt;br /&gt;Todos ellos obtiene elementos vecinos relativos al que apliques este método.&lt;br /&gt;Este es el HTML del ejemplo siguiente:&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   HTML:&lt;br /&gt;   &amp;lt;ul id="getSiblingExamples"&amp;gt;&lt;br /&gt;       &amp;lt;li id="firstLI"&amp;gt;first&amp;lt;/li&amp;gt;&lt;br /&gt;       &amp;lt;li id="secondLI"&amp;gt;second&amp;lt;/li&amp;gt;&lt;br /&gt;       &amp;lt;li id="thirdLI"&amp;gt;third&amp;lt;/li&amp;gt;&lt;br /&gt;   &amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;       * first&lt;br /&gt;       * second&lt;br /&gt;       * third&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('secondLI').getPrevious() //obtiene el primer elemento de la lista&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $('secondLI').getNext() //obtiene el tercer elemento&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   $('getSiblingExamples').getLast() //obtiene el tercer elemento&lt;br /&gt;&lt;/div&gt;  &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;$Element(DOMelement, function, arguments) - funciones ayuda.&lt;/span&gt;&lt;br /&gt;Aplica un método con el pasda en argumentos para el pasado en elemento. Útil si no querés extender el elemento.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;   JavaScript:&lt;br /&gt;   $Element(el, 'hasClass', className) //Verdadero o falso&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-1700340463137652188?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/1700340463137652188/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=1700340463137652188' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/1700340463137652188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/1700340463137652188'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2007/01/mootools-introduccintutorial-native.html' title='Mootools Introducción/Tutorial - Native'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-1255038183551133983</id><published>2007-01-11T11:12:00.000-03:00</published><updated>2007-01-11T17:41:45.737-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mootools'/><title type='text'>Mootools Introducción/Tutorial - moo.js</title><content type='html'>El artículo original en inglés se encuentra &lt;a href="http://clientside.cnet.com/examples/mootools-primer/"&gt;acá&lt;/a&gt;, y esta es una traducción libre, de aficionado, con los fines de practicar ingles y aprender mootools...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Lo que sigue es un tutorial instructivo de la librería &lt;a href="http://mootools.net/"&gt;mootools&lt;/a&gt;. La mayoría del código de los ejemplos de código te permitirán ejecutarlos haciendo click en el link "ejecuta este código" que está abajo del ejemplo. Haciendo click ahí te mostrará el código y el resultado en el plugin Firebug debugging  de Firefox. Vas a necesitar tener instalado ese plugin ver algún resultado de la mayoría de los ejemplos de código.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Nota: Este ejemplo parece que solo funciona en Firefox por el momento; Lo voy a arreglar pronto.&lt;/span&gt;&lt;h1&gt;Creación de clases&lt;/h1&gt;&lt;a href="http://docs.mootools.net/files/Moo-js.html"&gt;Acá esta la página de documentación de moo.js&lt;/a&gt;&lt;br /&gt;Mootools contiene un sistema de creación de Clases y herencias robusto. Crear una nueva clase es, de hecho, muy fácil.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Clases vs funciones&lt;/span&gt;&lt;br /&gt;Las clases te permiten:&lt;br /&gt;-reutilizar y modificar código sin romper cosas que dependan de él.&lt;br /&gt;-Crear un objeto autómata/independiente/dinámico (statefull) que pueda guardar información en su propio alcance.&lt;br /&gt;-Crear aplicaciones más robustas a través del desarrollo de clases pequeñas, reutilizables y extendibles.&lt;br /&gt;Las funciones autónomas te permiten:&lt;br /&gt;-Crear colecciones de ejecuciones que deban ocurrir juntas&lt;br /&gt;-Crear atajos a otras funciones que tengan una sintaxis larga&lt;br /&gt;-Ejecutar algo, de hecho.&lt;br /&gt;Las funciones son usadas moderadamente con mootools porque las clases son mucho mas poderosas. Si empiezas con una clase y tratas de mantener las cosas genéricas, y piensas en lo que escribes para que sea reutilizable, te vas a encontrar luego extendiendo algo que ya habías escrito y ahorrando un montón de tiempo y creando una solución mas robusta para tus problemas. Otros podrán utilizarla también.&lt;br /&gt;El mismo Mootools es un gran ejemplo de como usar clases te permite crear aplicaciones complejas con menos código. El fundamento o base de mootools es el objeto clase. Casi toda otra parte de javascript en la librería extiende este objeto para crear funcionalidades mas complejas.&lt;br /&gt;Una clase simple&lt;br /&gt;Acá hay un una clase simple usando la sintaxis de mootools:&lt;br /&gt;&lt;div class="simple_box"&gt;Javascript:&lt;br /&gt;var Animal= new class ({&lt;br /&gt;  initialize: function(options){&lt;br /&gt;this.options=options;&lt;br /&gt;}&lt;br /&gt;});&lt;/div&gt;Animal ahora es una clase base sin funcionalidad concreta. Podemos extenderla, algo que vamos a hacer en la próxima sección. La sección "inicial" va a ser ejecutada cuando un nuevo objeto animal es instanciado, y los argumentos pasados al constructor van a ser guardados como ".options" del nuevo objeto, como esto:&lt;br /&gt;&lt;div class="simple_box"&gt;Javascript:&lt;br /&gt;var Gato = new animal({color: "negro"});&lt;/div&gt;Arriba tenemos una instancia de la clase Animal y establecimos el color de este Animal a "negro"&lt;br /&gt;&lt;div class="simple_box"&gt;Javascript:&lt;br /&gt;alert(Gato.options.color); //-&gt; Muestra "Negro"&lt;br /&gt;&lt;/div&gt;Esto por si mismo no es muy interesante, pero cuando empezás a crear clases que heredas una de la otra, o a implementar funcionalidades en la clase base, vas a ver la potencia que tiene.&lt;br /&gt;La cosa que es ilustrada acá es lo autómata/independiente/dinámico del objeto - la parte "this.options". Ahora este objeto puede recordar su estado sin tener que declarar un grupo de variables globales en la parte superior de tu documento solo para guardar información.&lt;br /&gt;&lt;h1&gt;Agregar funciones a una clase&lt;/h1&gt;Las clases pueden contener funciones dentro de ellas de la misma manera que pueden contener variables (como "this.options"). Ejemplo:&lt;br /&gt;&lt;div class="simple_box"&gt;Javascript:&lt;br /&gt;var Animal = new Class({&lt;br /&gt;initialize: function(options){&lt;br /&gt;   this.options = options; //Guarda tus opciones&lt;br /&gt;   //si las opciones especifican que Animal&lt;br /&gt;   //esta dormido cuando lo crean, llama dormir()&lt;br /&gt;   if(this.options.dormirAlInicio) this.dormir();&lt;br /&gt;   //sino está despierto&lt;br /&gt;   else this.depertar();&lt;br /&gt;},&lt;br /&gt;dormir: function() {&lt;br /&gt;   this.estaDormido= true;&lt;br /&gt;},&lt;br /&gt;despertar: function(){&lt;br /&gt;   this.estaDormido = false;&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;&lt;/div&gt;Ahora podemos instanciar nuestro animal y mandarlo a dormir o a despertarlo cuando queramos.&lt;br /&gt;&lt;div class="simple_box"&gt;Javascript:&lt;br /&gt;var Gato = new Animal({&lt;br /&gt;color: "Negro",&lt;br /&gt;dormidoAlInicio: true&lt;br /&gt;});&lt;br /&gt;//el gatito esta dormido, vamos a despertarlo&lt;br /&gt;Gato.despertar();&lt;br /&gt;alert(Gato.estaDormido);&lt;br /&gt;//-&gt; alerts "falso"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h1&gt;Extender las clases&lt;/h1&gt;Las clases pueden ser extendidas para crear funcionalidades mas complejas. En los ejemplos anteriores hemos creado un objeto (Animal) y una instancia de ese objeto (Gato), pero extendiendo la clase base podemos crear funcionalidades mas complejas mientras reutilizamos nuestro código. Ejemplo:&lt;br /&gt;&lt;div class="simple_box"&gt;JavaScript:&lt;br /&gt;var Animal = new Class({&lt;br /&gt;initialize: function(options){&lt;br /&gt;    this.options = options;&lt;br /&gt;    this.estaVivo= true;&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;var Mamifero = Animal.extend({&lt;br /&gt;initialize: function(options){&lt;br /&gt;    //esto ejecuta la función initialize() en la clase animal&lt;br /&gt;    //Vamos a pasar las opciones a la función initialize del padre&lt;br /&gt;    this.parent(options);&lt;br /&gt;  this.esSangreCaliente = true;&lt;br /&gt;    this.tienePelaje = true;&lt;br /&gt;    this.produceLeche = true;&lt;br /&gt;},&lt;br /&gt;dormir: function() {&lt;br /&gt;    this.estaDormido = true;&lt;br /&gt;},&lt;br /&gt;despertar: function(){&lt;br /&gt;    this.estaDormido= false;&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;var Raton = Mamifero.extend();&lt;br /&gt;var Gato = Mamifero.extend({&lt;br /&gt;initialize: function(options) {&lt;br /&gt;    //llama initialize de Mamifero&lt;br /&gt;    //traspasa todas las opciones a&lt;br /&gt;    //las clases Mamifero y animal&lt;br /&gt;    this.parent(options)&lt;br /&gt;    this.tieneGarras = true;&lt;br /&gt;    this.tieneCola = true;&lt;br /&gt;    this.esCarnivoro = true;&lt;br /&gt;},&lt;br /&gt;casaRaton: function(Raton){&lt;br /&gt;    Raton.estaVivo = false;&lt;br /&gt;    return Raton;&lt;br /&gt;}&lt;br /&gt;});&lt;/div&gt;Bien, ahora tenemos una clase Animal, una clase Mamifero (que extiende de Animal) y las clases Gato y Raton (que extienden de Mamifero). El código anterior crea las clases pero no ejecuta nada realmente. Entonces, pongamos este código en uso:&lt;br /&gt;&lt;div class="simple_box"&gt;JavaScript:&lt;br /&gt;var Kitty = new Gato({&lt;br /&gt;color: "Negro"&lt;br /&gt;});&lt;br /&gt;var Mickey = new Raton({&lt;br /&gt;color: "Negro",&lt;br /&gt;Pantalones: true,&lt;br /&gt;zapatos: true&lt;br /&gt;});&lt;br /&gt;Kitty.casaRaton(Mickey);&lt;br /&gt;alert(Mickey.estaVivo);&lt;br /&gt;//-&gt;falso&lt;br /&gt;&lt;/div&gt;Separando las cosas en clases de esta manera, en cualquier momento del futuro podemos implementar nuevos tipos de Animales, Mamiferos o tambien diferentes tipos de gatos y ratones. Significa tambien que si encontramos un error, por ejemplo, en la clase Mamifero, arreglarlo en ese lugar implica que no vamos a tener que arreglarlo en todas la instancias de Mamifero.&lt;br /&gt;&lt;h1&gt;Implementar Clases&lt;/h1&gt;Extender clases te permite tomar una clase base (como Animal mas arriba) y crear una nueva clase con esa como plantilla (como en nuestra clase Mamifero arriba). Esto no altera la clase animal de ninguna manera.&lt;br /&gt;Esto no es siempre lo que buscamos, sin embargo. A veces queres alterar la clase padre en un contexto dado. Digamos, por ejemplo, que estas usando la clase Animal de arriba, pero querés agregarle una función para tu ambiente. Extender la clase Animal para crear algo como AnimalExtended no te sirve por que vas a usar tambien Gato, Raton y Mamifero y no querés reescribirlas.&lt;br /&gt;Aca es donde Class.implement resulta útil. El método implement te permite agregar funcionalidad a la clase, alterando la clase misma. No podes usar la funcion "this.parent()" como si puedes con la extensión, por que no estás creando un hijo - estas modificando la clase. Adicionalmente, si usas el mismo nombre separado como uno que ya exista, lo vas a sobreescribir. Ejemplo:&lt;br /&gt;&lt;div class="simple_box"&gt;JavaScript:&lt;br /&gt;//esta es la misma clase Animal de antes&lt;br /&gt;var Animal = new Class({&lt;br /&gt; initialize: function(options){&lt;br /&gt;     this.options = options;&lt;br /&gt;     this.estaVivo= true;&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;//Vamos a cambiarla para agregarle algunas funcionalidades adicionales&lt;br /&gt;Animal.implement({&lt;br /&gt; comer: function() {&lt;br /&gt;     if(typeof this.energia == "indefinido") this.energia = 0;&lt;br /&gt;     this.energia++;&lt;br /&gt; }&lt;br /&gt;});&lt;/div&gt;&lt;br /&gt;Ahora Animal tiene una función llamada comer() que incrementa su valor de energía.&lt;br /&gt;Vamos a decir que luego queremos agregar la habilidad de pasas un valor inicial en options y queremos implementarlo en la clase tambien. Usando implement, si queremos alterar la función comer, vamos a tener que escribirlo todo de nuevo:&lt;br /&gt;&lt;div class="simple_box"&gt;JavaScript:&lt;br /&gt;//let's let you pass in a starting value&lt;br /&gt;Animal.implement({&lt;br /&gt; comer: function() {&lt;br /&gt;     if(typeof this.energia == "indefinido") {&lt;br /&gt;          if(typeof this.options.iniciarEnergia != "indefinido") this.energia = this.options.iniciarEnergia ;&lt;br /&gt;          else this.energia = 0;&lt;br /&gt;     this.energia++;&lt;br /&gt; }&lt;br /&gt;});&lt;/div&gt;Implement es usado en Mootools mayormente para extender clases que están en el grupo "Nativo" - específicamente String, Array, Function y Element prototype. Esto significa que si tiene este código:&lt;br /&gt;&lt;div class="simple_box"&gt;JavaScript:&lt;br /&gt;String.implement({&lt;br /&gt; alert: function() {&lt;br /&gt;     alert(this);&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/div&gt;Cualquier string va a heredar esa función:&lt;br /&gt;&lt;div class="simple_box"&gt;JavaScript:&lt;br /&gt;"hey howdy!".alert();&lt;br /&gt;&lt;/div&gt;De esta manera, Mootools te da un montón de atajos para cosas que a menudo haces a cosas como Strings, Arrays, etc.&lt;br /&gt;Hay otra manera de usar implement que es bastante útil. Podes crear una clase y luego implementarla en otra, tal cual:&lt;br /&gt;&lt;div class="simple_box"&gt;JavaScript:&lt;br /&gt;//Estas son las misma clases Mamifero y Gato de arriba&lt;br /&gt;var Gato = Mamifero.extend({&lt;br /&gt; initialize: function() {&lt;br /&gt;     this.parent() //llama initialize de Mamifero&lt;br /&gt;     this.tieneGarras = true;&lt;br /&gt;     this.tieneCola = true;&lt;br /&gt;     this.isCarnivoro = true;&lt;br /&gt; },&lt;br /&gt; function: casaRaton(Raton){&lt;br /&gt;     raton.estaVivo = false;&lt;br /&gt;     return raton;&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;var Carnivoro= new Class({&lt;br /&gt;     esCarnivoro = true,&lt;br /&gt;     energia = 0,&lt;br /&gt;     comer: function() {&lt;br /&gt;         this.energy++;&lt;br /&gt;     }&lt;br /&gt;});&lt;br /&gt;Gato.implement(Carnivoro);&lt;/div&gt;Ahora todos los Gatos que crees, van a tene la funcionalidad definida en Carnivoro. Esto te permite crear porciones de código mas pequeñas que puedan ser agregados donde se necesiten.&lt;br /&gt;&lt;h1&gt;Extender Objetos&lt;/h1&gt;Tal como en las clases, los objetos pueden ser extendidos. Esto permite combinar dos objetos juntos en la misma manera que los objetos Clase. Para se especifico, las propiedades de un objeto puede ser copiada en otro, tal como Class.implement() Ejemplo:&lt;br /&gt;&lt;div class="simple_box"&gt;JavaScript:&lt;br /&gt;var Ciudad= {&lt;br /&gt; tieneEdificios: true,&lt;br /&gt; tieneTrafico: true&lt;br /&gt;};&lt;br /&gt;var SanFrancisco = Object.extend(Ciudad, {&lt;br /&gt; tieneNiebla: true,&lt;br /&gt; numeroDeEdificios: 1000,&lt;br /&gt; Terremoto: function() {&lt;br /&gt;     this.numeroDeEdificios= this.numeroDeEdificios/2;&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;SanFrancisco.terremoto(); //espero que tengas seguro!!!&lt;br /&gt;&lt;/div&gt;Esto es muy similar a las clases pero no tenés la función initialize() que es ejecutada cuando creas algo y hay otras diferencias en las que no quiero profundizar.&lt;br /&gt;Un gran ejemplo de cómo y porqué  extender un objeto puede encontrarse en este articulo sobre &lt;a href="http://clientside.cnet.com/best-practices/thisoptions-setting-defaults-that-can-be-overwritten-in-your-classes/"&gt;this.options - valores por defecto establecidas que pueden ser sobreescritos en tus clases.&lt;/a&gt;&lt;br /&gt;&lt;h1&gt;Object.Native&lt;/h1&gt;Object.Native() solamente toma un objeto y hace que su función .extend() haga lo mismo que la función .implement(). Realmente es usado para crear clases prototipo extensibles como String, Array, etc. Ejecutando Object.Native(String) estableces tu ambiente para que te permita extender la funcionalidad básica de Strings. No necesitas usarlo realmente, pero es útil si querés forzar alguna extensión de una clase para modificar tambien la clase base.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-1255038183551133983?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/1255038183551133983/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=1255038183551133983' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/1255038183551133983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/1255038183551133983'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2007/01/mootools-introduccintutorial-moojs.html' title='Mootools Introducción/Tutorial - moo.js'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-115532669905151288</id><published>2006-08-11T17:02:00.000-03:00</published><updated>2006-11-14T15:25:35.894-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XXIII</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Dominar Ajax, Parte 5: Manipular el DOM&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Usar JavaScript para actualizar tu página web al vuelo. &lt;/span&gt;&lt;br /&gt;Nivel: Introductorio&lt;br /&gt;&lt;br /&gt;Brett McLaughlin (&lt;a href="mailto:brett@oreilly.com" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;     brett@oreilly.com&lt;/a&gt;), Autor y Editor, O´Reilly y Asociados.&lt;br /&gt;11 Abril 2006&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;El mes pasado Brett introdujo el Modelo de Objetos de Documento, cuyos elementos trabajan detrás de escena para definir tu página Web. Este mes se sumerge todavía más profundo en el DOM. Aprender como crear, eliminar y cargar las partes de un árbol DOM, y dar el próximo paso para actualizar tus páginas Web al vuelo&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Si seguiste mi discución de esta serie del mes pasado, tenes una visión de que sucede cuando un navegador Web muestra una de tus páginas. Como expliqué antes, cuando el HTML y el CSS que hayas definido para tu página es enviado a un navegador Web, es traducido desde texto a un modelo de objeto. Esto es cierto, así sea el código simple o complejo, contenido todo en un archivo o en archivos separados. El navegador trabajara entonces directamente con el modelo de objeto, más que con los archivos de texto que le entregaste. El modelo que el navegador usa se llama El Modelo de Objeto de Documento. Este conecta los objetos representando los elementos, atributos y texto en tus documentos. Todos los estilos, valores y más que nada los espacios en tu HTML y CSS son incorporados en el modelo de objetos. El modelo especifico para una página Web dada se llama "Arbol DOM" de la página.&lt;br /&gt;Entender que es un árbol DOM, y mas conocer como representa tu HTML y CSS, es solo el primer paso para tomal el control de tus páginas Web. Después tenés que aprender como trabajar con el árbol DOM para una página Web particular. Por ejemplo, si agregas un elemento al árbol DOM, ese elemento inmediatamente  aparece en el navegador Web del usuario--sin que se recargue la página. Eliminas algo de texto del árbol DOM y ese texto desaparece de la pantalla del usuario. Podes cambiar e interactuar con la interface del usuario a traves del DOM, que te da un tremendo poder y flexibilidad de programación. Una vez que aprendas como trabajar con un árbol DOM habrás hecho un gran salto hacia dominar ricos, interactivos y dinámicas páginas Web.&lt;br /&gt;Observar que la siguiente discusión está basada en "Explotar el DOM para una respuesta Web" del mes pasado; si no has leido ese artículo, puede ser que prefieras hacerlo antes de seguir con esto.&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-weight: bold;"&gt;    Importancia de la pronunciación del acrónimo.&lt;/span&gt;&lt;br /&gt;De todas formas, el modelo de objeto de documento, se habría podido llamar Modelo de Nodos de documentos. Por supuesto , la mayoría de la gente no sabe que significa el término nodo, y DNM no es tan fácil de pronunciar como DOM, por eso es fácil entender porque el W3C siguió con DOM.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cruce de navegadores, cruce de lenguajes.&lt;/span&gt;&lt;br /&gt;El modelo de objeto de doumento es un estandar de la W3C (ver Recursos por links a la W3C). Por esto, todos los navegadores Web modernos soportan DOM, al menos en algun grado. Si bien hay algunas variaciones entre navegadores, si usas la funcionalidad basica de DOM --y pones atencion a algunos casos especiales y excepciones-- tu código DOM va a trabajar en cualquier navegador de la misma manera. El código que escribas para modificar una pagina Web en Opera va a trabajar en el Safari de Apple, en Firefox, en Microsoft Internet Explorer y Mozilla.&lt;br /&gt;El DOM es también una especificación de cruce de lenguajes; en otras palabras, podes usarlo desde la mayoria de los lenguajes de programación más populares. La W3C define varios vinculos de lenguaje para el DOM. Por ejemplo, podes encontrar vínculos de lenguaje para DOM bien definido para C, Java y JavaScript. Por esto podes usar DOM con cualquiera de esos lenguajes. Los vinculos de lenguaje estan disponibles también para muchos otros lenguajes, aunque muchos de estos no estan definidos por la W3C, sino en su lugar por terceros.&lt;br /&gt;En esta serie me voy a enfocar en los vínculos de JavaScript en el DOM. Esto tiene sentido por que la mayoría de los desarrollos de aplicaciones asincronicas estan basados en escribir código JavaScript para ejecutar en un navegador Web. Con JavaScript y DOM, podes modificar la interfase del usuario al vuelo, responder a los eventos de los usuarios y a las entradas, y más --todo usando JavaScript bastante estandarizado.&lt;br /&gt;Todo lo dicho, te animo a que revises los vinculos de lenguaje para DOM en otros lenguajes. Por ejemplo, podes usar los vinculos del lenguaje Java no solo para trabajar con HTML, sino tambien con XML, como voy a analizar en un artículo más tarde. Entonces las lecciones que aprenderas acá se aplican mucho mas que en HTML, en muchos mas ambientes que solo el lado cliente JavaScript.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;El nodo conceptual&lt;/span&gt;&lt;br /&gt;Un nodo es mas que un tipo de objeto básico en el DOM. De hecho, como verás en este artículo, casi todo otro objeto definido por DOM extiende el objeto del nodo. Pero, antes de que llegues muy lejos en la semantica, necesitas entender el concepto que se representa con un nodo; luegopara aprender las propiedades reales y metodos de un nodo es un pabada.&lt;br /&gt;En un árbol DOM, casi todo lo que vas a encontrar es un nodo. Todo elemento es en su nivel más básico un nodo en el árbol DOM. Todo atributo es un nodo. Todo fragmento de texto es un nodo. Hasta los comentarios, caracxteres especiales (como ©, que representa eun simbolo de copyright), la declaracion DOCTYPE (si tenes una en tu HTML o XHTML) son todos nodos. Entonces antes de meterme en lo especifico de cada uno de esos typos individuales, realmente necesitas concer que es un nodod.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Un nodo es...&lt;/span&gt;&lt;br /&gt;En términos simples, un nodo es solo una unica cosa en el arbol DOM. Lo vago de "cosa" es intencional, porque asíe s de especifico como puede ser. Por ejemplo, probablemente no es obvio que un elemento en tu HTML, como img, y un fragmento de texto en HTML, como "Bajar para más detalles" tengan mucho en comun. Pero eso es porque probablemente estes pensando en la función de esos tipos individuales, y enfocando en cuan diferentes son.&lt;br /&gt;Considera, en su lugar, que cada elemento y fragmento de texto en un árbol DOM tiene un padre; ese padre es tambien el hijo de otro elemento (como cuando una imagen es anidada dentro de un elemento p) o es el primer elemento en el árbol DOM (que es un caso espaciel único para cada documento, y es donde se usa el elemento HTML). Considerar tambien que que ambos, elementos y texto, tienen un tipo. El tipo de un elemento es obviamente un elemento; el tipo de texto es texto. Cada nodo tiene tambien una estructura bastante bien definida para eso: Tiene un nodo (o nodos) debaajo de él, como elementos hijos? Tiene nodos hermanos  (nodos "al lado de" el elemento o texto)? A que documento pertenece cada nodo?&lt;br /&gt;Obviamente, mucho de esto suena bastante abstracto. De hecho, puede parecer tonto decir que el tipo de un elemento es... bueno... un elemento. Sin embargo, necesitas pensar un poco abstractamente para darte cuenta el valor de tener el nodo como un tipo de objeto común.&lt;br /&gt;El tipo de nodo comun&lt;br /&gt;La tarea simple que vas a realizar mas que ninguna otra en tu código DOM es navegar dentro de el árbol DOM de una página. Por ejemplo, podrías localizar un formulario por su atributo, y luego empezar a trabajar con el elemento y texto anidado en ese formulario. Van a haber intrucciones textuales, etiquetas para campos de entrada, elementos de ingreso reales, y pasiblemente otro tipo de elementos HTML como elementos img y links (un elemento). Si elementos y texto son tipos completamente diferentes, entonces tenés que escribir piesas de código completamente diferentes para mover desde un tipo a otro.&lt;br /&gt;Las cosas son diferentes si usas un tipo de nodo comun. En ese caso podes simplemente moverte de nodo a nodo y preocuparte sobre el tipo solo cuando querés hacer algo específico con un elemento o texto. Mientras solo te muevas en el árbol DOM, vas a usar las mismas operaciones para moverte al padre del elemento --o a sus hijos-- como lo harias con cualquier tipo de nodo. Solo vas a tener que trabajar específicamente con un tipo de nodo, como un elemento o texto, cuando necesitás algo específico de determinado tipo de nodo, como un atributo de un elemento. Pensar en cada elemento del árbol DOM simplemente como un nodo te permite operar mucho mas sencillamente. Con eso en mente, voy a ver exactamente que tiene que ofrecer la construcción Nodo de DOM, empezando con propiedades y métodos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-115532669905151288?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/115532669905151288/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=115532669905151288' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/115532669905151288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/115532669905151288'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/08/traduccin-de-artculo-de-ajax-xxiii.html' title='Traducción de Artículo de Ajax XXIII'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-115202929855014627</id><published>2006-07-04T13:08:00.000-03:00</published><updated>2006-11-14T15:25:35.790-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de artículo de Ajax XXII</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Introducir el DOM&lt;/span&gt;&lt;br /&gt;Hasta ahora has escuchado que los navegadores transforman una página Web a una representación de objeto y tal vez también hayas adivinado que la representación de Objeto es un árbol DOM. DOM sustituye a Modelo de Objeto de Documento y es una especificación disponible para la World Wide Web Consortium (W3C) ( podes ver varios links relacionados con DOM en los recursos)&lt;br /&gt;Más importante todavía, el DOM define los tipos de objeto y propiedades que permiten al navegador representar el markup (El próximo artículo de esta serie se focaliza en las especificaciones de uso de DOM para tu JavaScript y código Ajax).&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;El Objeto documento&lt;/span&gt;&lt;br /&gt;Primero y principal, vas a necesitar acceder al modelo de objeto en si mismo. Esto es extraordinariamente fácil; para usar la variable incorporada &lt;span style="font-style: italic;"&gt;document&lt;/span&gt;   en cualquier parte del código JavaScript funcionando en tu página Web, podes escribir código como este:&lt;br /&gt;&lt;blockquote&gt;var domTree = document;&lt;/blockquote&gt;&lt;br /&gt;Por supuesto, este código es bastante inútil de por si, pero demuestra que todo navegador Web pone a disposición el objeto &lt;span style="font-style: italic;"&gt;document &lt;/span&gt;para el código JavaScript y que el objeto representa el árbol completo del markup (figura 1).&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Todo es un nodo&lt;/span&gt;&lt;br /&gt;Claramente, el objeto &lt;span style="font-style: italic;"&gt;document &lt;/span&gt;es importante, pero solo es el comienzo. Antes de que puedas ir más lejos, necesitas aprender otro término: nodo. Ya sabés que cada parte del markup es representada por un objeto, pero es más que cualquier objeto -- es un tipo de objeto especifico, un nodo DOM. Los tipos más específicos --como texto, elemento y atributos--  son extensiones del este tipo de nodo básico. Así que tenés nodos de texto, nodos de elementos y nodos de atributos.&lt;br /&gt;Si has programado mucho en JavaScript, debería ocurrirte que ya has usado código DOM. Si seguiste esta serie de Ajax hasta este momento, definitivamente has usado código DOM en algún momento ahora.  Por ejemplo, la línea  &lt;span style="font-style: italic;"&gt;var number = document.getElementById("phone").value;&lt;/span&gt;   usa DOM para encontrar un elemento especifico y devolver el valor de ese elemento (en este caso, un campo de formulario). Aunque no te hayas dado cuenta, usaste DOM cada vez que escribiste  &lt;span style="font-style: italic;"&gt;document &lt;/span&gt;en tu código JavaScript.&lt;br /&gt;Para refinar los términos que ya has aprendido, un árbol DOM en un árbol de objetos, pero más específicamente en un árbol de objetos nodo. En aplicaciones Ajax --o cualquier otro JavaScript-- podés trabajar con esos nodos para crear efectos tales como remover un elemento y su contenido, resaltar  una parte del texto o agregar un nuevo elemento de imagen. Como todo esto ocurre en el lado cliente (código que se ejecuta en tu navegador Web), estos efectos tiene lugar inmediatamente sin comunicación con el servidor. El resultado final es una aplicación que se siente que responde bien por que las cosas en la página Web cambian sin largas pausas mientras que una petición va al servidor en una respuesta es interpretada.&lt;br /&gt;En la mayoría de los lenguajes de programación, necesitas aprender el nombre de objeto real para cada tipo de nodo, aprender las propiedades disponibles y comprender sobre tipos y elencos; pero ninguno de estos es necesario en JavaScript. Podes, simplemente crear una variable y asignarla en el objeto que quieras (tal como has visto):&lt;br /&gt;&lt;blockquote&gt;var domTree = document;&lt;br /&gt;var phoneNumberElement = document.getElementById("phone");&lt;br /&gt;var phoneNumber=phoneNumberElement.Value;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;No hay tipos y JavaScript se encarga de crear las variables y asignarles el tipo correcto como sea necesario. Como resultado, se vuelve bastante trivial usar DOM desde JavaScript  (en un artículo próximo nos focalizaremos en DOM relacionado con XML y cosas que son un poco mas difíciles).&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;En Conclusión&lt;/span&gt;&lt;br /&gt;En este punto, te voy a dejar con muchas preguntas sin respuestas. Obviamente, esto no ha sido una cobertura exaustiva del DOM; de hecho este articulo es un poco más que una introducción al DOM. Hay mucho mas DOM del que te he mostrado hoy!&lt;br /&gt;El próximo artículo de esta serie se expande en esas ideas y profundiza mas en como podés usar DOM en tu JavaScript para actualizar páginas Web, hacer cambios al vuelo en tu HTML y crear una experiencia mas interactiva para tu usuario. Voy a volver al DOM una vez mas en los últimos artículos que focalizarán en usar XML en tus peticiones AJAX. Así que familiarizate con el DOM; es la parte principal de las aplicaciones Ajax.&lt;br /&gt;Seria bastante simple lanzar más del DOM en este punto, detallar como moverse dentro de un árbol DOM, obtener los valores de los elementos y el texto, iterar en las listas de nodos, y mas, pero eso probablemente te dejaría con la impresión de que DOM es sobre código --no lo es.&lt;br /&gt;Antes del próximo artículo, trata de pensar sobre estructuras de árbol y trabaja en algunos de tus propios HTML para ver como un navegador Web cambia es HTML a una vista de árbol del markup. También, piensa en la organización del árbol DOM y trabaja en los casos especiales analizados en este artículo: atributos, texto que tiene elementos mezclados dentro de él, elementos que no tiene contenido de texto (como el elemento  &lt;span style="font-style: italic;"&gt;img&lt;/span&gt;).&lt;br /&gt;Si obtenés una comprensión firme de esos conceptos y luego aprendes la sintaxis de JavaScript y de DOM (en el próximo artículo), va a hacer el trabajo de hacer que responda bien, mucho más fácil.&lt;br /&gt;Y no te olvides, acá están las respuestas de los listings 2 y 3 que también están incluidas en el código de muestra.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Figura 2. Respuesta del Listing 2&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro4/tricky-solution.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro4/tricky-solution.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Figura 3. Respuesta del Listing 3&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro4/trickier-solution.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro4/trickier-solution.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-115202929855014627?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/115202929855014627/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=115202929855014627' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/115202929855014627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/115202929855014627'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/07/traduccin-de-artculo-de-ajax-xxii.html' title='Traducción de artículo de Ajax XXII'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-115101043269193996</id><published>2006-06-22T18:07:00.000-03:00</published><updated>2006-11-14T15:25:35.587-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XXI</title><content type='html'>&lt;span style="font-weight: bold;"&gt;El valor de los objetos&lt;/span&gt;&lt;br /&gt;Ahora que tenés alguna terminología básica en tu haber, es hora de enfocar mas en esos pequeños rectángulos con nombres de elementos y texto adentro. (figura 1). Cada rectángulo es un objeto; ahí es donde el navegador resuelve algunos de esos problemas con el texto. Usando objetos para representar cada parte del documento HTML, se vuelve muy fácil cambiar la organización, aplicar estilos, permitir a JavaScript acceder al documento y mucho mas.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Tipos de Objetos y Propiedades &lt;/span&gt;&lt;br /&gt;Cada tipo posible de markup tiene su propio tipo de objeto. Por ejemplo, los elementos en u HTML son representados por un objeto tipo element. El texto en tu documento es representado por un tipo  Text, los atributos son representados por tipos Attribute y así con todos.&lt;br /&gt;Entonces el navegador Web no solo tiene la posibilidad de usar un modelo de objetos para representar tu documento --dejando de lado el hecho de que tiene que tratar con texto estático--sino que también puede decir inmediatamente que es algo por su tipo de objeto. El documento HTML es analizado y convertido en un grupo de objetos como el que viste en la figura 1 y luego cosas como paréntesis angulares y secuencia de escape no son mas un problema. Esto hace que el trabajo de navegador, al menos después de que analiza el HTML de la entrada, mucho más simple. La operación para descubrir si algo es un elemento o un atributo y luego determinar que hacer con ese tipo de objeto es simple.&lt;br /&gt;Usando objetos, el navegador Web puede entonces cambiar las propiedades de esos objetos. Por ejemplo, cada elemento tiene un padre y una lista de hijos. Por eso agregar un nuevo elemento o texto hijo es simplemente un asunto de agregar un nuevo hijo a una lista de hijos de un elemento. Esos objetos tiene también una propiedad style, por esto se vuelve fácil cambiar el estilo de un elemento o parte de texto al vuelo. Por ejemplo, podrías cambiar la altura de un div usando JavaScript como este:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;someDiv.style.height = "300px";&lt;/blockquote&gt;&lt;br /&gt;En otras palabras, los navegadores Web pueden cambiar fácilmente la apariencia y estructura del árbol usando propiedades de objetos como esta. Comparando esto con la calse de cosas complicadas que el navegador tiene que hacer si representa la página como texto internamente; cada cambio de propiedades o estructuras que el navegador reescriba el archivo estático, lo re-analice y lo vuelva a mostrar en la pantalla. Todo esto se vuelve posiblo con objetos.&lt;br /&gt;En este punto, tomate el tiempo  de abrir algunos de tus documentos HTML y esquematizarlos como árbol. Así como este parece ser un pedido bastante inusual --especialmente de un artículo que contiene tan poco código -- vas a necesitar familiarizarte con la estructura de esos arboles si querés poder manipularlos.&lt;br /&gt;En el proceso, probablemente te encuentres con otras rarezas. Por ejemplo, consideremos las siguientes situaciones:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;¿Qué pasa con los atributos?&lt;/li&gt;&lt;li&gt;¿Qué pasa con el texto que es interrumpido por elementos, como em y b? &lt;/li&gt;&lt;li&gt;¿Y qué pasa con el HTML que no esté estructura do correctamente (como cuando falta la etiqueta de cierre p)&lt;/li&gt;&lt;/ul&gt;Una vez familiarizado con estos temas, vas a entender algunas de las próximas mucho mejor.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt; Estricto es algo bueno&lt;/span&gt;&lt;br /&gt;Si intentaste el ejercicio que acábo de mencionarte, probablemente encontraste algunos de los problemas potenciales de una vista de árbol en tu markup (si no hiciste el ejercicio, solo toma mi palabra). De hecho, vas a encontrar muchos de ellos en el listing 1 y en la figura 1, empezando por la manera en que el elemento p se interrumpe. Si le preguntás al típico desarrollador Web cual es el contenido del elemento p, la respuesta más común sería, "Bienvenido a una página realmente aburrida" y si comparás esto con la figura 1, vas a ver que esa respuesta --aunque lógica-- no es totalmente correcta.&lt;br /&gt;Resulta que el elemento p tiene tres objetos hijo diferentes y ninguno contiene todo el texto "Bienvenidos a una página realmente aburrida". Vas a encontrar partes de ese texto, como "Bienvenido a una Pagina Web" y "aburrida", pero todo completo. Para entender esto, recuerda que todo en tu markup tiene que ser convertido en un objeto de algún tipo.&lt;br /&gt;Es más, el orden importa! ¿Podes imaginarte como los usuarios responderían a un navegador Web si este muestra el markup correcto, pero en un orden diferente que el que vos le diste en tu HTML? ¿Los párrafos se intercalan entre títulos y cabeceras, aún cuando así no es como vos organizaste tu propio documento? Obviamente, el navegador debe preservar el orden de los elementos y el texto.&lt;br /&gt;En este caso, el elemento p tiene tres partes distintas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;El texto que va antes del elemento em&lt;/li&gt;&lt;li&gt;El elemento em mismo&lt;/li&gt;&lt;li&gt;El texto que va después del elemento em&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Si mezclas este orden, podrías aplicar el énfasis en una porción errónea del texto. Para mantener todo esto en orden, el elemento p tiene tres objetos hijos en el orden que esas cosas aparecieron en el HTML del Listing 1. Además, el texto enfatizado "realmente" no es un hijo del elemento p, es un hijo del em que es un hijo de p.&lt;br /&gt;Es muy importante para vos entender este concepto. Aun cuando el texto "realmente" se va a ver probablemente junto con el resto del texto del  elemento p,  igual es un hijo directo del elemento em. Puede tener formato diferente del resto del p y puede ser movido independientemente del resto del texto.&lt;br /&gt;Para ayudar a consolidar esto en tu mente, trata de diagramar el HTML de los listings 2 y 3, asegurándote de mantener el texto con su padre correcto (a pesar de como el texto se termine viendo en la pantalla).&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Listing 2. markup con anidación de elementos levemente difícil. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&amp;lt;html&amp;gt;&lt;p&gt;&amp;lt;head&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;lt;title&amp;gt; Este es un poquito difícil&amp;lt;/title&amp;gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt; &amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&lt;p&gt;&amp;lt;h1&amp;gt;Poné&amp;lt;u&amp;gt;mucha&amp;lt;/u&amp;gt; atención, OK?&lt;/p&gt;&lt;p&gt; &lt;/p&gt; &amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;div&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&lt;br /&gt;Este p no es  realmente &amp;lt;em&amp;gt;necesario&amp;lt;/em&amp;gt;, pero hace la  &amp;lt;span id="bold-text"&amp;gt;estructura &amp;lt;i&amp;gt; y &amp;lt;/i&amp;gt;la organización&amp;lt;/span&amp;gt; de la página fácil de mantener&lt;br /&gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;p&gt; &lt;/p&gt; &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Listing 3. Anidación de elementos un poco más difícil. &lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt; Este es un poquito difícil&amp;lt;/title&amp;gt; &amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;div id="main-body"&amp;gt;&lt;br /&gt;&amp;lt;div id="contents"&amp;gt;&lt;br /&gt;&amp;lt;table&amp;gt;&lt;br /&gt;&amp;lt;tr&amp;gt; &amp;lt;th&amp;gt;Pasos &amp;lt;/th&amp;gt; &amp;lt;th&amp;gt;Proceso &amp;lt;/th&amp;gt; &amp;lt;/th&amp;gt;&lt;br /&gt;&amp;lt;tr&amp;gt; &amp;lt;td&amp;gt;1 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Descubre el  &amp;lt;em&amp;gt;elemento raiz&amp;lt;/em&amp;gt;. &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;tr&amp;gt; &amp;lt;td&amp;gt;2 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Trabajar con la &amp;lt;span id="code"&amp;gt;cabecera&amp;lt;/span&amp;gt; primero, es normalmente fácil. &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;tr&amp;gt; &amp;lt;td&amp;gt;3 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Trabajar en el &amp;lt;span id="code"&amp;gt;cuerpo&amp;lt;/span&amp;gt;. Solo &amp;lt;em&amp;gt;tomate tu tiempo &amp;lt;/em&amp;gt;.&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;/table&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div id="closing"&amp;gt;&lt;br /&gt;Este link &amp;lt;em&amp;gt;no&amp;lt;/em&amp;gt; está activado, pero si lo estuviera, las respuestas a esto &amp;lt;a href=" answers.html"&amp;gt;&amp;lt;img="exercise.gif" /&amp;gt;&amp;lt;/a&amp;gt;estarían ahí. Pero &amp;lt;em&amp;gt;hacé el ejercicio igual &amp;lt;/em&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;Vas a encontrar las respuestas de estos ejercicios en los archivos GIF  tricky-solution.gif  en figura 2 y  trickier-solution.gif en figura 3 al final de este artículo. No las mires hasta que hayas tenido el tiempo de resolverlos vos mismo. Te ayudara a entender como aplicar las reglas estrictamente para organizar el árbol y realmente ayudarte en tu búsqueda de dominar HTML y su estructura de árbol.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;¿Qué pasa con los atributos? &lt;/span&gt;&lt;br /&gt;¿Te encontraste con algún problema cuando trataste de descubrir que hacer con los atributos? Como mencioné, los atributos tienen su propio tipo de objeto, pero un atributo nos es realmente un hijo del elemento en donde aparece --elementos anidados y texto no están al mismo nivel de un atributo y vas a notar que las respuestas de los ejercicios en los listings 2 y 3 no tiene atributos mostrados.&lt;br /&gt;Los atributos de hecho son almacenados en el modelo de objeto que usan los navegadores, pero son un caso especial. Cada elemento tiene una lista de atributos disponibles, separado de la lista de objetos hijos. Entonces un elemento div podría tener una lista que contenga un atributo llamado "id" y otro llamado "class".&lt;br /&gt;Ten en mente que los atributos de un elemento deben tener nombres únicos; en otras palabras, un elemento no puede tener dos atributos "id" u dos "class". Esto hace que la lista sea muy fácil de mantener y acceder. Como vas a ver en el próximo artículo, podes simplemente llamar a un método como getAttribute("id") para obtener el valor de un atributo por su nombre. Podes también agregar atributos y establecer ( o poner a cero) el valor de un atributo existente con un llamado a método similar.&lt;br /&gt;También vale la pena precisar que el hecho de que los nombres de los atributos sean únicos hace es ta lista diferente de la lista de objetos hijo. Un elemento p puede tener múltiples elementos em dentro de el. entonces la lista de objetos hijo puede contener ítem duplicados. Si bien la lista de hijos y la lista de atributos operan de manera similar, una puede contener duplicados (los hijos de un objeto)y la otra no (los atributos de un elemento objeto). Finalmente, solo los elementos pueden tener atributos, entonces los objetos de texto no tienen listas asociadas a ellos para almacenar atributos.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;HTML descuidado&lt;/span&gt;&lt;br /&gt;Antes de continuar, un tema nuevo vale la pena un tiempo cuando viene de cómo un navegador convierte el markup en una representación de árbol -- cómo un navegador se encarga del markup que no esta bien armado. Bien armado es en realidad un termino muy usado en XML y significa dos cosas básicas:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Toda etiqueta de apertura tiene una etiqueta de cierre coincidente. Entonces todo &amp;lt;p&amp;gt; se relaciona en el documento con un &amp;lt;/p&amp;gt;, todo &amp;lt;div&amp;gt; con un &amp;lt;/div&amp;gt;, y así sucesivamente.  &lt;/li&gt;&lt;li&gt;La etiqueta de apertura más interior hace juego con la etiqueta de cierre mas interior, luego la siguiente etiqueta de apertura más interior con la siguiente etiqueta de cierre mas interior y así sucesivamente. Por eso &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;negritas e itálicas &amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; sería ilegal porque la etiqueta de apertura  &amp;lt;i&amp;gt; esta incorrectamente relacionada con la etiqueta de cierra más interior &amp;lt;b&amp;gt;. Para armar bien esto, necesitarías cambiar el orden de las etiquetas de apertura u el orden de las etiquetas de cierre. (si se cambian ambas, mantendrías el problema) &lt;/li&gt;&lt;/ul&gt;Estudia estas dos reglas atentamente. Ambas son reglas que no solo aumentan la sencilla organización de un documento, sino que también eliminan la ambigüedad. ¿Debería aplicarse negritas primero y luego itálicas? ¿o al revés? Si parece que este orden y ambigüedad no es un gran problema, recuerda que CSS permite a las reglas que sobrescriban otras reglas para, por ejemplo, la fuente del texto entre elementos b sea distinta de la fuente entre elementos i, el orden en el cual el formato sea aplicado se vuelve muy importante. Por lo tanto, el buen formato de una página HTML entra en juego.&lt;br /&gt;En los casos donde un navegador recibe un documento que no esté bien armado, hace simplemente lo mejor que puede. La estructura de árbol resultante es en el mejor de los casos, una aproximación de lo que el autor original de la pagina previó o peor algo completamente diferente. Si cargaste tu pagina en un navegador y viste algo completamente inesperado, puede ser que hayas visto el resultado de un navegador tratando de adivinar que debería ser tu estructura y haciendo el trabajo mal. Por supuesto, la solución a esto es bastante simple: ¡asegurate de que tus documentos estén bien armados! Si no tenés claro como escribir HTML estandarizado como este, consultá los recursos por ayuda.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-115101043269193996?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/115101043269193996/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=115101043269193996' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/115101043269193996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/115101043269193996'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/06/traduccin-de-artculo-de-ajax-xxi.html' title='Traducción de Artículo de Ajax XXI'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-115022596256324903</id><published>2006-06-13T16:12:00.000-03:00</published><updated>2006-11-14T15:25:35.492-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XX</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Que hace el markup&lt;/span&gt;&lt;br /&gt;Una vez que te des cuenta de que tu markup es realmente sobre organización, podes verlo diferente. Mas que pensar que un  &lt;span style="font-style: italic;"&gt;H1&lt;/span&gt;   hace que el texto se vea mas grande, en color Negro, estilo Negritas, pensá el &lt;span style="font-style: italic;"&gt;H1&lt;/span&gt;   como un heading. Como ve el usuario eso -- y si el usuario usa tu CSS, la suya, o alguna combinación de las dos--es una consideración secundaria. En su lugar, date cuenta de que el markup es realmente sobre proveer este nivel de organización; un p indica que ese texto está en un párrafo, img denota una imagen, div divide un página en secciones y así sucesivamente.&lt;br /&gt;Deberías tener claro también que estilo y comportamiento (gestionadores de eventos y JavaScript) son aplicados a esta organización, después de todo.  El markup tiene que estar en su lugar para operar sobre el o aplicarle estilo.  Entonces, como probablemente tengas CSS en un archivo externo a tu HTML, la organización de tu markup está separada de su estilo, formato y comportamiento.  Así como ciertamente podés cambiar el estilo de un elemento o pieza de texto desde JavaScript, es más interesante cambiar la organización que tu markup presenta.&lt;br /&gt;Mientras que mantengas en la mente que tu markup solo provee organización, o marco, a tu página, estás adelante en el juego. Y un poco mas todavía, vas a ver como el navegador toma esta organización textual y la transforma en algo mucho más interesante --un grupo de objetos, cada uno de los cuales pueden ser cambiados, agregados o borrados.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Las ventajas del markup de texto&lt;/span&gt;&lt;br /&gt;Antes de referirme al navegador Web, vale la pena considerar porqué el texto plano es absolutamente la mejor opción para almacenar tu HTML (para mas de esto, ver algunos  &lt;a href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro4/index.html#additional" target="_blank"&gt;pensamientos adicionales sobre markup&lt;/a&gt;   ). Sin entrar en pro y contra, simplemente resalto que tu HTML es enviado a través de la red a una navegador Web toda vez que la página es vista (poniendo el cache y demás a un lado por motivos de simplicidad). Simplemente no hay  abordaje más eficiente que pasar por texto. Objetos binarios, representaciones gráficas de la página, y partes reorganizadas del markup... todas ellas son mas difícil de enviar a través de la red que archivos de texto plano.&lt;br /&gt;Adicionar a eso el valor que un navegador agregar a la ecuación. Los navegadores de hoy permiten a los usuarios cambiar el tamaño del texto, escalar imágenes, descargar el CSS o JavaScript de una página (en la mayoría de los casos) y mucho más --todo esto imposibilita todo tipo de representación gráfica de la página al navegador. En cambio, el navegador necesita el HTML crudo para poder aplicar cualquier proceso a la página en el navegador más que confiar en al servidor que se encargue de esa tarea. En la misma linea, separar CSS del JavaScript y separar estos del markup HTML requiere un formato que se fácil de, bueno, separar. Archivos de texto otra vez son una manera genial de hacer esto.&lt;br /&gt;Por ultimo, pero no menos importante, recuerda que la promesa de los nuevos estándares como HTML 4.01 y XHTML 1.0 y 1.1 separan contenido (la información en tu página) de presentación y estilo (normalmente aplicado con CSS). Para los programadores separar si HTML de sus CSS, luego forzar a un navegador a devolver alguna representación de una página que una todo eso junto, frustra muchas de las ventajas de esos estándares. Mantener esas partes dispares separadas hasta el navegador le permite mayor flexibilidad al obtener el HTML del servidor.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Algunos pensamientos adicionales sobre markup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Editar texto plano:¿bien o mal?&lt;/span&gt;&lt;br /&gt;Los archivos de texto plano son ideales para guardar markup, pero eso no es así para editar el markup. Es perfectamente aceptable el uso de un IDE como Macromedia DreamWeaver --o el un tanto mas intrusivo Microsoft Front Page-- para trabajar en el markup de la página. Esos ambientes a menudo ofrecen atajos y ayuda al crear páginas Web, especialmente cuando estas usando CSS y JavaScript, cada uno de un archivo externo a un markup de pagina real. Muchos todavía prefieren el viejo y querido Notepad o Vi (lo confieso yo soy uno de ellos) y es una gran opción también. En todo caso, el resultado final es un archivo de texto lleno de markup.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Texto sobre la red: algo bueno. &lt;/span&gt;&lt;br /&gt;Como ya se mencionó, el texto es un gran medio para un documento --como HTML o CSS-- que es transferido por la red cientos y miles de veces. Cuando digo que el navegador tiene un tiempo difícil representando el texto, significa específicamente transformar el texto en un página gráfica que los usuarios ven. Esto no tiene relación con como el navegador realmente recupera una página del servidor Web; en ese caso, el texto es todavía más la mejor opción.&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt; Una mirada mas profunda a los navegadores Web &lt;/span&gt;&lt;br /&gt;Para algunos de ustedes, todo lo que han leído hasta ahora puede ser una revisión divertida de tu rol en el proceso del desarrollo Web. Pero en lo que concierne a que hace el navegador Web, muchos de los diseñadores y desarrolladores Web mas listos a menudo no se dan cuenta de que pasa realmente "abajo del capot". Me focalizaré en eso en esta sección. Y no te preocupes, el código vendrá pronto, pero aguanta tu impaciencia de codificar por que entender exactamente que hace un navegador Web es esencial para que trabajes en tu código correctamente&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Las desventajas del markup de texto &lt;/span&gt;&lt;br /&gt;Justamente como texto el markup tiene ventajas fabulosas para un diseñador o un creador de páginas, también tiene desventajas un tanto significativas para el navegador. Específicamente, los navegadores tienen un tiempo muy difícil en cuanto a representar markup de texto visualmente para el usuario (para mas de esto, ver algunos &lt;a href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro4/index.html#additional" target="_blank"&gt;pensamientos adicionales sobre markup&lt;/a&gt;)Considerar estas tareas frecuentes del navegador:&lt;ul&gt;&lt;li&gt;Aplicar estilos CSS --frecuentemente de múltiples hojas de estilo en archivos externos--  para un markup basado en el tipo de elementos, sus clases, sus ids y sus posiciones en el documento HTML. &lt;/li&gt;&lt;li&gt;Aplicar los estilos y formatos basados en código JavaScript --también frecuentemente en archivos externos-- a partes diferentes del documento HTML. &lt;/li&gt; &lt;li&gt;Cambiar el valor de los campos de formulario basado en el código JavaScript&lt;/li&gt;&lt;li&gt;Dar soporte a efectos visuales como rollover e intercambio de imágenes en código JavaScript.&lt;/li&gt;&lt;/ul&gt;La complejidad no está en codificar esas tareas; es bastante fácil hacer cada una de esas cosas. La complejidad viene desde el navegador realmente, llevando a cabo la acción solicitada. Si el markup es almacenada como texto y, por ejemplo, querés centrar el texto (text-align: center) de un elemento p en la clase center-text,¿como lográs esto? &lt;ul&gt;&lt;li&gt;¿Agregás estilo en la linea del texto?&lt;/li&gt;&lt;li&gt;¿Aplicás el estilo al texto HTML en el navegador y solo continuas con cual contenido centrar o no centrar?&lt;/li&gt;&lt;li&gt;¿Aplicás HTML sin estilo y luego aplicas el formato? &lt;/li&gt;&lt;/ul&gt;Estas tan difíciles preguntas son porqué pocas personas codifican navegadores estos días. (Esos quienes deberían recibir un caluroso agradecimiento)&lt;br /&gt;Claramente, texto plano no es una gran manera de guardar HTML para el navegador aun cuando el texto fuera una buena solución para obtener el markup de una página en primer lugar. Sumale a esto la habilidad de JavaScript de cambiar la estructura de una página y las cosas se vuelven realmente difíciles. ¿Debería el navegador reescribir la estructura modificada al disco? ¿Como puede actualizar con cual es la etapa actual del documento?&lt;br /&gt;Claramente, texto no es la respuesta. Es difícil de modificar, torpe para aplicar estilos y comportamiento y lleva en última instancia poca semejanza a la naturaleza dinámica de Web pages de hoy.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    Mudanza a una vista de árbol&lt;/span&gt;&lt;br /&gt;La respuesta a este problema --al menos, la respuesta elegida por los navegadores Web de hoy en día-- es usar una estructura de árbol para representar HTML. Veamos el listing 1 , una página HTML bastante simple y aburrida representada como texto markup.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Listing 1 Pagina HTML simple en markup de texto&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt; &amp;lt;title&amp;gt;Arboles, árboles por todas partes&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;  &amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;h1&amp;gt; Arboles, árboles por todas partes&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt; Bienvenido a una página &amp;lt;em&amp;gt;realmente&amp;lt;/em&amp;gt; aburrida&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;div&amp;gt;&lt;br /&gt;Vuelve pronto.&lt;br /&gt;&amp;lt;img scr="come-again.gif" /&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;El navegador toma esto y lo convierte en una estructura como árbol, como en la figura 1&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Figura 1. La vista de árbol del listing 1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;img alt="The tree view of Listing 1" src="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro4/tree.gif" height="478" width="422" /&gt;&lt;br /&gt;Hice algunas simplificaciones menores para mantener este artículo en tema. Los expertos en DOM o XML se van a dar cuenta que ese espacio en blanco puede tener un efecto en como el texto es representado en un documento y una ruptura en la estructura de árbol del navegador Web. Meterse en esto suma poco y confunde el tema, entonces si sabés sobre el efecto del espacio en blanco, genial, si no, continua leyendo y no te preocupes por el. Cuando se convierta en un tema, vas a encontrar todo lo que necesites en ese momento. el árbol empieza con el elemento contenedor mas exterior que es el elemento HTML. Este se llama el elemento raíz(root) manteniendo la metáfora del árbol.  Aunque esté en la parte inferior del árbol, siempre empieza acá cuando observes y analices arboles. Si te ayuda,  podes dar vuelta el esquema, aunque se pierde un poco la metáfora del árbol.&lt;br /&gt;De la raíz surgen lineas que muestran las relaciones entre las diferentes partes del markup. los elementos &lt;span style="font-style: italic;"&gt; head &lt;/span&gt;y el &lt;span style="font-style: italic;"&gt;body &lt;/span&gt;son hijos del elemento raíz &lt;span style="font-style: italic;"&gt;html;&lt;/span&gt; &lt;span style="font-style: italic;"&gt;title &lt;/span&gt; es un hijo de &lt;span style="font-style: italic;"&gt;head &lt;/span&gt;y luego el texto "Arboles, arboles, en todas partes" es un hijo de &lt;span style="font-style: italic;"&gt;title&lt;/span&gt;. El árbol entero se organiza así, hasta el navegador obtiene una estructura similar a lo que ves en la figura 1.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Algunos términos adicionales&lt;/span&gt;&lt;br /&gt;Para continuar con la metáfora del árbol, &lt;span style="font-style: italic;"&gt;head &lt;/span&gt;y &lt;span style="font-style: italic;"&gt;body &lt;/span&gt;se dice que son ramas del &lt;span style="font-style: italic;"&gt; html&lt;/span&gt;. Son ramas por que ellas por su lado tienen sus propios hijos. SI vas a las extremidades del árbol, te vas a encontrar mayormente con texto como "Arboles, árboles, por todos lados" y "realmente". A estos normalmente nos referimos como Hojas por que no tienen hijos. No necesitas memorizar esos términos y es frecuentemente mas fácil solo visualizar la estructura de árbol cuando trates descubrir que significa un término particular.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-115022596256324903?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/115022596256324903/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=115022596256324903' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/115022596256324903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/115022596256324903'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/06/traduccin-de-artculo-de-ajax-xx.html' title='Traducción de Artículo de Ajax XX'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114985975584355585</id><published>2006-06-09T10:29:00.000-03:00</published><updated>2006-11-14T15:25:35.387-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XIX</title><content type='html'>&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Dominar Ajax Parte 4:  Explotar DOM para la respuesta Web&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Convertir HTML en un Modelo de Objetos para hacer las paginas Web Dinámicas e interactivas &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Nivel: Introductorio&lt;br /&gt;&lt;br /&gt;Brett McLaughlin (&lt;a href="mailto:brett@oreilly.com"&gt;brett@oreilly.com&lt;/a&gt;), Autor y Editor, O´Reilly y Asociados.&lt;br /&gt;14 Mar 2006&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;La gran división entre programadores (que trabajan con aplacaiones Back-end) y Programadores Web (que gastan su tiempo escribiendo HTML, CSS y JavaScript)es de muchos años. Sin embargo, el Modelo de Objetos de Documento (DOM) rompe las distancias, y hace posible trabajar con ambos XML en el Back-end y HTML en el front-end y como un herramienta efectiva. En este artículo, Brett McLaughlin introduce el Modelo de Objetos de Documento, explica su uso en las páginas Web y empieza a explorar su uso desde JavaScript.&lt;/blockquote&gt;&lt;p&gt;Como muchos programadores Web, probablemente hayas trabajado con HTML. HTML es como los programadores empiezan a trabajar en una página Web; HTML es a menudo la última cosa que hacen al terminar una aplicación o sitio, y un poco de colocación, color o estilo. Y tan común como es el uso de HTML, es la idea equivocada de que es exactamente lo que le pasa a ese HTML una vez que va al navegador para generar la pantalla. Antes, profundizo en que podrías pensar que sucede --y por que es probablemente erróneo--quiero que tengas claro el proceso involucrado en el diseño y el servicio de páginas web:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Alguien (normalmente vos!) crea HTML en un editor de texto o IDE&lt;/li&gt;&lt;li&gt;Luego subes el HTML a un servidor Web, como Apache HTTPD, lo haces publico en Internet o en una intranet.&lt;/li&gt;&lt;li&gt;Un usuario solicita tu página Web con un navegador como FireFox o Safari &lt;/li&gt;&lt;li&gt;El navegador del usuario hace una petición del HTML a tu servidor Web&lt;/li&gt;&lt;li&gt;El navegador muestra la página que recibió del servidor gráficamente y textualmente; el usuario mira y activa la página Web.&lt;br /&gt;&lt;/li&gt; &lt;/ol&gt; Mientras que esto se siente muy básico, las cosas se volverán interesante rápidamente. De hecho, la tremenda cantidad de "cosas" que pasan entre los pasos 4 y 5 es lo que enfoca este artículo. El termino "cosas" realmente se aplica también, ya que la mayoría de los programadores nunca consideran lo que pasa exactamente a su especificación de formato(markup) cuando un usuario pide que se lo muestre:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;¿El navegador solo lee el texto en el HTML y lo muestra?&lt;/li&gt;&lt;li&gt;¿Que pasa con CSS, espacialmente si el CSS esta en un archivo externo?&lt;/li&gt;&lt;li&gt;¿Y sobre JavaScript -- otra vez a menudo en un archivo externo?&lt;/li&gt;  &lt;li&gt;¿Como el navegador gestiona esos ítem y como relaciona los gestionadores de eventos, funciones y estilos para esta especificación de formato (markup) textual?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Resulta que la respuesta a todas esas preguntas es el Modelo de Objetos de Documento. Entonces, sin más complicaciones, vamos a profundizar en DOM.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Programadores Web y especificación de formato (markup)&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Para la mayoría de los programadores, su trabajo termina donde el navegador Web empieza. En otras palabras, una vez que colocaste un archivo HTML en un directorio en tu servidor Web, generalmente la archivas como lista y (esperanzadamente) nunca pensás realmente en ella de nuevo. Esa es una gran meta cuando viene de la escritura limpia, páginas bien-organizadas, también; no hay nada de malo con querer que tu especificación de formato muestre lo que debe, en todos los navegadores, con varias versiones del CSS y del Javascript.  &lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;El problema es que esta manera limita la comprensión del programador de que es lo que realmente pasa en el navegador. Mas importante, limita tu habilidad de actualizar, cambiar y reestructurar una página Web dinámicamente usando JavaScript del lado cliente. Sacate de encima esa limitación, y permite una todavía más grande interacción y creatividad en tu páginas Web.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lo que hacen los programadores&lt;/span&gt;&lt;br /&gt;Como típico programador Web, probablemente dispares tu editor de texto y IDE y empezás a ingresar HTML, CSS, o más, JavaScript. Es fácil pensar en esas etiquetas y selectores y atributos solamente como pequeñas tareas para hacer que un sitio de vea bien. Pero necesitas flexibilizar tu mente más allá de ese punto -- en su lugar, darte cuenta de que estas organizando tu contenido. No te preocupes; te prometo esto no se va a transformar en una lectura sobre la belleza del markup lo que tenés que darte cuenta es el verdadero potencial de tu página Web, y todo lo metafísico más. Lo que necesitas entender es exactamente cual es tu rol en el desarrollo Web.&lt;br /&gt;Cuando viene como se ve una página, a lo mejor solamente podes hacer sugerencias. Cuando proporcionas una hoja de estilos CSS, un usuario puede invalidar tus elecciones de estilo. Cuando proporcionas un tamaño de fuente, un navegador de un usuario puede alterar esas medidas para los de visión disminuida o escalarlo en monitores masivos (con resoluciones igualmente masivas). También los colores y los tipos de fuentes que elegiste están sujetas al monitor de los usuarios y a las fuentes que los usuarios instalen en sus sistemas. Si bien es genial que hagas lo mejor que puedas en el estilo de una página, ese no es el más grande impacto que tienes en una página Web.&lt;br /&gt;Lo que vos controlás absolutamente es la estructura de tu página Web. Tu markup no se puede cambiar, es inalterable y los usuarios no puede hacer un lio con el; sus navegadores solo pueden recuperarlo del servidor y mostrarlo (no obstante, con un estilo más conforme al gusto del usuario que al tuyo). Pero la organización de esta página --este esta palabra dentro de ese párrafo en en el otro div-- es únicamente tuya. Cuando realmente hay que cambiar tu página  (que es lo que las aplicaciones Ajax más focalisan), es la estructura de tu página la que trabajas. Si bien es lindo cambiar el color de una parte del texto, es mucho mejor agregar texto o una sección entera a una página existente. No importa el estilo que el usuario le de a esa sección vos trabajás con la organización de la página misma.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114985975584355585?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114985975584355585/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114985975584355585' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114985975584355585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114985975584355585'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/06/traduccin-de-artculo-de-ajax-xix.html' title='Traducción de Artículo de Ajax XIX'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114953665294992005</id><published>2006-06-05T15:56:00.000-03:00</published><updated>2006-11-14T15:25:32.850-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XVIII</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Tipos de peticiones adicionales&lt;/span&gt;&lt;br /&gt;Si realmente quieres tener el control del objeto XMLHttpRequest, considera este última parada -- agregar peticiones HEAD a tu repertorio. En los dos artículos previos, te mostré como hacer peticiones GET, en un próximo artículo, vas a aprender todo sobre mandar información al servidor usando las peticiones POST. Con el espíritu de realzar la gestión de errores y la reunión de información, debes aprender como hacer peticiones HEAD.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Hacer la Petición&lt;/span&gt;&lt;br /&gt;Realmente hacer una petición HEAD es absolutamente trivial. Simplemente llama al método &lt;span style="font-style: italic;"&gt;open() &lt;/span&gt;con HEAD en vez de GET o POST como primer parámetro, como de muestra en el listing 9.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 9. Hacer una petición HEAD con Ajax&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function getSalesData(){&lt;br /&gt;createRequest();&lt;br /&gt;var url = "/boards/servlet/UpdateBoardSales";&lt;br /&gt;request.open("HEAD", url, true);&lt;br /&gt;request.onreadystatechange = updatePage;&lt;br /&gt;request.send(null);&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Cuando haces una petición HEAD como esta, el servidor no devuelve una respuesta real como lo haría para una petición GET o POST. En su lugar, el servidor solo tiene que devolver las cabeceras de la fuente que incluye la ultima hora que el contenido de la respuesta fue modificado, si la fuente de la petición existe o no, y algunas otras partes interesantes de información. Podés usar varias de esas para descubrir sobre un recurso antes que el servidor haya procesado y devuelto ese recurso.&lt;br /&gt;La cosa mas fácil que puedes hacer con una petición como esta es simplemente mostrar todas las cabeceras de la respuesta. Esto te da la pauta de que es lo que tenes disponible a travez de las peticiones HEAD. El listing 10 provee una funcion de rellamada simple para exteriorizar todas las cabeceras de respuesta de una peticion HEAD.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 10. Imprimir  todas las cabeceras de respuesta de una petición HEAD&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatepage(){&lt;br /&gt;if (request.readyState == 4){&lt;br /&gt;alert(request.getAllResponseHeader());&lt;br /&gt;}&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Controlar la figura 7, que muestra las cabeceras de respuestas de una aplicación simple que hace peticiones HEAD a un servidor.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Figura 7. Cabeceras de respuesta de una petición HEAD&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/response_headers.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/response_headers.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;Podés usar cualquiera de esas cabeceras (desde el tipo de servidor hasta el tipo de contenido) individualmente para dar información extra o funcionalidad dentro de una aplicación Ajax.&lt;br /&gt;Controlar una URL&lt;br /&gt;Ya has visto como controlar un error 404 cuando una URL no existe. Si esto se vuelve un problema comun --probablemente algún script o servlet este fuera de lineo cada tanto-- podrías querer controlar la URL antes de hacer una petición GET o POST completa. Para esto, haz una petición HEAD y luego controla el error 404 en tu funcion de rellamada; El listing 11 muestra una rellamada de muestra.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 11. controlar si una URL existe&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;if (request.readyState ==4){&lt;br /&gt;if (request.status==200){&lt;br /&gt;alert ("Existe URL");&lt;br /&gt;} else if (request.status ==404){&lt;br /&gt;alert ("No existe la URL");&lt;br /&gt;} else{&lt;br /&gt;alert ("El estado es: " + request.status);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Para ser honestos, esto tiene poco valor. El servidor tiene que reponder la petición y resolver una respuesta para poblar el tamaño del contenido de la cabecera de respuesta, entonces no salvas nada de tiempo de procesamiento. Además, toma tanto tiempo hacer la petición y ver si la URL existe usando un petición HEAD que si lo hicieras usando GET o POST, solo estionando los errores como se muestra en el Listing 7. Aún así, a veces es útil saber exactamente que está disponible; nunca sabes cuando surgirá la creatividad y necesites la petición HEAD.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Peticiones HEAD útiles&lt;/span&gt;&lt;br /&gt;Un área donde vas a encontrar útil la petición HEAD es para controlar el tamaño del contenido o también el tipo del contenido. Esto te permite determinar si tal cantidad de información va a ser devuelta para procesar la petición o si el servidor va a tratar de devolver información binaria en vez de HTML, texto o XML (los cuales son mucho mas fácil de procesar por JavaScript que la información binaria).&lt;br /&gt;En esos casos, usas la cabecera apropiada y lo pasas al método &lt;span style="font-style: italic;"&gt;getResponseHeader() &lt;/span&gt;del objeto &lt;span style="font-style: italic;"&gt;XMLHttpRequest&lt;/span&gt;. Entonces para obtener el tamaño de una respuesta, solo llama al &lt;span style="font-style: italic;"&gt;request.getResponseHeader("Content-Length");.&lt;/span&gt; Para obtener el tipo del contenido, usa &lt;span style="font-style: italic;"&gt;request.getResponseHeader("Content-Type");&lt;/span&gt;.&lt;br /&gt;En muchas aplicaciones, hacer peticiones HEAD no agrega funcionalidad y hasta poner lenta una petición (forzando una petición HEAD para obtener información sobre la respuesta y luego la petición GET o POST para obtener la respuesta propiamente dicha). Sin embargo, en el caso de que no estes seguro sobre un script o un componente del lado servidor, una petición HEAD puede permitirte obtener alguna información básica sin tener que lidiar con información de respuesta ni necesitas el ancho de banda para enviar esa respuesta.&lt;br /&gt;En Conclusión&lt;br /&gt;Para muchos programadores de Ajax y Web, el material en este artículo puede parecer bastante avanzado. ¿Cual es el valor de hacer una petición HEAD?¿Cual es realmente el caso donde deberías gestionar un codigo de estado de redireccionamiento explicito en tu JavaScript? Son buenas preguntas; para aplicaciones simples, la respuesta es que esas tecnicas avazadas probablemente no sean validas.&lt;br /&gt;Sin embargo, la Web no es mas un lugar donde solo son toleradas aplicaciones simples; usuarios han vuelto más avanzados, los clientes esperan robustez y reportes de errores avanzados, y los directores son despedidos porque una aplicacion se cae un 1% del tiempo.&lt;br /&gt;Es tu trabajo entonces, ir más allá de una simple aplicación y eso requiere una comprensión más profunda de XMLHttpRequest.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Si puedes explicar la variedad de estados ready --y comprender como se diferencian de navegador a navegador -- serás capas de eliminar errores de una aplicación rápidamente. Puede ser que incluso aparezcas con una creativa funcionalidad basada en los estados Ready y reportes un estado de la petcion a los usuarios y clientes.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Si tiene un manejo de los códigos de estados, podes fijar tu aplicación para que maneje los errores en el script, las respuestas inesperadas y los casos límite.  Como resultado, tu aplicación va a trabajar todo el tiempo, mas que solo en llas situaciones en que todo está bien.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Agregas a hesta habilidad el hacer peticiones HEAD, controlar la existencia de una URL, y descubrir cuando un archivo fue modificado y puede asegurar que los usuarios acceden a páginas validas, estan actualizados en su información y (lo más importante) los sorprendes con solo lo robusta y versatil que es tu aplicación.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Este artículo no va a hacer tus aplicaciones llamativas, ayudarte a resaltar el texto con luces amarillas que se devanecen, o que se sientan más como un escritorio. Mientras estas son todas fortalezas de Ajax (y temas que trataremos en próximos artículos) son en algun grado solo beneficios adicionales. Si podés usar Ajax para construir una sólido base en la cual tu aplicación maneje los errores y  problemas suavemente, los usuarios van a volver a tu sitio y aplicación. Agregale a  esto los trucos visuales de los que vamos a hablar en próximos artículos y vas a tener clientes emosionados, entusiasmandos y felices. (seriamente, no querrás perderte el próximo artículo!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114953665294992005?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114953665294992005/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114953665294992005' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114953665294992005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114953665294992005'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/06/traduccin-de-artculo-de-ajax-xviii.html' title='Traducción de Artículo de Ajax XVIII'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114911063753860062</id><published>2006-05-31T18:21:00.000-03:00</published><updated>2006-11-14T15:25:32.749-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XVII</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Redireccionamientos y reenrutamiento&lt;/span&gt;&lt;br /&gt;Antes de hablar en profundidad sobre errores, vale la pena hablar sobre algo que probablemente no hay que preocuparse cuando estas usando Ajax -- redireccionamientos. En los códigos de estado de HTTP, esta es la familia 300 de los códigos de estado, incluyendo:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;301&lt;/b&gt;: Movido permanentemente&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;302&lt;/b&gt;: Encontrado (La petición fue redireccionada a otra URL/URI)&lt;/li&gt;&lt;li&gt;&lt;b&gt;305&lt;/b&gt;: Usar Proxy (La petición debe usar proxy para acceder al recurso solicitado)&lt;/li&gt;&lt;/ul&gt;los programadores de Ajax probablemente no están preocupados por los redireccionamientos por dos razones:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Primero, las aplicaciones ajax siempre se escriben para un script, servlet o aplicación del lado-servidor especifico. Para que ese componente desaparesca y sea movido a otro lado sin que vos, el programador de ajax, te enteres es un poco extraño. Entonces, más a menudo que no, vas a saber que ese recurso fue movido (por que lo moviste), cambias la url en tu petición y nunca te encuentras con este tipo de resultados.&lt;/li&gt;&lt;li&gt;y la razon las relevante es: Las aplicaciones Ajax tiene sandbox. esto significa que el dominio que sirve a una página Web que hace peticiones Ajax es el dominio que tiene que responder a esas peticiones. Por esto una pagina web servida por ebay.com no puede hacer una peticion de estilo Ajax a un script que se ejecuta en amazon.com; Aplicaciones Ajax en ibm.com no pueden peitcionar a los servlets que se ejecutan en netbeans.org&lt;/li&gt;&lt;/ul&gt;Como resultado, tus peticiones no pueden ser redirecciondas a otro servidor sin generar un error de seguridad. En esos casos, no vas a recibir un código de estado. Normalmente solo vas a tener un error JavaScript en la consola de debug. Por esto, mientras que piensas en un montón de códigos de estado, puedes ignorar en gran parte los códigos de redireccionamiento en conjunto.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Casos límite y casos difíciles&lt;/span&gt;&lt;br /&gt;En este punto, los programadores principiantes  se preguntaran qué es todo este lio. Es cierto que menos del 5% de las peticiones Ajax requieren trabajar con los estados ready 2 y 3 y los códigos de estados como el 403 (de hecho, sería más cercano al 1% o menos). Estos casos son importantes y se llaman casos límites -- ocurren en situaciones muy inusuales  en las cuales se desarrollan las condiciones más extrañas. Apesar de ser inusuales los casos límites probocan alrededor de 80% de las frustraciones de los usuarios!&lt;br /&gt;Los usuarios típicos de olvidan de las 100 veces que una aplicación funciona correctamente pero recuerdan claramente la vez que no lo hace. Si podes manejar los casos límite -y los casos dificiles-suavemente, entonces vas a tener contenidos a los usuarios que volveran a tu sitio.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Errores&lt;/span&gt;&lt;br /&gt;Una vez que hayas tenido cuidado con el código de estado 200 y te hayas dado cuenta de que podes ignorar rotundamente la familia de códigos de estado 300, el otro grupo de códigos que queda para preocuparse es la familia 400, que indica varios tipos de error. Mirar de nuevo el listin 7 y notar que mientras se manejan los errores, solamente se muestra al usuario un mensaje de error genérico. Mientras este es un paso en la direccion corretam, es aun un mensaje bastante inutil a losefectos de decirle al usuario o programador que está trabajando en la aplicación que es lo que realmente esta mál.&lt;br /&gt;Primero, agregar soporte a las paginas perdidas. Esto no pasa mucho en los sistemas de producción, pero no es raro en pruebas para mover un script o que un programador ingrese una URL incorrecta. Si podes reportar los errores 404 con gracia, vas a proveer mucha mas ayuda a los usuarios y programadores confundidos. Por ejemplo, si un script en el servidor fue removido y usas el codigo en el listing 7, verías un error no descriptivo como el que se muestra en la figura 5.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Figura 5. Manejo de error genérico&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ibm.com/developerworks/web/library/wa-ajaxintro3/generic_error.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www.ibm.com/developerworks/web/library/wa-ajaxintro3/generic_error.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;El usuario no tiene manera de decirte si el problema es de autenticación, o un scrip perdido (que es el caso acá), o un error de usuario, o más si algo en el código causó el problema o no. Un poco de código simple adicional puede hacer este error mucho más especifico. Hechale una ojeda al listing 8 que trata los script perdidos, así como errores de autenticación con un mensaje especifico.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 8. Controlar el código de estado válido&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;if (request.readyState == 4){&lt;br /&gt;if (request.status == 200){&lt;br /&gt;var response = request.responseText.split("|");&lt;br /&gt;document.getElementById("order").value = response[0];&lt;br /&gt;document.getElementById("address").innerHTML = response[1].replace)/\n/g, "&amp;lt;br /&amp;g;");&lt;br /&gt;} else if (request.status == 404){&lt;br /&gt;alert ("No se encontro URL solicitada.");&lt;br /&gt;}else if (request.status == 403){&lt;br /&gt;alert ("Acceso denegado.");&lt;br /&gt;}else&lt;br /&gt;alert ("El estado es " + request.status);&lt;br /&gt;}&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Esto es todavía bastante simple, pero provee algo de información adicional. La figura 6 muestra el mismo error que en la figura 5, pero esta vez el código tratador de error da una mucho mejor imagen de  que esta pasando al usuario o programador.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Figura 6. Gestión de error especifica.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ibm.com/developerworks/web/library/wa-ajaxintro3/specific_error.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www.ibm.com/developerworks/web/library/wa-ajaxintro3/specific_error.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;En tus propias aplicaciones, podrias considerar despejar el nombre de usuario y la contraseña cuando ocurre una falla de autenticación y agregar un mensaje de error a la pantalla. Pueden ser  aplicadas mejoras similares para una gestion mas amigable de los script perdidos u otros errores tipo 400 (tal como el 405 para un método de petición inaceptable como enviar una petición HEAD que no está permitida o 407 en la que se requiere autenticacion de proxy). Cuaquier elección que hagas, empieza con la gestión del código de estado devuelto por el servidor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114911063753860062?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114911063753860062/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114911063753860062' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114911063753860062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114911063753860062'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/05/traduccin-de-artculo-de-ajax-xvii.html' title='Traducción de Artículo de Ajax XVII'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114895063894398695</id><published>2006-05-29T21:56:00.000-03:00</published><updated>2006-11-14T15:25:32.585-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XVI</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Conseguir datos seguros&lt;/span&gt;&lt;br /&gt;Toda la documentación y especificaciones insiten en que solamente cuando el estado ready esta en 4 la información es segura para usar. Creeme, rara vez encontraras un caso donde la información no pueda ser obtenida de la propiedad &lt;span style="font-style: italic;"&gt;responseText &lt;/span&gt;cuando el estado ready está en 3. Sin embargo, confiar en eso en tu aplicacion es una mala idea -- desde el momento que escribis código que dependa de información completa con estado ready en 3, está casi garantizado que llegará el momento en que la información sea incompleta.&lt;br /&gt;Una mejor idea es proveer al usuario de alguna información cuando el estado ready este en 3, que una respuesta esta proxima. Mientras que usar una funcion como &lt;span style="font-style: italic;"&gt;alert() &lt;/span&gt;es obviamente una mala idea --usar Ajax y luego bloquear al usuario con un cuadro de dialogo de alerta es muy poco razonable -- podes actualizar un campo en tu formulario o página mientras los estados ready cambian. Por ejemplo, trata de establecer el ancho de un indicador de progreso a un 25% para el estado ready en 1, 50% para el 2, 75% para el 3 y 100% (completo) cuando el estado ready llega a 4.&lt;br /&gt;Por supuesto, como has visto, esta mejora es inteligente pero navegador-dependiente. En Opera, nunca obtendrás esos dos primeros estados ready y en Safari salta el primero (1). Por esa razón, dejo el codigo como este como ejercicio antes que incluirlo en el articulo.&lt;br /&gt;Tiempo de echar un vistaso a los códigos de estado.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Una mirada mas cercana a los códigos de estado de HTTP&lt;/span&gt;&lt;br /&gt;Con los estados READY y la respuesta del servidor en tu bolsa de técnicas de programación de Ajax, etas listo para agregar otro nivel de la sofisticación a tus aplicaciones Ajax --trabajar con códigos de estado del HTTP. Estos códigos son nada nuevo a Ajax. Han estado alrededor de la Web siempre que hubo Web. Ya has visto probablemente varios de éstos con tu navegador web:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;401&lt;/b&gt;: Sin autorizacion&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;403&lt;/b&gt;: Prohibido&lt;/li&gt;&lt;li&gt;&lt;b&gt;404&lt;/b&gt;: No encontrado&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;Podes encontrar mas (Para una lista completa, ver &lt;a href="http://www.ibm.com/developerworks/web/library/wa-ajaxintro3/#resources"&gt;Resources&lt;/a&gt;). Para agregar otra capa de control y sensibilidad (y particularmente un manejor de error más robusto) a tus aplicaciones Ajax, entonces necesitas comprobar los códigos de estado en una petición y responder apropiadamente.&lt;br /&gt;&lt;/p&gt;&lt;ul style="font-weight: bold;"&gt;&lt;li&gt;&lt;span class="smalltitle"&gt;200: Todo está Bien&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;En muchas aplicaciones Ajax, vas a ver una funcion de rellamada que controla el estado ready y luego continuan trabajando con la información de la respuesta del servidor, como en el listing 6.&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 6. Funcion de rellamada que ignora el codigo de estado&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;if(request.readystate ==4){&lt;br /&gt;var response = request.responseText.split("|");&lt;br /&gt;document.getElementById("order").value = response[0];&lt;br /&gt;document.getElementById("address").innerHTML = response[1].replace(/\n/g, "&amp;lt;br /&amp;gt;");&lt;br /&gt;}&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;Esto resulta ser una mejora  miope y propensa a error en programacion Ajax. Si un script requiere autentificación  y tu peticion no provee credenciales validas, el servidor va a devolver un código de error como el 403 o 401. Sin embargo, el estado ready va a estar establecido en 4 ya que el servidor respondió la petición  (a pesar de que la respuesta no sea la que querias o esperabas para tu petición). Como resultado, el usuario no va a obtener información valida y hasta podría obtener un error feo cuando tu JavaScript trate de usar una unformación del servidor no existente.&lt;br /&gt;Toma un esfuerzo minimo asegurarse que el servidor no solo haya terminado con una petición, sino que haya devuelto un código de estado "todo esta bien". Ese código es "200" y se reporta a traves de la propiedad &lt;span style="font-style: italic;"&gt;status &lt;/span&gt;del objeto &lt;span style="font-style: italic;"&gt;XMLHttpRequest&lt;/span&gt;. Para estar seguro de que no solo el servidor haya terminado con una petición sino que también reporte un estado ok, agrega un control adicional en tu función de rellamada como se muestra en el listing 7.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 7. Controlar el código de estado válido&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;if (request.readyState ==4) {&lt;br /&gt;if (request.status == 200){&lt;br /&gt;var response = request.responseText.split("|");&lt;br /&gt;document.getElementById("order").value = response[0];&lt;br /&gt;document.getElementById("address").innerHTML = response[1].replace(/\n/g,"&amp;lt;br /&amp;gt;");&lt;br /&gt;} else&lt;br /&gt;alert ("el estado es " + request.status);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Con la adición de algunas líneas del código, podes estar seguro de que si algo sale mal, tus usuarios van a obtener un (custionablemente) útil mensaje de error antes que ver una pagina con información mutilada sin explicación alguna.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114895063894398695?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114895063894398695/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114895063894398695' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114895063894398695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114895063894398695'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/05/traduccin-de-artculo-de-ajax-xvi.html' title='Traducción de Artículo de Ajax XVI'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114893528670590389</id><published>2006-05-29T16:57:00.000-03:00</published><updated>2006-11-14T15:25:32.488-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XV</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Inconsistencia de navegadores&lt;/span&gt;&lt;br /&gt;Una vez que tenes un entendimiento básico de este proceso, trata de acceder desde varios navegadores diferentes. Deberías notar algunas inconsistencias en como estos estados ready son manipulados. Por ejemplo en Firefox 1.5, ves los siguientes estados ready:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;1&lt;/li&gt;&lt;li&gt;2&lt;/li&gt;&lt;li&gt;3&lt;/li&gt;&lt;li&gt;4&lt;/li&gt;&lt;/ul&gt;Esto no debería ser una sorpresa ya que todos los estados están representados acá. Sin embargo si accedes la misma aplicación usando Safari, deberías ver --o mas,  no ver-- algo interesante. Acá están los estados que ves en Safari 2.0.1&lt;br /&gt;&lt;ul&gt;&lt;li&gt;2&lt;/li&gt;&lt;li&gt;3&lt;/li&gt;&lt;li&gt;4&lt;/li&gt;&lt;/ul&gt;Safari realmente deja afuera el primer estado ready y no hay una explicación sensata de porqué; es simplemente la manera en que trabaja Safari. Esto ilustra también un punto importante: mientras es una buena idea asegurar que el estado Ready de una petición sea 4 antes de usar la información del servidor, escribir código que dependa de cada cambio del estado ready es una manera segura de obtener resultados distintos en navegadores distintos.&lt;br /&gt;Por ejemplo, cuando se usa Opera 8.5, las cosas son todavía peores con la salida de los estados ready:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;3&lt;/li&gt;&lt;li&gt;4&lt;/li&gt;&lt;/ul&gt;Por último pero no menos, Internet Explorer responde con los siguientes estados:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;1&lt;/li&gt;&lt;li&gt;2&lt;/li&gt;&lt;li&gt;3&lt;/li&gt;&lt;li&gt;4&lt;/li&gt;&lt;/ul&gt;Si tienes problemas con una petición, este es el primer lugar para buscar los problemas. Agrega un alerta para mostrar el estado ready de tu petición para que puedas asegurarte de que las cosas estan operando correctamente. Mejor todavía, prueba en Internet Explorer y Firefox--vas a obtener los 4 estados readyy vas a poder controlar cada etapa de la petición.&lt;br /&gt;Luego yo miro el lado de la respuesta.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Información de respuesta bajo el microscopio&lt;/span&gt;&lt;br /&gt;Una vez que entiendas los varios estados ready que ocurren durante una petición, estás listo para mirar otra pieza importante del objeto XMLHttpRequest --la propiedad responseText. Recuerda del último artículoque esta es la propiedad usada para obtener la información del servidor. Una vez que el servidor ha terminado de procesar la petición, situa toda información que se necesita para responder la petición en el responseText de la petición. Luego tu función de rellamada puede usar esa información, como se ve en el listing1 y 4.&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 4. Usar la respuesta del servidor&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage() {&lt;br /&gt;if(request.readyState == 4) {&lt;br /&gt;var newTotal = request.responseText;&lt;br /&gt;var totalSoldEl = document.getElementById("total-sold");&lt;br /&gt;var netProfitEl = document.getElementById("net-profit");&lt;br /&gt;replaceText(totalSoldEl, newTotal);&lt;br /&gt;/*Descubrir la nueva ganancia neta*/&lt;br /&gt;var boardCostEl = document.getElementById("board-cost");&lt;br /&gt;var boardCost = getText(boardCostEl);&lt;br /&gt;var manCostEl = document.getElementById("man-cost");&lt;br /&gt;var manCost = getText(manCostEl);&lt;br /&gt;var profitPerBoard = boardCost - manCost;&lt;br /&gt;var netProfit = profitPerBoard * newTotal;&lt;br /&gt;/*Actualizar la ganancia neta el el formulario de ventas*/&lt;br /&gt;netProfit = Math.round(netProfit *100)/100;&lt;br /&gt;replaceText (netProfitEl, netProfit);&lt;br /&gt;}&lt;br /&gt;}&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;El Listing 1 es bastante simple; el Listing 4 es un poco mas complicado, pero para empezar, ambos controlan el estado ready y luego toman el valor (o valores) de la propiedad &lt;span style="font-style: italic;"&gt;responseText&lt;/span&gt;.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Visualizar el texto de respuesta durante una petición&lt;/span&gt;&lt;br /&gt;Como el estado ready, el valor de la propiedad&lt;span style="font-style: italic;"&gt; responseText &lt;/span&gt;cambia durante el ciclo de vida de la petición. Para ver esto en acción, usa el código como el que se muestra en el listing 5 para probar el texto de respuesta de una petición, tal como los estados ready.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 5. Probar la propiedad responseText&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;//Mostrar el estado ready actual&lt;br /&gt;alert("updatePage() llamada con el estado ready en " + request.readyState + " y un texto de respuesta de '" + request.responseText + "'");&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Ahora abre tu aplicación Web en un navegador y activa tu petición. Para obtener lo maximo de este código, usa Firefox o Internet Explorer ya que estos navegadores reportan todos los estados posibles durante una petición. Con un estado ready en 2, por ejemplo, la propiedad &lt;span style="font-style: italic;"&gt;responseText&lt;/span&gt; es indefinida (ver figura 3) y deberías ver un error si la consola JavaScript está abierta tambien.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Figura 3. Texto de respuesta con un estado ready en 2&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/ready-state_2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/ready-state_2.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Con el estado ready en 3 sin embargo, ha colocado un valor en la propiedad &lt;span style="font-style: italic;"&gt;responseText&lt;/span&gt;, al menos en este ejemplo (ver figura 4).&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Figura 4: Texto de respuesta con un estado ready en 3&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/ready-state_3.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/ready-state_3.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;Vas a descubrir que tu respuesta en el estado ready 3 varía de scritp a script, servidor a servidor  y navegador a navegador. SIn embargo esto aun es increiblemente util para eliminar errores de tu aplicación.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114893528670590389?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114893528670590389/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114893528670590389' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114893528670590389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114893528670590389'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/05/traduccin-de-artculo-de-ajax-xv.html' title='Traducción de Artículo de Ajax XV'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114891343264015302</id><published>2006-05-29T11:08:00.000-03:00</published><updated>2006-11-14T15:25:32.319-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XIV</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Dominar AJAX, Parte 3: Peticiones y respuestas Avanzandas en AJAX&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ganar una comprensión completa de los códigos de estado de HTTP, de los estados READY, y del objeto de XMLHttpRequest&lt;/span&gt;&lt;br /&gt;Nivel: Introductorio&lt;br /&gt;Brett McLaughlin (brett@oreilly.com), Autor y Editor, O´Reilly y Asociados.&lt;br /&gt;14 Feb 2006&lt;br /&gt;&lt;blockquote&gt;Para muchos desarrolladores Web, hacer peticiones simples y recibir respuestas simples es todo lo que siempre necesitaron, pero para desarrolladores que quieran dominar Ajax, se requiere un entendimiento completo de códigos de estado de HTTP, estados Ready y el objeto XMLHttpRequest. En este artículo Brett McLaughlin te va a mostrar los diferentes códigos de estado y va a demostrar como los maneja cada navegador y va a mostrar peticiones menos usadas que se pueden hacer con Ajax&lt;/blockquote&gt;&lt;br /&gt;En el último artículo de esta serie, proporcioné una sólida introducción al objeto XMLHttpRequest, la pieza central de una aplicación Ajax que maneja peticiones para aplicaciones o scripts del lado servidor y tambien trata con información devuelta por ese componente del lado servidor. Toda aplicación Ajax usa el objeto XMLHttpRequest, por eso vas a querer estar intimamente familiarizado con él, para realizar tus aplicaciones Ajax y para realizarlas bien.&lt;br /&gt;En este artículo, me muevo más allá de los fundamentos del artículo pasado y me concentro más en detalle sobre tres parte claves de este objeto de petición:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Los estados Ready de HTTP&lt;/li&gt;&lt;li&gt;Los códigos de estado de HTTP&lt;/li&gt;&lt;li&gt;Los tipos de peticiones que podes hacer&lt;/li&gt;&lt;/ul&gt;Cada uno de estos es considerado generalmente parte de la cañería de una petición; como resultado, poco detalle se registra sobre estos temas. Sin embargo vas a necesitar ser fluido en estados Ready, códigos de estado, y peticiones si querés hacer mas que solo salpicar en programación Ajax. Cuando algo anda mal en tu aplicación -- y las cosas siempres andan mal-- entender estados Ready, como hacer una petición de cabeceras o que significa un código de estado 400 puede hacer la diferencia entre 5 minutos de eliminar errores y 5 horas de frustración y confusión.&lt;br /&gt;Miraré estados READY de HTTP primero.&lt;br /&gt;Introduciendonos mas profundo en los estado ready de HTTP&lt;br /&gt;Debés recordar del articulo anterior que el objeto XMLHttpRequest tiene una propiedad llamada readyState. Esta propiedad asegura que un servidor ha completado una petición y típicamente una función de rellamada usa la informacion del servidor para actualizar un formulario web o página. El listing 1 muestra un ejemplo simple de esto (también en el último artículo de la serie)&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 1.Tratar con una respuesta del servidor en una funcion de rellamada.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;if(request.readyState==4){&lt;br /&gt;if (request.status==200){&lt;br /&gt; var response = request.responseText.split("|");&lt;br /&gt; document.getElementById("order").value=response[0];&lt;br /&gt; document.getElementById("address").innerHTML=response[1].replace(/\n/g."&amp;lt;br /&amp;gt;");)&lt;br /&gt;} else&lt;br /&gt;alert ("El estado es " + request.status);&lt;br /&gt;}&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Este es definitivamente el uso más común (y el mas simple) de los estado ready. Como seguramente adivinaras por numero "4", hay varios otros estado ready  (tambien viste esta lista en el último artículo):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;0: La petición no está inicializada (antes de llamar a la funcion open()).&lt;/li&gt;&lt;li&gt;1: La petición esta establecida pero no enviada (antes de que hayas llamado a send()).&lt;/li&gt;&lt;li&gt;2: La petición fue enviada y está en proceso (podes normalmente obtener los contenidos de cabecera de la respuesta en este punto)&lt;/li&gt;&lt;li&gt;3: La petición está en proceso , a veces alguna información parcial está disponible de la respuesta, pero el servidor no ha terminado con esa respuesta.&lt;/li&gt;&lt;li&gt;4: La respuesta esta completa, podes tomar la respuesta del servidor y usarla.&lt;/li&gt;&lt;/ul&gt;Si deseas ir mas alla de los fundamentos de la programación en Ajax, necesitas saber no solo estos estados sino cuando ocurren y como podes usarlos. Sobre todo, necesitas aprender en qué estado de una petición encuentras cada estado READY. Desafortunadamente, esto es bastante poco intuitivo y también implica algunos casos especiales.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Estados ready ocultos&lt;/span&gt;&lt;br /&gt;El primer estado ready, identificado por la propiedad del readyState 0 (readyState== 0), representa una petición no inicialidada. Tan pronto como llames a open() en tu objeto petición, esta propiedad se establece a 1. Como casi siempre llamas a open() tan pronto como inicializas tu petición, es raro ver readyState==0. Es más el estado ready sin inicializar es bastante inútil en aplicaciones prácticas.&lt;br /&gt;No obstante, en el interés de ser completo, comprobar en el listing 2 que demuestra cómo conseguir el estado READY cuando es 0.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 2. Obtener el estado ready 0&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function getSalesData() {&lt;br /&gt;//crear el objeto petición&lt;br /&gt;createRequest();&lt;br /&gt;alert("El estado Ready es " - request.readyState);&lt;br /&gt;//Establecer (inicializar) la petición&lt;br /&gt;var url = "/boards/servlet/updatePage";&lt;br /&gt;request.send(null);&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;En este ejemplo simple, getSalesData() es la función que tu página Web llama para empezar una petición (como cuando un botón es presionado). Observar que tienes que comprobar el estado READY antes de que se llame a open() . La figura 1 demuestra el resultado de ejecutar esta aplicación.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Figura 1: Un estado ready en 0&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/ready-state_0.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/ready-state_0.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Obviamente, esto no te hace mucho de bueno; hay muy pocas veces en que necesitarás cerciorarse de que open() no se haya llamado. El único uso para este estado READY en el casi-verdadero-mundo de programación de Ajax es si haces peticiones múltiples usando el mismo objeto de XMLHttpRequest a través de funciones múltiples. En esa situación (algo inusual), puede ser que desees asegurarse de que un objeto de la petición esté en el estado sin inicializar( readyState== 0) antes de hacer nuevas peticiones. Esto esencialmente se asegura de que otra función no esté utilizando el objeto al mismo tiempo.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;span style="font-weight: bold;"&gt;Cuando 0 es igual a 4 &lt;/span&gt;&lt;br /&gt;En el caso de uso donde las funciones múltiples de Javascript utilizan el mismo objeto de petición, comprobar si hay un estado READY en 0 para asegurarse de que el objeto de la peticiónno esté en uso puede resultar ser problemático. Puesto que el readyState== 4  indica una petición terminada, encontrarás a menudo los objetos depetición que no se están utilizando con su estado READY todavía fijado en 4 -- los datos del servidor fueron utilizados, pero nada ha ocurrido desde entonces para reajustar el estado READY. Hay una función que reajusta un objeto de la petición llamado abort(), pero realmente no fue pensada para este uso. Si tenes que utilizar funciones múltiples, puede ser que sea mejor crear y utilizar un objeto de petición para cada función más que compartir el objeto a través de funciones múltiples.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ver el estado READY de una petición en curso &lt;/span&gt;&lt;br /&gt;Aparte del estado READY en 0, tu objeto de petición debe pasar con cada uno de los otros estados READY en una petición y respuesta típica, y finalmente terminar con un estado READY de 4. Éso es cuandola línea if(request.readyState == 4)  del código que ves en la mayoría de las funciones de rellamada entra; asegura que el servidor terminó y es seguro actualizar la página Web o tomar una acción basada en la información del servidor.&lt;br /&gt;Es una tarea trivial realmente ver este proceso tal como ocurre. En vez de solamente de ejecutar el código en tu rellamada si el estado READY es 4, solamente muestra el estado READY cada vez que tu rellamada sea llamada. Como ejemplo del código que hace esto, comprobar el listing 3.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 3. Comprobar el estado Ready&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;//mostrar el estado Ready actual&lt;br /&gt;alert("updatePage() llamado con un estado ready en " + request.readyState);&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Si no estás seguro de cómo conseguir este funcionamiento, necesitarás crear una función para llamar desde tu página Web y para hacer que envíe una petición a un componente del lado servidor (tal como la función que fue demostrada en el listing 2 y a través de los ejemplos en el primero y segundo artículos en esta serie). Cerciorarte de que cuando  estableciste tu petición, fijaras la función de rellamada al updatePage (); para hacer esto, fijar la propiedad  onreadystatechange de tu objeto petición al updatePage ().&lt;br /&gt;Este código es una gran ilustración de exactamente qué significa el onreadystatechange -- el estado READY de la petición cambia cada vez, se llama el updatePage () y ves una alarma. Figura 2 demuestra un ejemplo de esta función siendo llamada, en este caso con un estado READY de 1.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Figura 2 Un estado ready en 1&lt;/span&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/ready-state_1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/ready-state_1.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Probá este código vos mismo. Ponelo en tu página Web y luego activá tu evento (presionar un botón, salir de un campo con Tab, o cualquier metodo que hayas establecido como disparador el una petición). Tu función de rellamada se va a ejecutar varias veces -- cada vez que el estado ready de la petición cambie-- y vas a ver un alerta por cada estado ready. Esta es la mejor manera de seguir una petición en cada una de sus etapas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114891343264015302?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114891343264015302/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114891343264015302' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114891343264015302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114891343264015302'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/05/traduccin-de-artculo-de-ajax-xiv.html' title='Traducción de Artículo de Ajax XIV'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114891010866775154</id><published>2006-05-29T10:20:00.000-03:00</published><updated>2006-11-14T15:25:32.228-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XIII</title><content type='html'>&lt;span style="font-weight: bold;"&gt;En Conclusión&lt;/span&gt;&lt;br /&gt;Ya estarás un poco cansado del XMLHttpRequest --rara vez leo un artículo entero sobre un solo objeto, especialmente uno que es tan simple. Sin embargo, vas a usar este objeto una y otra vez en cada página y aplicación que escribas donde uses Ajax. En verdad, todavía queda algo por decir sobre XMLHttpRequest. En próximos artículos, vas a aprender a usar POST ademas de GET en tus peticiones, establecer y leer contenidos de cabeceras en tus petición así como en la respuesta del servidor; vas a entender como codificar tus peticiones y también menjar XML en tu modelo petición/respuesta.&lt;br /&gt;Un poco mas adelante vas a ver también algunos de los cajas de herramientas populares que están disponibles. Estas cajas de herramientas abstraen realmente la mayor parte de los detalles discutidos en este artículo y hacen la programación de Ajax más fácil. Puede ser que incluso te preguntes porqué tenés que códificar todo este detalle de bajo nivel cuando las cajas de herramientas estan tan fácilmente disponibles. La respuesta es, él es terriblemente durodarse cuenta que está mal en tu aplicación si no entendes qué está pasando en tu aplicación.&lt;br /&gt;Por eso no ignores estos detalles o pases rapidamente por ellos; cuando tu práctico-excelente caja de herramientas crea un error, te no detengas racando tu cabeza y mandando un email a la ayuda. Con una comprensión de cómo utilizar XMLHttpRequest directamente, encontrarás fácil eliminar errores y arreglar incluso los problemas más extraños. Las cajas de herramientas están muy bien a menos que cuentes con ellas para resolver todos tus problemas.&lt;br /&gt;Entonces ponete con XMLHttpRequest. De hecho, si tienes en funcionamiento código de Ajax que utilice una caja de herramientas, intenta reescribirla usando solo el objeto XMLHttpRequest y sus propiedades y métodos. Será un gran ejercicio y te ayudará probablemente a entender qué está pasando mucho mejor.&lt;br /&gt;En el artículo siguiente, indagarás incluso más profundo en este objeto, explorando algunas de sus características particulares (como responseXML), así como tambien cómo utilizar peticiones POST y enviar datos en diversos formatos. Entonces empezá a codificar y chequée acá en alrededor de un mes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114891010866775154?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114891010866775154/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114891010866775154' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114891010866775154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114891010866775154'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/05/traduccin-de-artculo-de-ajax-xiii.html' title='Traducción de Artículo de Ajax XIII'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114891431854596843</id><published>2006-05-29T04:49:00.000-03:00</published><updated>2006-11-14T15:25:32.411-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XII</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Códigos de estado del HTTP&lt;/span&gt;&lt;br /&gt;A pesar del exito aparente en el código del listing 12, todavía hay un problema -- que pasa si el servidor responde a tu petición y termina de procesar, pero reporta un error? Recuerda, el código del lado servidor debería tener en cuenta si esta siendo llamado por Ajax, JSP, un formulario HTML común, o cualquier otro tipo de código; solo tiene los métodos especificos Web tradicionales de reportar información. Y en el mundo Web, códigos HTTP pueden tratar con varias cosas que pueden pasar en una petición.&lt;br /&gt;Por ejemplo, has ingresado una petición para una URL, escribis mal la URL, y recibes un código de error 404 que indica que la página está perdida. Este es uno de tantos códigos de error que una petición HTTP puede recibir como estatus (ver Recursos por un link a una lista completa de códigos de estado). 403 y 401, ambos indican información segura u prohibidaesta siendo accedida, también son comunes. En cada uno de esos casos, son códigos que resultan de una&lt;br /&gt;respuesta completa. En otras palabras, el servidor completa la petición (significa que el estado ready es 4), pero es probable que no devuelva la informacion deseada por el cliente.&lt;br /&gt;Además del estado ready, tambien necesitas chequear el estado HTTP. Estas buscando al código de estado 200 que simplemente significa correcto. Con un estado ready 4 y un código de estado de 200, estas listo para procesar la información del servidor y esa información debería ser lo que pediste (y no un error u otro tipo de información problemática). Agrega otro control de estado a tu método de rellamado como se muestra en el listing 14.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 14. Controlar el código de estado HTTP&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage() {&lt;br /&gt;if (request.readyState == 4)&lt;br /&gt;if (request.status == 200)&lt;br /&gt;alert("Server is done!");&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Para agregar un manejo de error más robusto --con minimas complicaciones-- deberias agregar un control o dos para otros códigos de estado; ver la version modificada de updatePage() en el listing 15.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Listing 15. Agregar algún control de error liviano.&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage() {&lt;br /&gt;if (request.readyState == 4)&lt;br /&gt;if (request.status == 200)&lt;br /&gt;alert("Server is done!");&lt;br /&gt;else if (request.status == 404)&lt;br /&gt;alert("Request URL does not exist");&lt;br /&gt;else&lt;br /&gt;alert("Error: status code is " + request.status);&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Ahora cambiar el URL en tu getCustomerInfo() a una URL no existente y vean que pasa. Deberias ver una alerta que te diga que el URL que solicitaste no existe -- perfecto! Dificilmente vaya a controlar toda condición de error, pero en una cambio simple que cubre el 80% de los problemas que pueden ocurrir en una típica aplicación Web.&lt;p&gt;&lt;/p&gt;&lt;span style="font-weight: bold;"&gt;Leer el texto de respuesta&lt;/span&gt;&lt;br /&gt;Ahora que te aseguraste de que la petición fue procesada completamente (a traves del estado ready) y el servidor te da una respuesta normal y lista (a traves de el código de estado), podes finalmente trabajar con la información devuelta por el servidor. Esta es convenientemente almacenada en la propiedad responseText del objeto XMLHttpRequest.&lt;br /&gt;Detalles sobre como se ve el texto en responseText, en terminos de formato o tamaño, es intensionalmente vago. Esto permite al servidor establecer este texto a virtualmente cualquier cosa. Por ejemplo, un script puede retornar valores separados con coma, otro valores separados con pipe (el pipe es el caracter |) y otro podria retornar una larga cadena de texto. Todo está en el servidor.&lt;br /&gt;En el caso del ejemplo usado en este artículo, el servidor devuelve la última orden del cliente y luego su dirección, separadas por el simbolo |. La orden y la dirección son usados para establecer los valores de elementos en el fomulario; el listing 16 muestra el código que actualiza la pantalla.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Listing 16. tratar con la respuesta del servidor.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;if(request.readyState==4){&lt;br /&gt;if(request.status ==200) {&lt;br /&gt;var response = request.responseText.split("|");&lt;br /&gt;document.getElementById("order") .value = response[0];&lt;br /&gt;document.getElementById("adress").innerHTML =&lt;br /&gt;response[1].replace(/\n/g,"&lt;br /&gt;");&lt;br /&gt;}else&lt;br /&gt;alert("el estado es "+request.status);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Primero, el responseText es extraido y separado en los simbolos | usando el metodo JavaScript split(). El arreglo de valores resultante, es volcado en response. El primer valor --la última orden del cliente-- se accede en el arreglo como response[0],y es establecido como el valor del campo con un ID "orden". El segundo valor en el arreglo, en response[1] es la dirección del cliente y requiere un poco más de procesamiento. Como las lineas en la direccion están separadas por separadores de linea normales (el caracter \n), el código necesita remplazar estas con separadores de lineas estilo XHTML, &amp;lt;br /&amp;gt;s. Esto se realizo a traves del uso de la funcion replace() junto con una expresion regular. Finalmente, el texto modificado se establece como el HTML interior de un div en el fomulario HTML. El resultado es que el formulario es actualizado de repente con la información del cliente, como puedes ver en la figura 4.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;img alt="The Break Neck form after retrieving customer data" src="http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro2/info.jpg" style="font-family: verdana,arial,helvetica,sans-serif;" height="422" width="450" /&gt;&lt;/div&gt;&lt;br /&gt;Antes de concluir, otra  propiedad importante del XMLHttpRequest se llama responseXML. Esta propiedad contiene (podes adivinar?) una respuesta XML en el evento de donde el servidor elija  responder con XML. Trabajar con una respuesta XML es un tanto distinto que trabajar con una repuesta de texto plano, e involucra análisis, el Modelo de Objetos de documento (DOM) y otras varias consideraciones. Vas a aprender más sobre XML en un  artículo futuro. Además, por que responseXML comunmente aparece en discuciones alrrededor de responseText, vale la pena  mencionarlo acá. Para muchas aplicaciones simples de Ajax es todo lo que necesitas, pero pronto vas a aprender a manejar XML a travez de aplicaciones Ajax también.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114891431854596843?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114891431854596843/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114891431854596843' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114891431854596843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114891431854596843'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/05/traduccin-de-artculo-de-ajax-xii.html' title='Traducción de Artículo de Ajax XII'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114832094731899148</id><published>2006-05-22T07:59:00.000-03:00</published><updated>2006-11-14T15:25:32.139-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax XI</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Manipulación de respuestas del servidor&lt;/span&gt;&lt;br /&gt;Hiciste tu petición, tu usuario esta trabajando felizmente en el formulario Web (mientras el servidor tranaha en la petición), y ahora el servidor termina de tratar la petición. El servidor se fija en la propiedad onreadystatechange y detecta que método llamar. Una vez que eso ocurre, podes pensar en tu aplicación como en cualquier otra, asincrónica o no. En otras palabras, no tenes que tomar ninguna acción especial escribiendo métodos que respondan al servidor; solo cambiá el formulario, enviá al usuario a otra URL o hacé lo que necesites con la respuesta del servidor. En esta sección nos centraremos en responder al servidor y luego tomar una acción típica --cambiar al vuelo parte del formulario que ve el usuario.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Rellamadas y Ajax&lt;/span&gt;&lt;br /&gt;Ya viste como hacer saber al servidor que hacer cuando termina: fijar la propiedad onreadystatechange del objeto XMLHttpRequest al nombre de la funcion a ejecutar. Luego, cuando el servidor haya procesado la petición, va a llamar automaticamente esa función. Tampoco necesitás preocuparte de ningún parámetro para ese método. Vas a empezar con un método simple como en el Listing 12.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Listing 12. Código del método de rellamada&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;script language="javascript" type="text/javascript"&amp;gt;&lt;br /&gt;var request = false;&lt;br /&gt;try {&lt;br /&gt;request = new XMLHttpRequest();&lt;br /&gt;} catch (trymicrosoft) {&lt;br /&gt;   try {&lt;br /&gt;       request = new ActiveXObject("Msxml2.XMLHTTP");&lt;br /&gt;   } catch (othermicrosoft) {&lt;br /&gt;       try {&lt;br /&gt;           request = new ActiveXObject("Microsoft.XMLHTTP");&lt;br /&gt;               } catch (failed) {&lt;br /&gt;                       request = false;&lt;br /&gt;                   }&lt;br /&gt;               }&lt;br /&gt;          }&lt;br /&gt;if (!request)&lt;br /&gt;alert("Error al inicializar XMLHttpRequest!");&lt;br /&gt;function getCustomerInfo() {&lt;br /&gt;var phone = document.getElementById("phone").value;&lt;br /&gt;var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);&lt;br /&gt;request.open("GET", url, true);&lt;br /&gt;request.onreadystatechange = updatePage;&lt;br /&gt;request.send(null);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function updatePage() {&lt;br /&gt;alert("El servidor terminó!");&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Esto solo dispara una alerta útil, para decirte cuando termina el servidor. Prueba este código en tu propia página, guarda la página y luego tirala en un navegador (si queres XHTML de este ejemplo, ver el listing 8) cuando ingreses un número de teléfono y dejes el campo, deberías ver la ventana de alerta (ver figura 3); pero si presionás OK va a aparecer otra vez... y otras.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Figura 3: Código de Ajax mostrando una ventana de alerta&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro2/alert.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro2/alert.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Dependiendo de su navegador, vas a tener dos, tres, o aún cuatro alarmas antes de el formulario pare de mostrar alarmas.  ¿Qué se está pasando?  Resulta que no has considerado el estado ready del HTTP, un componente importante del ciclo de peticion/respuesta.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Estados ready de HTTP&lt;/span&gt;&lt;br /&gt;Antes, dije que el servidor, una vez que termina con una petición, busca qué método  llamar en la propiedad onreadystatechange de XMLHttpRequest. Eso es verdad, pero no es toda la verdad. De hecho, llama a ese método cada vez que el estado READY del HTTP cambia.  ¿Qué significa?  Bien, tenes que entender los estados READY del HTTP primero.&lt;br /&gt;Un estado READY del HTTP indica el estado o situacion de una petición. Se utiliza para reconocer si se ha comenzado una petición, si se está contestando, o si el modelo de petición/respuesta ha terminado. Es también útil en la determinación de si es seguro leer cualquier texto o datos de la respuesta que un servidor pudo haber provisto.  Necesitas saber sobre los cinco estados READY en tus aplicaciones Ajax.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=""&gt;0: La petición está sin inicializar (antes de que hayas llamado a open())&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=""&gt;1: La petición esta seteada, pero no ha sido enviada (antes de que hayas llamado a send())&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=""&gt;2: La petición fue enviada y está siendo procesada (normalmente podes obtener el contenido cabecera de la respuesta a este punto)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=""&gt;3: La petición está siendo procesada; a menudo alguna informacion parcial de la respuesta está disponible, pero el servidor todavía no ha terminado con esa respuesta.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=""&gt;4: La respuesta está completa; podes tomar la respuesta del servidor y usarla.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Como la mayoria de los asuntos de multi-navegador, estos estados ready son usados un poco incosistentemente. Esperarias ver siempre los estados ready moverse desde 0 a 1 a 2 a 3 a 4, pero en la práctica, es raramente el caso. Algunos navegadores nunca reportan 0 o 1 y saltan directamente al 2, después al 3 y luego al 4. Otros navegadores reportan todos los estados. Ademas otros van a reportar el estado 1 varias veces. Como ves en la ultima sección, el servidor llama al updatePage() varias veces, y cada invocación resulta en una caja de alerta mostrandose --probablemente no como querías!&lt;br /&gt;Para la programación Ajax, el unico estado con el que necesitas tratar es el estado ready 4, que indica que la respuesta del servidor está completa y es segura para ver la información de respuesta y usarla. A cuenta de esto, la primera línea en el método de rellamada deberia ser como se muestra en el listing 13&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Listing 13. Check the ready state&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage() {&lt;br /&gt;if (request.readyState == 4)&lt;br /&gt;alert("Server is done!");&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Este cambio comprueba para asegurarse de que el servidor realmente haya acabado con el proceso. Intenta ejecutar esta versión del código Ajax y solamente deberías obtener el mensaje alerta una vez, que es como debe ser.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114832094731899148?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114832094731899148/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114832094731899148' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114832094731899148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114832094731899148'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/05/traduccin-de-artculo-de-ajax-xi_22.html' title='Traducción de Artículo de Ajax XI'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114539594159674418</id><published>2006-04-18T18:31:00.000-03:00</published><updated>2006-11-14T15:25:31.876-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax X</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Especificando un metodo de rellamada&lt;/span&gt;&lt;br /&gt;En este punto has hecho bastante poco que se sienta como nuevo, revolucionario o asincronico. Concedido, esa pequeña clave "true" en el método open() establece una peticion asincronica. Pero ademas de eso, este codigo se parece a la programacion con servlets Java y JSPs, PHP o Pearl. Entonces, ¿cuál es el gran secreto de Ajax y Web 2.0?  EL secreto da vueltas sobre una simple propiedad de XMLHttpRequest llamada onreadystatechange.&lt;br /&gt;Primero asegurate de que entiendas el proceso que creaste en este código (revisa el listing 10 si lo necesitas). Una petición es seteada y luego hecha. Además, a causa de que esta es una peticion sincrónica, el método Javascript (getCustomerInfo() en el ejemplo) no va a esperar al servidor. Entonces el código va a continuar; en este caso, esto significa que el método va a salir y el control va a volver al formulario. Los usuarios pueden continuar ingresando información y la aplicación no va a esperar al servidor.&lt;br /&gt;Esto crea una interesante pregunta, sin embargo: ¿qué pasa cuando el servidor termina de procesar la petición?. La respuesta, el menos tal como el código esta hasta ahora, es nada!. Obviamente, eso no es bueno, por eso el servidor necesita tener algún tipo de instrucción sobre que hacer cuando termine de procesar la peticion enviada a traves del XMLHttpRequest.&lt;br /&gt;Aca es donde la propiedad onreadystatechange entra en juego. Esta propiedad te permite especificar un método de rellamada. Una rellamada permite al servidor (puedes adivinar) rellamar al código de tu página web.Le da un grado de control al servidor, tambien; cuando el servidor termina una petición, se fija en el objeto XMLHttpRequest y especificamente en la propiedad onreadystatechange. Cualquier método espsificado por esa propiedad es inbocado. Es una rellamada por que el servidor inicia una llamada de vuelta a la pagina Web --sin importar lo que este pasando en la pagina misma. Por ejemplo, podría llamar a este metodo mientras el usuario está sentado en su silla, sin tcar el teclado; sinembargo, tambien podría llamarlo cuando el usuario está tipeando, miviendo el mouse, moviendo la ventana, presionando un botón... no importa que esté haciendo el usuario.&lt;br /&gt;Acá es realmente cuando la asincronicidad entra en juego: el usuario opera el formulario en un nibvel mientras en otro nivel, el servidor responde una petición y luego dispara  el método de rellamada indicado por la propiedad onreadystatechange. Entonces necesitas especificar ese netodo en tu código como se muestra en el listing 11.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Listing 11. Establecer un metodo de rellamada&lt;/span&gt;&lt;div class="simple_box"&gt;function getCustomerInfo(){&lt;br /&gt;var phone = document.getElemntById("phone").value;&lt;br /&gt;var url = "/cgi-local/lookupCustomer.php?phone="+escape(phone);&lt;br /&gt;request.open("GET", url, true);&lt;br /&gt;request.onreadystatechange = updatePage;&lt;br /&gt;request.send(null);&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Poner especial atencion a donde en el código se fija esta propiedad --es antes de de la llamada send(). Tenes que fijar esta propiedad antes de que la petición sea enviada, así el servidor puede buscar la prpiedad cuando termine de responder una petición. Todo lo que nos queda es codificar el updatePage() que es el foco de la última sección de este articulo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114539594159674418?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114539594159674418/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114539594159674418' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114539594159674418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114539594159674418'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/04/traduccin-de-artculo-de-ajax-x.html' title='Traducción de Artículo de Ajax X'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114260505515813890</id><published>2006-03-17T10:18:00.000-03:00</published><updated>2006-11-14T15:25:31.790-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de Ajax IX</title><content type='html'>Un acertijo sobre asincronicidad&lt;br /&gt;En un último artículo de esta serie, voy a tomarme un buen tiempo para escribir y usar código asincronico, pero deberías tener una idea de por que el último parametro en open() es tan importante. En un modelo normal de petición/respuesta -pensa en la Web 1.0 acá- el cliente (tu navegador o el código ejecutandose en tu maquina local) hace una petición al servidor. Esa petición es sincrónica, en otras palabras, el cliente espera por la respuesta del servidor. Mientras el clientes está esperando, normalmente ves una de las fomas de notificacion de que está esperando:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;un reloj de arena (especialmente en windows)&lt;/li&gt;&lt;li&gt;Una pelota de playa giratoria (normalmente en máquinas Mac)&lt;/li&gt;&lt;li&gt;La aplicación se congela y a veces el cursor cambia.&lt;/li&gt;&lt;/ul&gt;Esto es lo que hace que las aplicaciones web en particular se sientan pesadas y lentas -- la ausencia de interactividad real. Cuando apretas un boton, tu aplicación se vuelve inutilisable hasta que la peticion que enviaste sea respondida. Si haces una peticion que requiera un importante procesamientos del servidor, la espera puede ser significativa  (al menos para los multiprocesadores, DSL , mundo sin espera de hoy).&lt;br /&gt;Una petición asincrónica sin embargo, no espera a que el servidor responda.  Mandas la petición y luego tu aplicación continúa. Los usuarios pueden cargar información al formalario todavía, presionar otros botones, y hasta dejar el formulario. No hay pelota de playa giratoria o reloj de arena girando  y no hay grandes congelamientos de la aplicacion. El servidor responde silenciosamente y cuando termina, le hace saber al solicitante original que ya está hecho (de maneras que verás en un momento). El resultado final es una aplicacion que no se siente pesada o lenta, al contrario es dinámica, interactiva y se siente mas rápida. Este es solo un componente de la Web 2.0, pero es muy importante. Todos los los componentes GUI pulidos y los paradigmas del diseño web  no pueden superar un lento, sincrónico modelo de petición/respuesta.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Enviar la petición&lt;/span&gt;&lt;br /&gt;Una vez configurada la peticion con open(), estás listo para enviarla. Afortunadamente el metodo para enviar una petición se llama de forma mas apropiada que open(); es llamado simplemente send().&lt;br /&gt;send() tiene un solo parámetro, el contenido a enviar. Pero antes que penses mucho en eso, recuarda que estás listo para mandar informacion a traves de la URL misma:&lt;br /&gt;&lt;blockquote&gt;var= url="/cgi-local/lookupcustomer.php?phone="+escape(phone);&lt;/blockquote&gt;Aunque podés mandar información usando send(), tambien podes mandarla a traves dela URL misma. De hecho, en las peticiones GET (que van a constituir tanto como el 80% de tu uso tipico de Ajax), es mucho mas facil mandar la informacion en la URL. Cuando empezas a mandar información segura o XML, es cuando queres ver como se manda contenido mediante send() (voy a hablar de ambos, informacion segura y envio de XML en uno de los ultimo sarticulos de esta serie). Cuando no necesitas pasar informacion atraves de send(), pasa null como argumento de este metodo. Entonces, para mandar una petición en el ejemplo que has visto en este artículo, eso es exactamente lo que se necesita.  (ver listing10)&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;listing 10: enviar la peticion&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function getCustomerInfo(){&lt;br /&gt; var phone = document.getElementById("phone").value;&lt;br /&gt; var url =  "/cgi-local/lookupCustomer.php?phone=" + escape(phone);&lt;br /&gt; request.open("GET", url, true);&lt;br /&gt; request.send(null);&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114260505515813890?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114260505515813890/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114260505515813890' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114260505515813890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114260505515813890'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/03/traduccin-de-artculo-de-ajax-ix.html' title='Traducción de Artículo de Ajax IX'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114228291508922169</id><published>2006-03-13T16:21:00.000-03:00</published><updated>2006-11-14T15:25:31.709-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo de AJAX VIII</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Enviar peticiones con XMLHttpRequest&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Una vez que tenés tu objeto de petición, podés empezar el ciclo petición/respuesta. Recuerda, el único proposito de XMLHttpRequest es permitirtehacer peticiones y recibir respuestas. Todo lo demás -cambiar la interfaz del usuario, intercambio de imagenes, interpretar la información devuelta por el servidor- es trabajo de Javascript, CSS u otro código en tus paginas. Con XMLHttpRequest listo para usar, podes hacer una petición al servidor.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Bienvenido al cajón de arena&lt;/span&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-weight: bold;"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Ajax tiene un modelo de seguridad sandbox. Como resultado, tu código Ajax (y especificamente, el objeto XMLHttpRequest) solamente puede hacer peticiones en el servidor en el cual esta ejecutandose. Vas a aprender mucho más sobre seguridad y Ajax en un artículo próximo, pero por ahora tené en cuenta que el código ejecutandose en tu máquina local solo puede hacer peticiones al los scripts del lado servidor en tu máquina local.  Si tenés código Ajax ejecutandose en www.breakneckpizza.com, deberá hacer peticiones a los scripts que se ejecutan en www.breackneckpizza.com.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Establecer la URL del servidor&lt;/span&gt;&lt;br /&gt;La primera cosa que necesitas determinar el la URL para conectarse con el servidor. Esto no es especifico de Ajax -obviamente ya tenes que saber como contruir una URL- pero es esencial para hacer una conexión. En la mayoria de las aplicacione, contruirias la URL con algo de información estática convinada con información del formulario con el que trabajan tus usuarios. Por ejemplo, el listing 7 muestrs algo de JavaScript que toma el valor del campo del número de teléfono y luego construye una URL usando esa información.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Listing 7. Construir una URL de petición&lt;br /&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;script language="javascript" type="text/javascript"&amp;gt;&lt;br /&gt;var request = false;&lt;br /&gt;try {&lt;br /&gt;request = new XMLHttpRequest();&lt;br /&gt;} catch (trymicrosoft){&lt;br /&gt;try {&lt;br /&gt;               request=new ActiveXObject("Msxml2.XMLHTTP");&lt;br /&gt;   } catch(othermicrosoft) {&lt;br /&gt;              try {&lt;br /&gt;                           request= new ActivexObject("Microsoft.XMLHTTP");&lt;br /&gt;               } catch (failed) {&lt;br /&gt;                 request = false;&lt;br /&gt;         }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;if (!request)&lt;br /&gt;alert("Error al inicializar XMLHttpRequest!");&lt;br /&gt;&lt;br /&gt;function getCustomerInfo(){&lt;br /&gt;var phone = document.getElementById("phone").value;&lt;br /&gt;var url = "cgi-local/lookupCustomer.php?phone=" + escape(phone);&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/div&gt;&lt;/blockquote&gt;Nada de esto debería confundirte. Primero, el código crea una nueva variable llamada phone y le asigna el valor del campo del formulario con el id igual a phone. El listing 8 muestra el XHTML para este formulario en particular donde podés ver el campo phone y su atributo id.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Listing 8. El formulario de Break Neck Pizza&lt;br /&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&amp;lt;img src="breakneck-logo_4c.gif" alt = "Breack Neck Pizza" /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;form action ="POST"&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&lt;br /&gt;  &amp;lt;input type = "text" size="14" name="phone" id="phone" onChange="getCustomerInfo();" /&amp;gt;&lt;br /&gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;YOur order will be delivered to:&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;div id="address"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;Type your order here&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&amp;lt;textarea name="order" rows="6" cols="50" id="order"&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&amp;lt;input type = "submit" value "Order Pizza" id="submit"/&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;/div&gt;&lt;/blockquote&gt;Tambien fijense que  cuando el usuario ingresa su número de teléfono o lo cambia, dispara el método getCustomerInfo() mostrado en el listing 7. Ese método toma el numero y lo usa para construir una cadena URL, guardada en la variable URL. Recuerda, dado que el codigo Ajax tiene caja de arena y solo se puede conectar con el mismo servidor, no necesitarías  el nombre deldominio en tu URL. En este ejemplo, el nombre del script es /cgi-local/lookupCustomer.php. Finalemnte, el número de teléfono es asociado a este script como un parámetro GET: "phone="+escape(phone).&lt;br /&gt;Si no habías visto antes el método escape() , se usa para deschar todo caracter que no pueda ser enviado correctamente como texto. Por ejemplo, cualquier especio en el nuemro de telefono es convertido a los caracteres %20, haciendo posible el pasaje de los caracteres a traves de la URL.&lt;br /&gt;Podes agregar tantos parametros como necesites. Por ejemplo, si queres agregar otro parametro, solo asocialo en la URL y separa los parametroscon el caracter ampersans &amp; (el primer parametro es separado del nombre del script con un signo de pregunta ?)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Abriendo la petición&lt;/span&gt;&lt;br /&gt;Con una URL para conectarse, podés configurar la petición. Lo logras usando el método open() de tu objeto XMLHttpRequest. Este método tiene tantos como 5 parámetros:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;request-type: el tipo de petición a enviar. los valores tipicos son GET o POST, pero tambien podes mandar peticiones HEAD&lt;br /&gt;&lt;/li&gt;&lt;li&gt;url: LaURL para contectarse&lt;br /&gt;&lt;/li&gt;&lt;li&gt;asynch: Verdadero (true) que la petición sea asincrónica y falso (false) si tiene que ser una peticion sincrónica. Este parametro es opcional y por defecto es verdadero.&lt;/li&gt;&lt;li&gt;username: si se requiere autenticacion, podes especificar el nombre de usuario acá. Es un parametro opcional y no tiene valor por defecto.&lt;/li&gt;&lt;li&gt;password:  si se requiere autenticacion, podes especificar la contraseña acá. Es un parametro opcional y no tiene valor por defecto.&lt;/li&gt;&lt;/ul&gt;Tipicamenter, vas a usar en primero de los tres. De hecho, hasta cuando quieras una peticion asincronica, deberías espesificar verdadero como tercer parametro. Ese es el valor por defecto , pero es un buen poco de auto-documentación para indicar si la peticion es asincronica o no.&lt;br /&gt;Ponelo todo junto y normalemnte terminar con una linea que se ve como el listing 9:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Listing 9. Abrir la peticion&lt;br /&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;function getCustomerInfo(){&lt;br /&gt;var phone = document.getElementById("phone").value;&lt;br /&gt;var url = "cgi-local/lookupCustomer.php?phone=" + escape(phone);&lt;br /&gt;request.open("GET", url, true);&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Una vez que tenes la URL resulta, esto es bastante simple. Para la mayoria de las peticiones, usar GET es suficiciente (vas a ver situaciones en las cuales usarías post en articulos futuros); esto, junto con la URL, es todo lo que necesitas para usar open().&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;1. &lt;a href="http://computing-dictionary.thefreedictionary.com/sandbox"&gt;sandbox&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114228291508922169?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114228291508922169/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114228291508922169' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114228291508922169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114228291508922169'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/03/traduccin-de-artculo-de-ajax-viii.html' title='Traducción de Artículo de AJAX VIII'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114176718971226443</id><published>2006-03-07T16:29:00.000-03:00</published><updated>2006-11-14T15:25:31.620-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de artículo de Ajax VII</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Estático versus dinámico&lt;/span&gt;&lt;br /&gt;Fijate en los Listing 1, 3 y 4 y observá que todo el código está anidado directamente entre etiquetas script. Cuando JavaScript es codificado así y no puesto dentro un método  o en el cuerpo de una función, se llama JavaScript estático. Esto significa que el código se ejecuta a veces antes que la página se muestre al usuario (no es 100% claro desde la especificación precisamente de  cuando este código se ejecuta y los navegadores hacen diferentes las cosas; igual te garantiza que el código se ejecuta antes que los usuarios puedan interactuar con tu página). Es como generalmente la mayoría de los programadores de Ajax crean el objeto XMLHttpRequest.&lt;br /&gt;Dicho esto, indudablemente podés poner este código en un método como se muestra en el listing 5&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Listing 5. Mover el código de creación XMLHttpRequest dentro de un método&lt;br /&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;script language="javascript" type="text/javascript"&amp;gt;&lt;br /&gt;var request;&lt;br /&gt;function createRequest () {&lt;br /&gt;  try {&lt;br /&gt;     request = new XMLHttpRequest();&lt;br /&gt; } catch (trymicrosoft){&lt;br /&gt;       try {&lt;br /&gt;               request=new ActiveXObject("Msxml2.XMLHTTP");&lt;br /&gt;       } catch(othermicrosoft) {&lt;br /&gt;              try {&lt;br /&gt;                       request= new ActivexObject("Microsoft.XMLHTTP");&lt;br /&gt;               } catch (failed) {&lt;br /&gt;             request = false;&lt;br /&gt;         }&lt;br /&gt;       }&lt;br /&gt; }&lt;br /&gt; if (!request)&lt;br /&gt;   alert("Error al inicializar XMLHttpRequest!");&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Con el código dispuesto como este, vas a necesitar llamar el método antes de que hagas algun trabajo Ajax. Entonces deberías tener algo como el listing 6&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Listing 6. Usar un método de creación de XMLHttpRequest&lt;br /&gt;&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;script language="javascript" type="text/javascript"&amp;gt;&lt;br /&gt;var request;&lt;br /&gt;function createRequest () {&lt;br /&gt;  try {&lt;br /&gt;     request = new XMLHttpRequest();&lt;br /&gt; } catch (trymicrosoft){&lt;br /&gt;       try {&lt;br /&gt;               request=new ActiveXObject("Msxml2.XMLHTTP");&lt;br /&gt;       } catch(othermicrosoft) {&lt;br /&gt;              try {&lt;br /&gt;                       request= new ActivexObject("Microsoft.XMLHTTP");&lt;br /&gt;               } catch (failed) {&lt;br /&gt;             request = false;&lt;br /&gt;         }&lt;br /&gt;       }&lt;br /&gt; }&lt;br /&gt; if (!request)&lt;br /&gt;   alert("Error al inicializar XMLHttpRequest!");&lt;br /&gt;}&lt;br /&gt;function getCustomerInfo();&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;El único tema con este código - y la razón por la cual la mayorías de los programadores de Ajax no usan esta forma- es que retarda la notificación de error. Supongamos que tenés un formulario complejo con 10 o 15 campos, cajas de selección y similares, y disparas algo de código Ajax cuando el usuario ingresa texto en el campo 14 (al final del formulario). A ese punto, getCustomerInfo() se ejecuta, trata de crear un objeto XMLHttpRequest y (para este ejemplo) falla. Entonces se escupe un alerta al usuario, diciéndole (en varias palabras) que no puede usar esta aplicación  Pero el usuario ya gastó su tiempo ingresando información en el formulario! Eso es bastante molesto y molestia no es algo que típicamente atraiga a los usuarios a volver a tu sitio. &lt;br /&gt;En el caso donde usas JavaScript estático, el usuario va a ver un error apenas entre a la página. ¿eso es molesto tambien? Probablemente; puede hacer que los usuarios se enojen por que tu aplicacion no funciones en sus navegadores. Sin embargo,  indudablemente es mejor que tirarle el mismo error despues de que se gastó 10 minutos ingresando información. Por esa sola razón, te propongo establecer tu códgo estaticamente e informarles a los usuarios de forma tamprana sobre posibles problemas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114176718971226443?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114176718971226443/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114176718971226443' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114176718971226443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114176718971226443'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/03/traduccin-de-artculo-de-ajax-vii.html' title='Traducción de artículo de Ajax VII'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114175555461408783</id><published>2006-03-07T15:17:00.000-03:00</published><updated>2006-11-14T15:25:31.433-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de artículo sobre Ajax VI</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Introducción al XMLHttpRequest&lt;/span&gt;&lt;br /&gt;Para hacer que esta maravilla suceda, necesitás familiarizarte íntimamente con un objeto JavaScript llamado XMLHttpRequest. Este pequeño objeto -que realmente ha estado en varios navegadores hace bastante tiempo- es la clave de Web 2.0, Ajax y casi todo lo demás que vas a aprender en esta columa por lo próximos meses. Para darte una rápida vista, estos son solo algunos de los métodos y propiedades que vas a usar en este objeto:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;open()&lt;/span&gt;: establecer una nueva petición a un servidor&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;send()&lt;/span&gt;: enviar una petición al servidor&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;abort()&lt;/span&gt;: Escapar de la petición actual&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;readystate&lt;/span&gt;: provee el estado correcto del HTML actual&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;responseText&lt;/span&gt;: El texto que el servidor devuelve al responder una petición.&lt;/li&gt;&lt;/ul&gt;No te preocupes si no las entendés todas (o algunas para el caso) vas a aprender sobre cada método y propiedad en próximos artículos. Lo que deberías sacar de esto es una buena idea de que hacer con XMLHttpRequest. Observa que cada uno de esos métodos y propiedades se relacionan con mandar una petición y tratar con la respuesta. De hecho, si mirás cada método y propiedad de XMLHttpRequest, estarán todas relacionadas a ese tan simple modelo petición/respuesta. Por eso claramente, no vas a aprender sobre un sorprendente objeto GUI nuevo o alguna clase de avance super secreto para crear interacción con el usuario; vas a trabajar con simples peticiones y simples respuestas. Puede ser que no suene exitante, pero el uso cuidadoso de este objeto puede cambiar totalmente tus aplicaciones.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;La simplicicidad de lo nuevo&lt;/span&gt;&lt;br /&gt;Primero, necesitás crear una nueva variable y asignarle una instancia del objeto XMLHttpRequest. Eso es bastante simple en JavaScript; solo usa la nueva palabra clave con el nombre del objeto, como ves en el linsting 1&lt;br /&gt;&lt;blockquote&gt;&lt;small style="font-weight: bold;"&gt;Listing 1. Crear un nuevo objeto XMLHttpRequest&lt;/small&gt;&lt;div class="simple_box"&gt;&amp;lt;script language="javascript" Type="text/javascript"&amp;gt;&lt;br /&gt;var request= new XMLHttpRequest();&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/div&gt;&lt;/blockquote&gt;No es tan difícil, ¿no?. Recuerda, JavaScript no requiere que ingreses algo en sus variables, por eso no necesitas nada como lo que ven en Listing 2 (que sería como deberías crear este objeto en Java)&lt;br /&gt;&lt;blockquote&gt;&lt;small style="font-weight: bold;"&gt;Listing 2. Crear un nuevo objeto XMLHttpRequest&lt;/small&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;XMLHttpRequest request= new XMLHttpRequest();&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Entonces creaste la variable en Javascript con &lt;span style="font-style: italic;"&gt;var&lt;/span&gt;, dandole un nombre (como "request") y despues le asignaste una nueva instancia de XMLHttpRequest. En esete punto, ya estas listo para usar el objeto en sus funciones.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Manejo de error&lt;/span&gt;&lt;br /&gt;En la vida real, las cosas puede ir mal y este código no provee ningún manejo de error. Una pequeña mejora es crear este objeto y tener una salida elegante si algo sale mal. Por ejemplo, muchos navegadores viejos  (aunque no lo creas, la gente todavía sigue usando versiones viejas de Netscape Navigator) no soportan XMLHttpRequest y necesitás hacerles saber que algo anda mal. El listing 3 muestra como deberías crear este objeto para que si algo falla, tire una alerta de JavaScript. &lt;blockquote&gt;&lt;small style="font-weight: bold;"&gt;Listing 3. Crear XMLHttpRequest con algunas habilidades de tratamiento de error&lt;/small&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&amp;lt;script language="javascript" type="text/javascript"&amp;gt;&lt;br /&gt;var request = false;&lt;br /&gt;try {&lt;br /&gt;   request = new XMLHttpRequest();&lt;br /&gt;} catch (failed) {&lt;br /&gt;   request = false;&lt;br /&gt;}&lt;br /&gt;if (!request)&lt;br /&gt;   alert("Error al inicializar XMLHttpRequest!");&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Asegurate de entender cada uno de estos pasos:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Crear una nueva variable llamada request y asignarle un valor falso (false). Vas a usar falso como condición que signifique que el objeto XMLHttpRequest no haya sido creado todavía.&lt;/li&gt;&lt;li&gt;Agregarlo en un bloque try/catch&lt;/li&gt;&lt;ol&gt;&lt;li&gt;tratar y crear el objeto XMLHttpRequest&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Si eso falla (catch(failed)), asegurate que request todavía sea falso.&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Control si request es falso (si las cosas salen bien no lo será)&lt;/li&gt;&lt;li&gt;Si hubo un problema (y request es falso), usa un alerta JavaScript para decirle al usuario que hubo un problema.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Es bastante simple; es mas largo de leer y escribir, que de entender para la mayoría de los desarrolladores JavaScript y Web. Ahora tenes una piesa de código a prueba de error que crea un objeto XMLHttpRequest y hasta te avisa si algo sale mal.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lidiar con Microsoft&lt;/span&gt;&lt;br /&gt;Todo esto se ve bastante bien... por lomenos hasta que pruebes tu código en Internet Explorer. Si lo haces, vas a obtener algo tan feo como en la figura 1:&lt;br /&gt;&lt;blockquote&gt;figura 1: Internet Explorer reportando un error.&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;img src="http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro2/ie_broken.jpg" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt; Claramente, algo no está funcionando. Internet Explorer es duramente un navegador desactualizado y alrededor del 70% del mundo lo usa. En otras palabras, no harías bien en el mundo Web si no soportaras Microsoft e Internet Explorer! Por eso, necesitas una mejora diferente para lidiar con navegadores Microsoft.&lt;br /&gt;Resulta que Microsoft soporta Ajax, pero llaman a su versión de XMLHttpRequest algo diferente. De hecho lo llaman de diferentes formas. Si estás usando una version nueva de IE, necesitas usar un objeto llamado Msxml2.XMLHTTP; algunas versiones mas viejas usan Microsoft.XMLHTTP. Necesitas soportar esos dos tipos de objetos (sin perder el soporte que ya tenes para los navegadores no-Microsoft). Revisa el listing 4 que agrega soporte para Microsoft al código que ya habías visto.&lt;br /&gt;&lt;blockquote&gt;&lt;small style="font-weight: bold;"&gt;Listing 4. Agregar soporte para los navegadores Microsoft&lt;/small&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&amp;lt;script language="javascript" type="text/javascript"&amp;gt;&lt;br /&gt;var request = false;&lt;br /&gt;try {&lt;br /&gt;   request = new XMLHttpRequest();&lt;br /&gt;} catch (trymicrosoft){&lt;br /&gt;   try {&lt;br /&gt;       request=new ActiveXObject("Msxml2.XMLHTTP");&lt;br /&gt;   } catch(othermicrosoft {&lt;br /&gt;      try {&lt;br /&gt;           request= new ActivexObject("Microsoft.XMLHTTP");&lt;br /&gt;       } catch (failed) {&lt;br /&gt;           request = false;&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;if (!request)&lt;br /&gt;   alert("Error al inicializar XMLHttpRequest!");&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;Es fácil perderse en estos vericuetos, por eso los guio a traves de ellos un paso por vez:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Crear una nueva variable llamada request y asignarle un valor falso (false). Usar el valor falso como condición para indicarque el objeto XMLHttpRequest no ha sido creado todavía.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Agregar el bloque try/catch&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Probar  y crear un objeto XMLHttpRequest&lt;/li&gt;&lt;li&gt;Si falla (catch(trymicrosoft))&lt;/li&gt;&lt;li&gt;Probar  y crear un objeto compatible con Microsoft usando las más nuevas versiones de Microsoft (Msxml2.XMLHTTP)&lt;/li&gt;&lt;li&gt;Si falla (catch(othermicrosoft)), probar y crear un objeto compatible con Microsoft usando la version mas vieja de Microsoft (Microsoft.XMLHTTP)&lt;/li&gt;&lt;li&gt;Si aún falla, asegurate de que request siga establecida en falso&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Verifica si request es todavia falso (si las cosa están bien, no será)&lt;/li&gt;&lt;li&gt;Si hay un problema (y request es falso), usa un alerta de Javascript para avisarles a los usuarios que hay un problema.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Has esos cambios a tu código y prueba las cosas en IE otra vez; deberías ver el formularioque creaste (sin mensaje de error). En mi caso, resulto algo como en la figura 2.&lt;br /&gt;&lt;blockquote&gt;Figura 2: Internet Explorer trabajando normalmente&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&lt;img src="http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro2/ie_fixed.jpg" /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114175555461408783?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114175555461408783/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114175555461408783' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114175555461408783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114175555461408783'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/03/traduccin-de-artculo-sobre-ajax-vi.html' title='Traducción de artículo sobre Ajax VI'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114141792199031390</id><published>2006-03-03T17:32:00.000-03:00</published><updated>2006-11-14T15:25:31.320-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción del articulo de Ajax V</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Bueno, para seguir con esto, vamos por la &lt;a href="http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro2/index.html"&gt;Parte II&lt;/a&gt; del asunto:&lt;br /&gt;&lt;br /&gt;&lt;big style="font-weight: bold;"&gt;Dominar AJAX, Parte 2: Hacer peticiones asincrónicas con Javascript y Ajax&lt;/big&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Usar XMLHttpRequest para peticiones Web&lt;br /&gt;&lt;/span&gt;Nivel: Intermedio&lt;br /&gt;Brett McLaughlin (brett@oreilly.com), Autor y Editor, O´Reilly y Asociados.&lt;br /&gt;17 Ene 2006&lt;br /&gt;&lt;blockquote&gt;La mayoría de las aplicaciones Web usan un modelo pedido/respuesta que toma una página HTML entera desde el servidor. El resultado es un ida y vuelta que generalmente involucra presionar el botón, esperar al servido, presionar otro botón y esperar un poco más. Con Ajax y el objeto XMLHttpRequestpodés usar un modelo de pedido/respuestaque nunca deja a los usuarios esperando a que un servidor les responda. en este artículo, Brett McLaughlin te muestra como crear instancias XMLHttpRequesten una forma&lt;span style="font-style: italic;"&gt; multi-navegador &lt;/span&gt;, construir y enviar peticiones  y respuestas al servidor.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;En el último artículo de esta serie (ver en recursos por links), fuiste introducido a las aplicaciones Ajax y viste algo de los conceptos básicos que manejan las aplicaciones Ajax. En el centro de esto había un monton de tecnología que problablemente ya conocias: JavaScript, HTML and XHTML, un poco de HTML dinámico y tambien un poco de DOM (Modelo de objeto de documentos). En este artículo voy a focalizar desde esa vista de 10.000 pies y focalizar en detalles especificos de Ajax.&lt;br /&gt;En este artículo, vas a empezar con el mas fundamental y básico de todos los objetos relacionados con Ajax y de mejoras de programación: el objeto XMLHttpRequest. Este objeto es realmente el único hilo en común entre todas las aplicaciones Ajax y , como como debes esperar, vas a querer entenderlo a fondo para llevar tu programación al límite de lo posible. De hecho, vas a descubrir que aveces, para usar XMLHttpRequest apropiadamente, no vas a usar XMLHttpRequest explicitamente. De que se trata todo esto?&lt;br /&gt;Web2.0 de un vistazo&lt;br /&gt;Primero, toma este último pedaito de repaso antes de que te sumerjas en el código, asegurate de tener clara esta idea sobre la Web 2.0. Cuando escuchas el término Web 2.0, deberías preguntar primero ¿que es Web 1.0? Sin Embargo raramente vas a escuchar Web 1.0, esto se refiere a la web tradicional donde se tiene un modelo de petición y respuesta bastante diferente. Por ejemplo, ir a Amazon.com y presionar un botón o ingresar un término de búsqueda. Una petición es hecha el servidor y luego una respuesta vuelve a tu navegador. Esa respuesta tiene mucho más que solo una lista de libros y titulos, sin embargo; realmente es otra página HTLML completa. Como resultado, probablemente tengas algo de destelleos u oscilaciones mientras la pantalla de tu navegador es redibujada con esta nueva página HTML. De hecho podes ver claramente la petición y la respuesta, delineada por cada nueva página que ves.&lt;br /&gt;La Web 2.0 prescinde de esta tan visible ida y vuelta (en un alto grado). Como ejemplo, visitar un sitio como Google maps o Flickr (los links de ambos sitios web 2.0 potenciados con Ajax están de Recursos). En Gogle Maps, por ejemplo, podés mover el mapa con el mouse, ampliar o reducir la vista con muy poco redibujamiento. Por supuesto, se hacen peticion y respuesta aquí, pero todas detras de escena. Como usuario, la experiencia es mucho mas agradable y se siente mucho como una aplicación de escritorio. Esta nueva sensacion y paradigma es lo que ves cuando alguien se refiere a Web 2.0. Lo que te tiene que preocupar entonces es como hacer posible estas nuevas interacciones. Obviamente, todavía tenes que hacer peticiones y respuestas de campo, pero es el redibujamiento de el HTML para toddas interacción de petición/respuesta la que da la percepción de una interface Web lenta y pesada. Por eso claramente necesitas un acercamiento que te permitahacer peticiones y recibir respuestas que incluyan la información que necesitás, más que una página HTML entera. El único momento que vas a querer lebantar una página HTML entera es cuando... bueno... cuanto quieras que el usuario vea una nueva página.&lt;br /&gt;Pero la mayoría de las interacciones agregan detalles o cambian el texto del cuerpo, o sobreponer información en las páginas existentes. En todos esos casos, Ajax y Web 2.0 acercan la posibilidad de enviar y recibir información sin actualizar una página HTML entera. Y para cualquier usuario web frecuente. Esta habilidad va a hacer que tu aplicación se sienta más rápida, más dinámica, y los traerá de vuelta una y otra vez&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114141792199031390?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114141792199031390/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114141792199031390' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114141792199031390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114141792199031390'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/03/traduccin-del-articulo-de-ajax-v.html' title='Traducción del articulo de Ajax V'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114115994521069543</id><published>2006-02-28T17:38:00.000-03:00</published><updated>2006-11-14T15:25:31.228-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de artículo sobre Ajax IV</title><content type='html'>&lt;span style="font-weight: bold;font-size:130%;" &gt;Pescar en el formulario Web&lt;/span&gt;&lt;br /&gt;¿Entonces que queda? Realmente no mucho. Tenen un método JS que toma la información que el usuario pone en el formulario, lo manda al servidor, le da otro método JS para escuchar y manejar la respuesta y hasta establecer el valor de un campo cuando la respuesta vuelve. Todo lo que realmente queda es llamar ese primer evento JS y empezar nuevamente todo el proceso. Podés obviamente agregar un botón a tu formulario HTMLpero eso es un poco 2001, ¿no te parece? Toma ventaja de la tecnología JS como en Listing 7&lt;br /&gt;&lt;blockquote&gt;&lt;small&gt;&lt;small style="font-weight: bold;"&gt;Listing 7.Lanzar un proceso Ajax&lt;/small&gt;&lt;/small&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&amp;lt;form&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;Ciudad: &amp;lt;input name="ciudad" id="ciudad" size="25" onchange="callServer();" type="text"&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;Estado: &amp;lt;input name="estado" id="estado" size="25" type="text"&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;Código Postal: &amp;lt;input name="codigoPostal" id="codigopostal" size="5" type="text"&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/div&gt; &lt;/blockquote&gt;Si esto se siente como otra piesa más de código de rutina, entonces estas en lo correcto, eso es. Cuando un usuario pone un nuevo valor para cualquier campo ciudad o estado, se dispara el método callServer() y la dirversión Ajax empieza. Estas empezando a sentir que tenes más manejo de las cosas? bien; esa es la idea!&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;En conclución&lt;/span&gt;&lt;br /&gt;En este punto, probablemente no estarás listo para ir y escribir tu primer aplicación Ajax,  al menos que desees hacer algo de investigación real en la sección recursos. Sin embargo podes tener una idea basica de como esas plaiciones trabajan y un entendimiento básico del objeto XMLHttpRequest. en el artículo que viene, vas a aprender especialmente este objeto, como manejar la comunicación JS-Servidor, como trabajar con formularios HTML, y también empezar a indagar en DOM.&lt;br /&gt;Por ahora, tomate algo de tiempo para pensar sobre cuan poderosas pueden se las aplicaciones Ajax. Imagina un formulario web que te responda no solamente cuando apretes un botón, sinó cuando ingreses texto en un campo, cuando elijas una opcion de un cuadro desplegable, hasta cuando pases el mouse por la pantalla.Esto es exactamente lo que significa asincronico; pensá en código JS ejecutando y no esperado, en el servidor para responder a sus peticiones. ¿en que clase de problemas poder caer? ¿en que áreas vás a tener mas cuidado? y ¿como el diseño de tus formularios va a cambiar para justificar estas mejoras en programación?&lt;br /&gt;Si te tomas un tiempo para estos temas, vas a estar mejor ubicado que solo tenienco código para cortar y pegar, y tirarlo en una aplicación que realmente no entiendas. En el próximo artículo vas a poner esas ideas en práctica y te voy a dar los detalles del código que necesites para hacer realmente aplicaciones como este trabajo. Entonces, hasta ese momento, disfuta de las posibilidades de Ajax.&lt;br /&gt;&lt;br /&gt;Para los recursos ver el &lt;a href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html?ca=dgr-lnxw01MasterAJAX#resources"&gt;artículo original.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114115994521069543?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114115994521069543/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114115994521069543' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114115994521069543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114115994521069543'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/02/traduccin-de-artculo-sobre-ajax-iv.html' title='Traducción de artículo sobre Ajax IV'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114106845891551915</id><published>2006-02-27T16:27:00.000-03:00</published><updated>2006-11-14T15:25:31.132-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo sobre Ajax III</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;span style="font-weight: bold;"&gt;Una Palabra sobre seguridad&lt;/span&gt;&lt;br /&gt;¿Qué pasa con la seguridad? Los Navegadores actualesle dan al usuario la habilidad de manejar sus niveles de seguridad, apagar la tecnología JavaScript, y desabilitar cualquier numero de opciones en su navegador. En esos casos, tu código no va a trabajar bajo ninguna cirscunstancia. Para esas situaciones, vas a tener que manejar los problemas con gracia, es por lo menos un artículo en si mismo, uno que voy a enfrentar mas tarde (Va a ser una serie larga, ¿no?, no te preocupes vas a dominar todo esto antes de que termines). Por ahora, estas escribiendo código robustos, pero no perfecto, que es genial para empezar a entender Ajax. Vas a volver sobre los detalles más finos.&lt;br /&gt;&lt;big&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Pedido/respuesta en un mundo Ajax&lt;/span&gt;&lt;/big&gt;&lt;br /&gt;Entonces ahora ntendes Ajax y tenés una básica idea sobre el objeto XMLHttpRequest y como crearlo. Si has leido en detalle, ya te habrás dado cuenta que es la tecnología JavaScript la que se comunica con cualquier aplicación Web en el servidor, más que tu formulario HTML siendo aceptado directamente para esa aplicación.&lt;br /&gt;¿Cuál es la parte que falta? Como usar realmente el XMLHttpRequest. Como es código crítico que vas a usar de alguna manera en toda aplicación Ajax que escribas, hace un paseo rápido por como luce un modelo básico de petición/respuesta con Ajax.&lt;br /&gt;Hacer una Petición&lt;br /&gt;Tenés tu nuevo objeto XMLHttpRequest brillante; vamos a dar una vuelta en él. Primero, necesitás un método JavaScript que tu web pueda llamar (como cuando un usuario ingrese texto o seleccione una opción de un menú). Despues, vas a seguir las mismos puntos básicos en casi todas tus aplicaciones Ajax:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Obtener toda la información que necesites del formulario web&lt;/li&gt;&lt;li&gt;Construir la URL para conectarlo&lt;/li&gt;&lt;li&gt;Abrir una conección con el Servidor&lt;/li&gt;&lt;li&gt;Establecer una función para que el servidor ejecute cuando este hecho. &lt;/li&gt;&lt;li&gt;Mandar la petición.&lt;/li&gt;&lt;/ol&gt;El Listing 5 es un ejemplo de un método Ajax que hace especificamente esas cosas, en ese orden.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Listing 5. Hacer una petición con Ajax&lt;/span&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function callServer() {&lt;br /&gt;// Toma la ciudad y el estado del formulario web&lt;br /&gt;var ciudad = document.getElementById("ciudad").value;&lt;br /&gt;var estado = document.getElementById("estado").value;&lt;br /&gt;//Solamente continua si hay valores para ambos campos&lt;br /&gt;if((ciudad==null) || (ciudad=="")) return;&lt;br /&gt;if((estado==null) || (estado=="")) return;&lt;br /&gt;//Construir la URL para conectarse&lt;br /&gt;var url = "/scripts/getZipCode.php?ciudad="+escape(ciudad)+" /&amp;gt;&lt;br /&gt;//open a connection to the server&lt;br /&gt;xmlHttp.open("GET", url, true);&lt;br /&gt;//Establecer una función para que el servidor ejecute cuando esté hecho&lt;br /&gt;xmlHttp.onreadystatechange = updatePage&lt;br /&gt;//Mandar la petición&lt;br /&gt;xmlHttp.send(null);&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;Mucho de esto se explica solo. La primera parte del código usa JS básico para extraer los valores de algunos campos del formulario. Despues el código establece un script PHP como el destino para conectarse. Ver como el URL del script es especificado y luego la ciudad y el estado (del formulario) son adosados a el usando simples parametros GET.&lt;br /&gt;Despues, la conexión es abierta; este es el primer lugar donde ves el XMLHttpRequest en acción otra vez. El método de conexión es indicado (GET), tal como la URL para conectarse. El último parametro, cuando es establecido a Verdadero (true), solicita una conexión asincrónica (así haciéndolo Ajax). Si usaras falso (false), el código esperaría en el servidor cuando se hace la petición y no continuaría hasta una que respuesta sea recibida. Estableciéndolo a Verdadero (true) , tus usuarios pueden todavia usar el formulario (y hasta llamar otros métodos JS) mientras el servidor está procesando este pedido en el fondo.&lt;br /&gt;La propiedad onreadystatechange del xmlHttp (recuerda, es tu instancia del objeto XMLHttpRequest) te permite decirle al servidor que hacer cuando termine de ejecutar (lo cual puede ser en cinco minutos o en cinco horas). Como el código no va a esperar al servidor, vas a necesitar hacerle saber al servidor que hacer para que puedas responderle. En este caso un método especifico, llamado updatePage(), va a ser accionado cuando el servidor termine de procesar tu pedido.&lt;br /&gt;Finalmente, send() es llamdo con el valor null. Como ya agregaste la información para mandar al servidor (la ciudad y el estado) en el URL de petición, no necesitás mandar nada en la petición. Entonces esto dispara tu petición y el servidor puede hacer lo que le pediste que haga.&lt;br /&gt;Si no tomas nada más fuera de esto, te das cuenta cuan fácil y simple es esto! Aparte de poner la naturaleza asincrónica del Ajax dentro de tu cabeza, es relativamente una tarea simple. Vas a apreciar cuanto te libera para concentrarte en aplicaciones e interfaces atractivas, más que en complicado código de petición/respuesta HTTP.&lt;br /&gt;El código en el listing 5 es tan fácil como se ve. La información es texto simple y puede ser incluído como parte del URL. GET manda el pedido mejor que el más complicado POST. No hay XML con contenido de cabecera para agregar, sin información para mandar en el cuerpo de la petición, ésta es una utopía Ajax en otras palabras.&lt;br /&gt;A no temer; Las cosas se van a poner mas complicadas a medida que esta serie avance. Vas a aprender como mandar peticiones POST, como establecer tipos de cabeceras y contenidos, como codificar XML en tus mensajes, comoagregar seguridad a tu petición... La lista es bastante larga! No te preocupes por las complicaciones por ahora; poné tu cabeza en las bases, y rápidamente vas a construir un completo arsenal de herramientas Ajax.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Manejar la respuesta&lt;/span&gt; Ahora necesitás tratar con la respuesta del servidor. Realmente solo necesitás saber dos cosas en este punto:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No hacer nada hasta que la propiedad xmlHttp.readyState sea igual a 4&lt;/li&gt;&lt;li&gt;El servidor va a colocar su respuesta en la propiedad xmlHttp.responseText.&lt;/li&gt;&lt;/ul&gt;La primera de ellas -estados correctos- avanza sobre el tema principal de el próximo artículo; vas a aprender sobre las etapas de una petición HTTP, más de lo que quisieras saber. Por ahora, si simplemente chequeas un determinado valor (4), las cosas van a andar (y vas a tener mas expectativas de ver el próximo artículo). El segundo ítem -usar la propiedad xmlHttp.responseText para obtener la respuesta del servidor- es fácil. El Listing 6 muestra un ejemplo de un método que el servidor puede llamar, basado en los valores enviados en el Listing 5.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Listing 6. Manejar la respuesta del servidor&lt;/span&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;function updatePage(){&lt;br /&gt;if (xmlHttp.readyState == 4){&lt;br /&gt;var respuesta = xmlHttp.responseText;&lt;br /&gt;document.getElementById("CodigoPostal").value = response&lt;br /&gt;}&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;Otra vez, este código no es tan difícil ni complicado. Espera al servidor para llamarlo en el estado correcto y usa el valor que el servidor le devuelve (en este caso, el código postal para la ciudad y estado que ingresó el usuario) para establecer el valor de otro campo del formulario. El resultado es que el campo CodigoPostal de pronto aparece con el código postal, pero el usuario nunca tuvo que apretar un botón. Esa es la sensación de aplicación de escritorio que hablabamos antes. Respuesta rápida, sensación dinámica y más todo con un poco de código Ajax.&lt;br /&gt;Los lectores observadores notarán que el campo CodigoPostal es un campo de texto normal. Una vez que el servidor devuelve el código postal, los usuarios puede sobreescribir el valor. Es intencional por dos razones: para mantener simples las cosas en el ejemplo y para mostrarte que a veces querés habilitar a los usuarios a sobrescribir lo que el servidor dice. Mantengan ambas cosas en mente; son importantes el el buen diseño de interfaces de usuario.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114106845891551915?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114106845891551915/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114106845891551915' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114106845891551915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114106845891551915'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/02/traduccin-de-artculo-sobre-ajax-iii.html' title='Traducción de Artículo sobre Ajax III'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114070480046315971</id><published>2006-02-23T12:18:00.000-03:00</published><updated>2006-11-14T15:25:30.918-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción del Artículo sobre Ajax II</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;span style="font-weight: bold;"&gt;Completar con DOM&lt;/span&gt;&lt;br /&gt;Por último pero no menos importante, está el DOM, el modelo de objetos de documento. Para alguno de ustedes, escuchar sobre DOM puede ser un poco intimidante, no es usado regularmente por los diseñadores de HTML y es todavía mas inusual para codificadores de JS a no ser que estén en tareas de programación de gran embergadura. Donde se encuentra mucho DOM en uso es en sólidos programas de Java y C/C++; de hecho, probablemente por esto es que, DOM adquirió un poco de su reputación de ser difícil o duro de aprender.&lt;br /&gt;Afortunadamente, usar DOM en tecnología JS es fácil y mayormente intuitivo. En este punto, normalmente muestro como usar DOM o por lo menos doy algunos ejemplos de código, pero eso sería un engaño. Verás, podés entrar bastante rápido en Ajax sin tener que lidiar con DOM y ese es el camino que les voy a mostrar. Volveré al DOM en un futuro artículo, pero por ahora, solo tené en cuenta que está ahí. Cuando empieces a enviar XML ida y vuelta entre código JS y el servidor y realmente cambies el formulario HTML, vasa volver a indagar en DOM. Es fácil obtener algo de Ajax efectivo sin él, así que postergalo por ahora.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Obtener el objeto Petición&lt;/span&gt;&lt;br /&gt;Con una descripción básica adquirida, estás listo para para ver algunos detalles. Como XMLHttpRequest es cetral para las aplicaciones Ajax, y probablemente nuevo para muchos de ustedes, voy a empezar ahí. Como viste en Listing 1 debería ser bastante fácil crear este objeto y usarlo, correcto? Espera un minuto.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Trabajar con navegadores Microsoft&lt;/span&gt;&lt;br /&gt;El navegador de Microsoft, Internet Explorer, usa el programa de análisis MSXML para trabajar el XML (puedes encontrar mas sobre MSXML en &lt;a href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html?ca=dgr-lnxw01MasterAJAX#resources"&gt;Recursos&lt;/a&gt;) Entonces cuando escribas aplicaciones Ajax que necesiten trabajar en Internet Explorer, vas a necesitar crear el objeto de una manera particular.&lt;br /&gt;Sin Embargo, no es tan fácil. MSXML realmente tiene dos versiones diferentes dando vueltas dependiendo de la versión de la tecnología JS instaslada en Internet Explorer, por eso tenés que escribir el código que maneje ambos casos. Mirá en Listing 3 el código que necesitás para crear un objeto XMLHttpRequest en Navegadores Microsoft.&lt;br /&gt;&lt;blockquote&gt;&lt;small&gt;&lt;b&gt;Listing 3: Tomar y establecer valores de campo con código JS&lt;/b&gt;&lt;/small&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;var xmlHttp = false&lt;br /&gt;try {&lt;br /&gt;xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");&lt;br /&gt;} catch (e) {&lt;br /&gt;try {&lt;br /&gt;xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");&lt;br /&gt;} catch (e2) {&lt;br /&gt;xmlHttp = false;&lt;br /&gt;}&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;Todo esto no es exactamente lo que necesitamos, pero está bien. Vas a indagar en programación en JavaScript, manejo de Errores, compilación condicional y mas antes de que esta serie termine. Por ahora tenes que tener dos líneas básicas en tu cabeza:&lt;br /&gt;xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");&lt;br /&gt;y&lt;br /&gt;xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");&lt;br /&gt;&lt;br /&gt;Aislado, este código trata de crear el objeto usando una versión de MSXML; si falla, lo crea usando la otra versión. Lindo, no? Si ninguno de esos anda, la variable xmlHttp se establece a falso, para decirle a tu código que algo no esta andando. Si ese es el caso, probablemente tengas un navegador no-Microsoft y necesitas usar un código diferente para hacer el trabajo.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Trabajando con Mozilla y navegadores No-Microsof&lt;/span&gt;t&lt;br /&gt;Si Internet Explorer no es tu navegador elegido o escribís código para navegadores No-Microsoft, entonces necesitás código diferente. De hecho, es la simple línea de código que viste en el listing 1:&lt;br /&gt;var xmlHttp = new XMLHttpRequest object;&lt;br /&gt;Esta línea mucho mas simple crea un objeto XMLHttpRequest en Mozilla, Firefox, Safari, Opera y casi todos los otros navegadores No-Microsoft que soporten Ajax de cualquier manera o moda.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ponerlos juntos&lt;/span&gt;&lt;br /&gt;La clave para soportar todos los navegadores. ¿Quién quiere escribir una aplicación que trabaje solo en internet explorer o una que trabaje solo en navegadores No-Microsoft ? Peor todavía, ¿querés escribir tu aplicación dos veces? Por supuesto que no! Entonces combiná tu código para que soporte a ambos. El Listing 4 muestra el código que hace solo eso:&lt;br /&gt;&lt;blockquote&gt;&lt;small&gt;&lt;b&gt;Listing 4: Crear un objeto XMLHttpRequest de la forma multi-navegador&lt;/b&gt;&lt;/small&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;/*Crear un nuevo objeto XMLHttpRequest para comunicarse con el servidor*/&lt;br /&gt;var xmlHttp = false;&lt;br /&gt;/*@cc_on @*/&lt;br /&gt;/*@if (@_jscript_version  5)&lt;br /&gt;try {&lt;br /&gt;xmlHttp = new ActiveObject("Msxml2.XMLHTTP"):&lt;br /&gt;} catch (e) {&lt;br /&gt;try {&lt;br /&gt;xmlHttp = new ActiveObject("Microsoft.XMLHTTP"):&lt;br /&gt;} catch (e2) {&lt;br /&gt;xmlHttp = false&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;@end @*/&lt;br /&gt;if (!xmlHttp  typeof XMLHttpRequest != 'undefined') {&lt;br /&gt;xmlHttp = new XMLHttpRequest();&lt;br /&gt;}&lt;/div&gt;&lt;/blockquote&gt;Por ahora, ingnorá los comentarios y etiquetas extrañas tal como @cc_on; son comandos de compliación especiales de JavaScript que vas a explorar en profundidad en mi próximo artículo, que va a estar focalizado especificamente en XMLHttpRequest. Este código puede dividirse en tres fases:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Crear la variable xmlHttp patas referir el objeto XMLHttpRequest que vas a crear&lt;/li&gt;&lt;li&gt;Tratar de crear los objetos en navegadores Microsoft:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;tratar y crear el objeto usando el objeto Msxml2.XMLHTTP&lt;/li&gt;&lt;li&gt;Si eso falla, tratar y crear el objeto usando el objeto Microsoft.XMLHTTP&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Si xmlHttp no está todavía establecido, crear el objeto en la manera no-Microsoft&lt;/li&gt;&lt;/ol&gt;Al final de este proceso, xmlHttp debe referenciar a un objeto XMLHttpRequest válido, sin importar que navegador utilicen los usuarios.&lt;br /&gt;&lt;br /&gt;-----------&lt;br /&gt;&lt;br /&gt;Bien, hoy fue un poco menos, mañana veremos que pasa..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114070480046315971?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114070480046315971/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114070480046315971' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114070480046315971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114070480046315971'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/02/traduccin-del-artculo-sobre-ajax-ii.html' title='Traducción del Artículo sobre Ajax II'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114063314756420995</id><published>2006-02-22T15:58:00.000-03:00</published><updated>2006-11-14T15:25:30.815-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Traducción de Artículo sobre Ajax</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Este artículo se encuentra originalmente en &lt;a href="http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html?ca=dgr-lnxw01MasterAJAX"&gt;IBM&lt;/a&gt;  y lo encontré vía &lt;a href="http://www.kbglob.com/desarrollo-web/javascript/introduccion-a-ajax/"&gt;kblog&lt;/a&gt; y es una traducción cuyo unicos objetivos son practicar mi inglés y aprender Ajax. Aclaro que solo es una traducción de alguien que apenas está estudiando. Se aceptan aportes, correcciones, críticas, etc.&lt;br /&gt;&lt;big&gt;&lt;b&gt;Dominar Ajax, Parte 1: Introducción a Ajax&lt;/b&gt;&lt;br /&gt;&lt;/big&gt;&lt;b&gt;Entender Ajax, un acercamiento productivo a la construcciones de sitios web, y como trabajan.&lt;br /&gt;&lt;/b&gt;Nivel: Introductorio&lt;br /&gt;Brett McLaughlin (brett@oreilly.com, Autor y Editor, O´Reilly y Asociados.&lt;br /&gt;06 dic 2006&lt;br /&gt;&lt;blockquote&gt;Ajax, que consiste en HTML, JavaScript tecnology, DHTML y DOM, es un excepcional acercamiento que te ayuda a transformar interfases web pesadas en aplicaciones interactivas Ajax. El autor, un experto en Ajax, demuestra como esas tecnologías trabajan juntas -desde una breve descripción a una vista detallada- para hacer el desarrollo web extremadamente eficiente una facil realidad. Tambien revela los conceptos centrales de Ajax, incluido el XMLHttpRequest object.&lt;br /&gt;&lt;/blockquote&gt;Cinco años atras, si no sabías XML, eras el patito feo a quien nadie hablaba. Dieciocho meses atrás, Ruby tomo popularidad y los programadores que que no sabían que estaba pasando con Ruby no eran bienvenidos en el &lt;i&gt;dispenser&lt;small&gt;&lt;small&gt;(1)&lt;/small&gt;&lt;/small&gt;&lt;/i&gt;. Hoy, si queres estar en lo último de la tecnología, AJAX es donde.&lt;br /&gt;Sin Embargo, Ajax es mucho mas que solo un capricho; es un poderoso adelanto para la construcción de sitios web y no es tan duro como aprender un nuevo lenguaje completo.&lt;br /&gt;Antes, voy a profundisar en que es Ajax, aunque, vamos a gastar solo unos momentos en entender que hace ajax. Cuando escribes una aplicación hoy, tenés dos opciones básicas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Aplicaciones de Escritorio &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Aplicaciones Web&lt;/li&gt;&lt;/ul&gt;Ambas son familiares, las aplicaciones de escritorio generalmente vienen en CD (o a veces se bajan de un sitio web) y se instalan completamente en tu computadora. Se puede usar Internet para descargar actualizaciones, pero el codigo que ejecutan esas aplicaciones reside en tu escritori. Aplicaciones Web- y no hay sorpresas aquí- se ejecutan en un servidor web en algún lugar y accedés a la aplicación con tu navegador Web.&lt;br /&gt;Más importante que donde se ejecuta el código para esas aplicaciones es, sin embargo, como las aplicaciones se comportan y como se interactúa con ellas. Las aplicaciones de escritoriogeneralmente son un poco mas rápidas (se ejecutan en tu computadora, no tenés que esperar a la conexión de internet), tienen interfaces de usuario grandiosas (generalmente interactuan con tu sistema operativo) y son increiblemente dinamicas. Podés clickea, apuntar, tipear, desplegar menus y submenus y navegar por ella casi sin esperas.&lt;br /&gt;Por otro lado, las aplicaciones web generalmente son actualizadas al segundo y proveen servicios no podrías tener nunca en tu escritorio (pensemos en Amazon.com y ebay). Sin Embargo, con el poder de la Web vienen las esperas: espera a que el servidor responda, espera a que las pantalla se actualicen, espera de la peticiones para volver y generar una nueva pagina.&lt;br /&gt;Obviamente esto es un poco una simplificación, pero tenés la idea básica. Como probablemente ya estarás sospechando, Ajax trata de disminuir el espacio entre la funcionalidad e interactividadde la aplicación de escritorio y de la siempre-actualizada aplicacion Web. Podés usar interfaces de usuario dinamicas y controles mas lujososcomo los que encontrás en las aplicaciones de escritorio, pero disponibles en uan aplicación Web.&lt;br /&gt;entonces, que estas esperando? Empezá a mirar a Ajax y como transformar tu pesada interface Web a aplicaciones Ajax de rápidas respuestas.&lt;br /&gt;&lt;b&gt;Vieja tecnología, nuevos trucos&lt;/b&gt;&lt;br /&gt;Cuando se entra a Ajax, La realidad es que involucra un monton de tecnologías, para estar mas allá de los fundamentos, necesitas insistir en varias tecnologías diferentes (Esto es la razón por la cual pase algunos artículos iniciales de esta serie describiendo cad auna de ellas). La buena noticia es que probablemente ya conoscas un parte decente sobre varias de estas tecnologías, mejor todvía, la mayorías de esas tecnologías individuales son faciles de aprender, ciertamente no tan difícil como un lenguaje de programación entero como Java or Ruby.&lt;br /&gt;Acá están las tecnologías básicas implicadas en en las aplicaciones Ajax:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;HTML se usa para construir formularios web e identificar campos para usar en el resto de la aplicación.&lt;/li&gt;&lt;li&gt;El código JavaScript es el código base ejecutado por las aplicaciones Ajax y ayuda a facilitar la comunicación con las aplicaciones servidor.&lt;/li&gt;&lt;li&gt;DHTML o HTML dinámico, ayuda a actualizar los formularios dinámicamente. Vas a usar div, span y otros elementos de HTML dinámico para comentar&lt;small&gt;&lt;small&gt;(2)&lt;/small&gt;&lt;/small&gt; tu HTML&lt;/li&gt;&lt;li&gt;DOM, Modelo de Objetos de Documento, va a ser usado (vía código Javascript) para trabajar con ambos: La estructura del HTML y en algunos casos el XML devuelto por el servidor.&lt;/li&gt;&lt;/ul&gt;Vamos a desglosarlos para tener una mejor idea de que hacen cada uno. Voy a indagar mas en cada uno de ellos en futuros artículos. Ahora focalicemos en familiarizarnos con esos componentes y tecnologías. Cuanto mas familiarizado estés con este código, más facil va a ser moverse desde conocimiento ocacional sobre estas tecnologías a dominarlas (y realmente &lt;i&gt;mejorar&lt;small&gt;&lt;small&gt;(3)&lt;/small&gt;&lt;/small&gt;&lt;/i&gt; el desarrollo de tu aplicación web).&lt;br /&gt;&lt;b&gt;El objeto XMLHttpRequest&lt;/b&gt;&lt;br /&gt;El primer objeto que vas a querer entender es probablemente el que te es más nuevo, se llama XMLHttpRequest. Es un objeto de JavaScript y se crea tan simple como se muestra en  Listing 1&lt;br /&gt;&lt;blockquote&gt;&lt;small&gt;&lt;b&gt;Listing 1: Crear un nuevo objeto XMLHttpRequest&lt;/b&gt;&lt;/small&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;&amp;lt;script languaje="javascript" type="text/javascript"&amp;gt;&lt;br /&gt;var xmlHttp=new XMLHttpRequest();&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Voy a hablar mas sobre este objeto en el próximo artículo, pero por ahora tengan en cuenta que este es el objeto que maneja todas las comunicaciones con el servidor. Antes de seguir, para y piensa: es la tecnología javascript a travez del objeto XMLHttpRequest la que habla con el servidor. No es el flujo normal de las aplicaciones y es donde Ajax toma mucha de su magia.&lt;br /&gt;En una aplicación web normal, los usuarios completan formularios y hacen click en el botón de &lt;span style="font-style: italic;"&gt;Submit. &lt;/span&gt;Entonces el formulario completo es enviado al servidor, el servidor transfiere el procesamiento a un Script (generalmente PHP, o Java o puede ser un proceso CGI o algo similar) y cuando el escrip está hecho, devuelve un pagina completamente nueva.  Esa página puede ser HTML con un nuevo formulario, con algo de información completada, o puede ser una confirmación o capás una página con algunas opciones selecionadas basadas en información ingresada en el formulario original.  Por supuesto, mientras el script o programa en el servidor esta procesando y devolviendo el nuevo formulario, los usuarios tienen que esperar. Sus pantallas se limpiaran y luego se redibujaran con la información que vuelve del servidor. Aca es donde la interactividad entra en juego: los usuarios no obtienen respuesta instantanea  y ciertamente no sienten que estén trabajando en una aplicación de escritorio.&lt;br /&gt;Ajax esencialmente pone la tecnología JavaScript y el objeto XMLHttpRequest entre tu formulario Web y el servidor. Cuando los usuarios completan formularios, es información es enviada a algun código JavaScript y no directamente al servidor. En cambio el código Javascript toma la infomación del formulario y manda una petición al servidor. Mientras esto está pasando, el formulario en la pantalla del usuario no se mueve, refresca, centellea, desaparece o para. En otras palabras, el código JavaScript manda el código en secret, el usuario no se da cuenta que la petición ha sido hecha. Todavía mejor, la peticion es enviada asincronicamente, que significa que tu JavaScript (y el usuario) no esperan sin hacer nada a que el servidor responda. Entonces los usuarios pueden continuar ingresando información, moviendose en la pantalla, y usando la aplicación.&lt;br /&gt;Luego, el servidor devuelve la información a tu código JavaScript (todavía esperando en el formulario Web) que decide que hacer con esa información. Puede actualizar campos de formularios en la marcha, dando ese sensacion de inmediatoa tu aplicación, los usuarios obtienen información sin que sus formularios hayan sido aceptados o refrescados. El código JavaScript puede demas tomar la información, realizar algunos cálculos  y mandar otra petición, todo sin la intervensión del ususario! Este es el poder del &lt;span style="font-style: italic;"&gt;XMLHttpRequest. &lt;/span&gt;Puede comunicarse de ida y vuelta con el servidor todo lo que quiera, sin que el usuario se entere de que eso está pasando. El resultado es un experiencia dinámica, de respuesta rápida, y altamente interactiva como la de una aplicación de escritorio, pero con todo el poder de internet detrás.&lt;br /&gt;Agregar algo de JavaScript&lt;br /&gt;Una vez que manejes &lt;span style="font-style: italic;"&gt;XMLHttpRequest &lt;/span&gt;, el resto de tu código JS va a parecerte un poco aburrido. De hecho, vas a usar código JS solo para algunas tareas básicas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Tomar la información del formulario: el código Js hace simple sacar la información fuera de tu formulario y lo mandarla al servidor.&lt;/li&gt;&lt;li&gt;Cambiar valores en el formulario: tambien es simple actualizar un formulario, desde los valores de los campos elegidos para reemplazar imagenes en la marcha. &lt;/li&gt;&lt;li&gt;Analizar HTML y XML: vas a usar código JS para manipular el DOM (ver la siguiente sección) y para trabajar con la estructura de tu formulario HTML y cualquier información XML que devuelva el servidor.&lt;/li&gt;&lt;/ul&gt;Para lso dos primeros items, vas a necesitar familiarizarte con el método &lt;span style="font-style: italic;"&gt;getElementById()&lt;/span&gt; como se muestra en listing 2&lt;br /&gt;&lt;blockquote&gt;&lt;small&gt;&lt;b&gt;Listing 1: Tomar y establecer valores de campo con código JS&lt;/b&gt;&lt;/small&gt;&lt;br /&gt;&lt;div class="simple_box"&gt;&lt;br /&gt;//Tomar el valor del campo "telefono" y ponerlo en una variable llamada telefono&lt;br /&gt;var telefono = document.getElementById("telefono").value;&lt;br /&gt;&lt;br /&gt;// Establecer algunos valores en un formulario usando un arreglo llamado respuesta&lt;br /&gt;document.getElemenById("orden").value= respuesta[0];&lt;br /&gt;document.getElemenById("direccion").value= respuesta[1];&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;No hay nada particularmente destacable acá y eso es bueno! Debes empezar a darte cuenta que no hay nada tremendamente complicado sobre esto.  Una vez que manejes &lt;span style="font-style: italic;"&gt;XMLHttpRequest &lt;/span&gt;, mucho del resto de tu aplicación Ajax va a ser código JavaScript simple como el que se muestra en el listing 2, mesclado con un poco de HTML inteligente. Entonces, a veces hay un poco de trabajo de DOM... por eso vamos a mirar eso.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Mañana sigo... bye.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;small&gt;(1)  water cooler gossip: conversación o chusmerío que se forma alrededor del dispenser de agua en las oficinas.&lt;br /&gt;(2) to mark up: to write notes or instructions for changes on a piece of writing, music etc.&lt;br /&gt;(3) blowing the doors off: expresion que no encontré traducción.&lt;br /&gt;&lt;/small&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114063314756420995?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114063314756420995/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114063314756420995' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114063314756420995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114063314756420995'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/02/traduccin-de-artculo-sobre-ajax.html' title='Traducción de Artículo sobre Ajax'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22501941.post-114001684962385877</id><published>2006-02-15T15:37:00.000-03:00</published><updated>2006-11-14T15:25:30.707-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Pinien</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Tener dicho algo en Mapuche.&lt;br/&gt;Tengo ganas de tener algo dicho. Unicamente con este poco original propósito empiezo este blog. Ni siquiera se si significa esto, pero me gustó y de eso se trata, de que me guste. &lt;br/&gt;Ademas provengo de estas tierras que alguna vez fueron de ellos y es probable, aunque no lo sé, que algo de su sangre corra en mis venas. Es es mi más que humilde homenaje. &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22501941-114001684962385877?l=pinien.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pinien.blogspot.com/feeds/114001684962385877/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22501941&amp;postID=114001684962385877' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114001684962385877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22501941/posts/default/114001684962385877'/><link rel='alternate' type='text/html' href='http://pinien.blogspot.com/2006/02/pinien.html' title='Pinien'/><author><name>Lau</name><uri>http://www.blogger.com/profile/14074250575058523263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
