Respuesta elaborada y bonita al final de la pregunta. Como en la vida real XD
On 2/24/06, Arnau Siches <[EMAIL PROTECTED]> wrote:
> ---- Planteo ----
>
> Estoy modificando un XHTML 1.0 Strict tipo:
>
> [...]
> <table>
>
> <thead id="demo">
> <tr>
> <th rowspan="2"></th>
> <th colspan="6">CSS 2</th>
> <th colspan="4">CSS 3</th>
> </tr>
> </thead>
> <tbody> [...] </tbody>
> </table>
> [...]
>
> Añadiendole un elemento <col>:
>
> <table summary="Suport d'alguns selectors CSS 2 i CSS 3 pels navegadors
> més comuns">
> <caption>Suport d'alguns selectors CSS 2 i CSS 3 pels navegadors més
> comuns</caption>
> <col span="8">
> <thead id="demo">
> <tr>
> <th rowspan="2"></th>
> <th colspan="6">CSS 2</th>
> <th colspan="4">CSS 3</th>
> </tr>
>
> Con la función:
>
> function agregarCol() {
> var elementThead = document.getElementById("demo");
> var elementCol = document.createElement("col");
>
> elementCol.setAttribute("span","8");
> elementThead.parentNode.insertBefore(elementCol,elementThead);
> }
>
> Via CSS estoy aplicando un estilo al elemento <col> del tipo:
>
> col {
> background: #ff6;
> font-weight: bold;
> }
>
> ---- El Problema ----
>
> Cuando visualizo el HTML con Internet Explorer 6 no se aplica el estilo de
> <col>
> En Firefox 1.5.0.1 (win) y Opera 9b2 (win) sí. (no dispongo de más
> navegadores a mano ahora)
>
> ¿Alguien se ha encontrado con casos parecidos? ¿Alguna solución?
Pues sí, pero no con el elemento `col` sino con el select multiple que
se comentó en la lista hace un par de días (bueno, y el problema
tampoco lo encontré yo).
Así que lo primero que he probado ha sido a aplicar la técnica del relojito:
setTimeout(
function() {
// ver nota #1 al final del mensaje
elementCol.span = elementCol.span - 1;
elementCol.span = elementCol.span + 1;
}, 10
);
Que hace que el elemento se tenga que redibujar. Lamentablemente, no
soluciona ná de ná.
Se me ocurre entonces utilizar la _devToolBar_ de IE y comparar el
árbol de un documento que incluye el elemento `col` en el marcado con
el de un documento que añade el elemento `col` mediante scripting.
Surprise!
Con el `col` en el marcado (la tabla con la que he hecho las
_primeras_ pruebas no incluía los elementos `caption` y `thead`):
* table
* caption
* colgroup
* col
* thead
* tr
* th, etc.
* tbody
* tr
* td, etc.
Con el `col` generado mediante scripting:
* table
* caption
* col <-- nótese que aquí no hay colgroup pariente.
* thead
* tr
* th, etc.
* tbody
* tr
* td, etc.
Parece que aquí está la clave, el árbol no es el mismo.
Pues por mis cojones, con perdón, que va a ser el mismo XD.
Voy a trabajar sobre esta tabla:
<table id="test">
<caption>Bla bla</caption>
<thead>
<tr>
<th colspan="2">Uno y dos</th>
<td>Tres</td>
</tr>
</thead>
<tbody>
<tr>
<td>Uno</td>
<td>Dos</td>
<td>Tres</td>
</tr>
</tbody>
</table>
Con esta hoja de estilos:
col {
background: red;
font-weight: bold;
}
Y este script:
window.onload = addCol;
function addCol() {
var t = document.getElementById('test');
var cg = document.createElement('colgroup');
var col = document.createElement('col');
col.span = '2';
cg.appendChild(col);
t.insertBefore( // ver nota #2
cg,
t.getElementsByTagName('thead')[0]
||
t.getElementsByTagName('tbody')[0]
);
}
Caca de la vaca, el árbol es correcto pero IE sigue sin aplicar los estilos.
Así que vuelvo a la carga con el relojito. Después del
`t.insertBefore...` y antes de la llave que cierra la función, añado:
setTimeout(
function() {
col.span = col.span - 1;
col.span = col.span + 1;
}, 0
);
Y el mundo es un poco menos imperfecto :)
Aquí queda solucionado, pues, el problemilla de Arnau.
Conclusión: otro bug de IE
Solución: al añadir un `col` mediante scripting hay que hacerlo como
hijo de un `colGroup`. No solo eso, también hay que darle un
empujoncito reasignando el atributo `span`.
Os dejo con un par notas acerca del código que habéis leído. Considero
que merece la pena su lectura.
## Notas ##
### Nota 1
Este pedacito de código va dentro de la función `agregarCol()`, así
que la variable `elementCol` que referencia al elemento `col`
insertado está dentro del _scope_ (ámbito). Por tanto, la podemos
utilizar dentro de una función anónima en lo que se llama una
_closure_ (no sé si existe traducción para este término).
### Nota 2
Otro truquito: quiero insertar el `colgroup` después del `caption`.
Pero no todas las tablas llevan `caption`, así que será mejor que lo
inserte **antes** del primer `thead`.
Pero... y si la tabla no incluye `thead`?
Entonces antes del `tbody`. Para _encontrar_ el elemento que busco
--puesto que utilizo `element.insertBefore(newElement,
elementDescendant)`-- podría utilizar una serie de `if` anidados o
aprovechar uno de los maravillosos atajos de los que el señor nos
provee (el señor ECMAScript, entiéndase).
Como en otros lenguajes, en una expresión compuesta como esta
1 + 1 || 2 + 2;
en la que el primer componente evaluado como booleano es distinto de
false, no se procesa la segunda expresión (y el valor devuelto es
`2`).
En cambio, en
1 - 1 || 2 + 2;
La primera expresión resulta en cero, que, convertido en booleano, es
más falso que los duros de chocolate. Se evalúa el segundo componente
y el valor devuelto es 4.
Así pues, en
t.getElementsByTagName('thead')[0] || t.getElementsByTagName('tbody')[0]
el resultado es el `thead` de la tabla `t` _si existe_; en caso
contrario, el resultado es el primer `tbody` de la tabla `t`.
Salud, compañeros.
--
Choan C. Gálvez
* Desarrollo web
<http://choangalvez.nom.es/>
* Mundo Du. Cuentos breves, relatos sorprendentes
<http://du.lacalabaza.net/>
_______________________________________________
javaEScript mailing list
[email protected]
http://lists.scriptia.net/listinfo.cgi/javaescript-scriptia.net