miércoles, 28 de marzo de 2012

Especificaciones privativas: DOM y JavaScript - Actualizado 09/05/12

La falta de control sobre las especificaciones puede suponer un auténtico rompecabezas para los desarrolladores, pues en muchos casos éstas no se encuentran disponibles en todos los ámbitos.

El DOM, modelo de objeto del documento, es a resumidas cuentas, un marco de trabajo con el que podemos interactuar con objetos para ofrecer así una vista del documento al usuario.

El responsable de su control, como en muchos otros estándares, es el consorcio WC3, y sus especificaciones se encuentra bajo el nivel 2. Esta versión de las especificaciones del DOM lleva dando guerra casi 12 años, pero de vez en cuando surgen necesidades y, mientras su versión renovada siga bajo un borrador, queda en manos de los navegadores, o más bien de los motores de renderización, actuar para adaptar éstas a sus necesidad.

Los motores de renderización son el corazón (¡Que poético!) de los navegadores. Quizá los que más repercusión estén teniendo sean Webkit, utilizado por Chrome y Safari entre todos, y Gecko, perteneciente a la fundación Mozilla. Bajo estos motores se encuentran diversas especificaciones, de la mano de WC3, relacionadas con HTML, DOM, JavaScript, CSS, además de las propias incluidas por estos motores, llamadas especificaciones propias.

Llegados a este último punto no hay control que valga y cada motor entra al trapo con sus especificaciones propias para rellenar esos huecos vacíos que deja la ineficacia de la WC3.

Entre esas especificaciones propias tenemos los vendor-specific de CSS (-moz-, -webkit--ms-, etcétera) o en el caso del DOM, pequeñas joyas escondidas como la que os comento a continuación.


Bajo el motor Gecko, y dentro de la especifiación del DOM, tenemos el objeto events, y a su vez, dentro de éste la propiedad explicitOriginalTarget, que es exclusiva de Gecko y no se encuentra disponible en los demás motores de renderización.

Esta propiedad hace referencia al elemento desde el cual se originó la llamada al evento, y a diferencia de target o currentTargetexplicitOriginalTarget tiene la peculiaridad de que, a pesar de que el evento sea reorientado internamente, consigue llegar al final de la cadena para obtener el elemento desde el que se inició dicho evento.

Esa reorientación del evento sucede, por ejemplo, en el evento submit de los formularios. Así, la propiedad a la que hacemos mención nos permitirá averiguar, en el ámbito de un formulario, bien, si nos encontrábamos dentro de un campo de texto cuando pulsamos la tecla intro o qué botón de envío pulsamos.

La falta de esta propiedad en la especificación original de la WC3 nos imposibilita todo lo anterior en el resto de navegadores, pero podemos recuperar parte de su funcionalidad mediante unas pocas líneas de código, ya que el hecho de añadir una capa de abstracción completa para simular dicha propiedad, y de este modo poseer toda su funcionalidad, puede poner en peligro la integridad del sitio.

Al pulsar sobre el botón de envío de un formulario, si este botón tiene asignado el atributo name, su nombre y valor serán incluidos en los datos a enviar del formulario. Tal resultado lo podemos apreciar en la siguiente dirección http://fiddle.jshell.net/GqQ9E/show/.

El problema aparece cuando intervenimos mediante JavaScript el evento submit y deseamos  recuperar los datos de envío, especialmente los del botón que accionó la petición.

Para recrear dichas situaciones recurriremos a jQuery y su función serialize, la cual obtiene los datos del formulario a enviar, tal como se muestra en el siguiente ejemplo http://fiddle.jshell.net/yeikos/4U3SX/.

Como podréis observar, al pulsar sobre cualquiera de los dos botones, tan sólo obtendremos los datos del campo de texto, pues la misión de la función serialize se limita a obtener los datos de los elementos (input, select, textarea, etcétera) del formulario y no los pertenecientes al botón de envío.

Para que en el ejemplo anterior obtengamos el resultado esperado, deberemos añadir una pequeña capa de abstracción que resuelva dicho problema y que podemos encontrar en la siguiente dirección https://gist.github.com/1261574#file_fix_eo_target.js.

De esta manera, intervendremos el evento click de todos los botones para que cuando éstos sean pulsados, añadamos sus datos al formulario antes de que el evento submit sea llamado.

El ejemplo funcional, ya con la capa de abstracción, lo podéis encontrar en la siguiente dirección http://jsfiddle.net/yeikos/yE8zB/.

No hay comentarios:

Publicar un comentario