Ir directamente al contenido de esta página

codexexempla.org

Una nota sobre el soporte de getAttribute y setAttribute en Internet Explorer 6

Tabla de contenidos

  1. Introducción
  2. Hipótesis número 1: La presencia del atributo
  3. Hipótesis número 2: El atributo obligatorio
  4. Hipótesis número 3: El atributo obligatorio y el Core
  5. Mira, mejor hago una tabla…

Introducción

No me canso de repetir para quien quiera escucharme —y a veces también para quien no quiere— que Internet Explorer 6 no soporta los métodos getAttribute y setAttribute, por lo que en muchos casos nos vemos obligados a programar dos ramas cuando queremos modificar atributos de elementos de un documento. Sin embargo, he de confesar que mi afirmación no es del todo exacta.

No es que IE6 no soporte getAttribute ni setAttribute, sino que su soporte es… ¿cómo decirlo?, ¿desconcertante?, ¿caótico?

El caso es que como material de apoyo para un curso sobre estándares y accesibilidad, programé para mis alumnos un ejemplo en JavaScript de un selector de estilos. Para alternar entre dos archivos .css distintos, modificaba el atributo href del link con el que vinculaba la hoja de estilo a la página. Tengo la buena costumbre de programar sobre un navegador respetuoso con los estándares, y luego añadir —en los casos necesarios— los parches para Explorer. Pero he aquí que cuando probé la página en este navegador, el selector de estilos, en el que aplicaba getAttribute y setAttribute funcionaba, ¡y en la versión 6! [Ver el ejemplo con href]

En el ejemplo, al pulsar el botón de obtener el href del encabezado, IE6 correctamente devuelve estilo.css. Al modificar el atributo de link, el encabezado cambia de color, y si volvemos a pulsar el primer botón, en la alerta leemos estilo_2.css. Todo correcto.

Ligeramente desconcertado, me pregunté por qué, entonces, en tantos otros scripts no había obtenido el resultado esperado.

Hipótesis número 1: La presencia del atributo

Revisando scripts anteriores, me fijé en que href era un atributo ya presente en el código de la página. Así, me dije que la explicación podría ser que getAttribute y setAttribute no funcionan en caso de que el atributo al que apuntan no exista de antemano.

Como prueba, creé una página con dos capas y un encabezado en cada una, el primero de ellos sin style y el segundo con. [Ver el ejemplo con style]

En Firefox, al hacer clic para obtener el valor de style para el primer encabezado, la primera vez obtenemos null; después de asignar un estilo en línea, obtenemos color: rgb(0,0,153);font-weight:normal;font-style:italic;, y el color del encabezado, el peso de la fuente y su estilo cambian. En IE6, en repitiendo el proceso obtenemos sendos [object], y el encabezado no varía.

Para el encabezado de la derecha, que cuenta con el atributo style, los resultados en Firefox son color: rgb(153,0,0) y de nuevo color: rgb(0,0,153);font-weight:normal;font-style:italic;. En IE6, de nuevo se repiten el par de [object], pero el encabezado no varía; presupongo, por tanto, que no funciona.

No, no parece que la presencia del atributo sea relevante.

Hipótesis número 2: El atributo obligatorio

Seguidamente, me pregunté en qué se diferenciaba href de style, y pensé: «¿acaso no es href obligatorio según la DTD que estoy empleando1?».

Para comprobarlo, creé un script que obtiene de una imagen su alt —que es un atributo obligatorio— y su title —que es opcional—. Después, ambos se pueden modificar. [Ver el ejemplo con alt y title]

En Firefox, los valores correctos se obtienen y se aplican para los dos atributos, aunque el alt que se ve en el ejemplo no se refresca; en IE6, el funcionamieno es también correcto, y además el alt se actualiza inmediatamente.

No, tampoco influye que el atributo sea obligatorio o no.

Hipótesis número 3: El atributo obligatorio y el Core

Reconozco que esta hipótesis empezaba a ser un poco enrevesada, a un paso casi de la teoría de la conspiración de turno («el tipo de Microsoft que me espía con los prismáticos desde el edificio de enfrente activa y desactiva el soporte de los atributos a capricho para torturarme»). La idea era que en la DTD que empleo hay una colección de atributos que se denominan Core (inglés), núcleo, y que son xml:space, class, id y title. ¿Podría ser que funcionase, además de con los atributos obligatorios, con los del núcelo?

Primero probé con id, y sí, funcionaba. Pero probé con class, y el resultado ya me sumió en ese estado de estupor que a veces asalta a los programadores en mi situación, una experiencia muy cercana al vacío de la mente del zen.

El caso de class es peculiar. Veamos primero el ejemplo en Firefox.

Tenemos dos encabezados, el primero sin, y el segundo con, atributo class. Del primero obtenemos el valor de su atributo class original; como es lógico, la alerta nos devuelve null. Aplicamos una clase, y se vuelve azul; además, si volvemos a obtener su valor, la alerta muestra clase_alternativa. El resultado con el segundo encabezado es el mismo, sólo que el primer resultado de todos es clase_original.

En IE6, la primera vez que obtenemos los valores de class para ambos encabezados obtenemos el mismo resultado: null. Sin embargo, al aplicar a ambos la nueva clase por medio de setAttribute, si repetimos el proceso obtenemos, correctamente y para los dos, clase_alternativa. Pero el color no cambia.

Vaya, se me acaban las ideas.

Mira, mejor hago una tabla…

…que es lo que solemos hacer cuando no podemos elaborar una teoría: acumular datos.

En vista del éxito, lo único que me quedaba por hacer para obtener algún resultado útil era elaborar una tabla con los atributos de XHTML 1.1 con los que sí funcionan tanto getAttribute como setAttribute.

La lista no es exhaustiva con respecto a las posibles combinaciones de elemento/atributos —sería una labor extensísima—, pero al menos creo que cubre los casos comunes en los que he necesitado emplear estos dos métodos. Si alguien tras consultarla encuentra algún patrón, por favor que me lo comunique.

La lista

Tabla 1: Core + I18N + Style (inglés)
AtributoSoporte IE6Soporte IE7Ejemplo
  1. Ver arriba el comportamiento con class.
classCasi [1]Casi [1]Ver el ejemplo
idVer el ejemplo
styleNoNoVer el ejemplo
titleVer el ejemplo
xml:langVer el ejemplo
Tabla 2: Atributos de los elementos de vinculación
AtributoSoporte IE6Soporte IE7Ejemplo
accesskeyNoNoVer el ejemplo
href (elemento a)Ver el ejemplo
href (elemento link)Ver el ejemplo
hreflangVer el ejemplo
mediaVer el ejemplo
rel (elemento a)Ver el ejemplo
rel (elemento link)Ver el ejemplo
Tabla 3: Atributos de object y param
AtributoSoporte IE6Soporte IE7Ejemplo
  1. Como se ve en el ejemplo, el atributo data se obtiene y se actualiza correctamente, pero el .swf que se muestra sigue siendo el mismo, porque en IE la película mostrada se especifica con <param name="movie" value="" />.
  2. En este caso ocurre como con el ejemplo de class que comento arriba: el script obtiene y actualiza correctamente el valor, pero no refresca el contenido del documento.
dataSí [1]Sí [1]Ver el ejemplo
nameVer el ejemplo
typeVer el ejemplo
valueCasi [2]Casi [2]Ver el ejemplo
Tabla 4: Atributos de los elementos de formulario
AtributoSoporte IE6Soporte IE7Ejemplo
  1. En el caso de accept-charset getAttribute no funciona hasta que no se ha asignado el atributo a través de setAttribute.
  2. Aunque se puede establecer disabled="disabled" para select, no funciona así para optgroup ni option.
  3. Comportamiento peculiar: cuando aún no se ha establecido size alguno, getAttribute devuelve el valor por defecto para input y 0 para select (aunque en este caso técnicamente es 1).
  4. Otro comportamiento peculiar: en el caso de button, cuando se aplica value, su valor aparece en el texto del botón (aunque éste sería un nodo de texto hijo de button, no su value).
accesskeyNoNoVer el ejemplo
acceptVer el ejemplo
accept-charsetCasi [1]Casi [1]Ver el ejemplo
actionVer el ejemplo
checkedVer el ejemplo
colsVer el ejemplo
disabledCasi [2]Casi [2]Ver el ejemplo
labelVer el ejemplo
maxlengthNoNoVer el ejemplo
methodVer el ejemplo
multipleVer el ejemplo
nameVer el ejemplo
readonlyNoNoVer el ejemplo
rowsVer el ejemplo
selectedVer el ejemplo
sizeSí [3]Sí [3]Ver el ejemplo
valueSí [4]Sí [4]Ver el ejemplo
Tabla 5: Atributos de los elementos de tabla
AtributoSoporte IE6Soporte IE7Ejemplo
  1. En el caso de colspan y rowspan, getAttribute devuelve siempre 1, incluso cuando inicialmente las celdas no cuentan con estos atributos; setAttribute no parece funcionar.
abbrVer el ejemplo
alignVer el ejemplo
colspanNo [1]No [1]Ver el ejemplo
headersVer el ejemplo
rowspanNo [1]No [1]Ver el ejemplo
scopeVer el ejemplo
summaryVer el ejemplo
valignNoNoVer el ejemplo
Tabla 6: Atributos de img
AtributoSoporte IE6Soporte IE7Ejemplo
altVer el ejemplo
heightVer el ejemplo
longdescNoNoVer el ejemplo
srcVer el ejemplo
widthVer el ejemplo
Tabla 7: Atributos de meta
AtributoSoporte IE6Soporte IE7Ejemplo
  1. En el caso de http-equiv, getAttribute no obtiene el valor hasta que no se ha asignado el atributo a través de setAttribute.
contentVer el ejemplo
http-equivCasi [1]Casi [1]Ver el ejemplo
nameVer el ejemplo
Tabla 8: Atributos de script
AtributoSoporte IE6Soporte IE7Ejemplo
  1. Soportarlo, lo soporta, pero al cargar el nuevo .js mantiene el funcionamiento de la función alerta tanto de script_26a.js como de script_26b.js, y al hacer clic en el botón lanza los dos comportamientos de manera consecutiva.
srcSí [1]Sí [1]Ver el ejemplo

La comprobación de los resultados para IE7 —versión 7.0.5730.11IC— en realidad no era necesaria, puesto que si revisamos el documento Technology Overview: Microsoft Windows Internet Explorer 7 (inglés), la única mejora referida a JavaScript afecta a XMLHttpRequest, que en IE7 es un objeto nativo. En fin, habrá que esperar para que el soporte de Explorer al DOM mejore…

Notas

  1. Para los ejemplos, salvo contadas excepciones, empleo la misma que para esta página, la DTD de XHTML 1.1 (inglés). Volver

Contacto

En virtud de la Ley Orgánica 15/1999 de Protección de Datos de Carácter Personal le informo de que los datos que proporcione no serán empleados para otro fin que el de responder a su mensaje. En especial, me comprometo a no cederlos a terceros ni a emplearlos para enviar información no solicitada.

Del blog de Digital Icon