Foros del Web » Programando para Internet » Javascript »

Aportación: cabecera de tabla fija

Estas en el tema de Aportación: cabecera de tabla fija en el foro de Javascript en Foros del Web. Buenas! Hace mucho que, por temas de trabajo, necesito que la cabeza de una tabla se quede fija mientras que el contenido hace scroll . ...
  #1 (permalink)  
Antiguo 01/10/2008, 05:32
Avatar de mgusdl  
Fecha de Ingreso: abril-2007
Ubicación: Malaga, España
Mensajes: 190
Antigüedad: 17 años
Puntos: 5
Aportación: cabecera de tabla fija

Buenas!
Hace mucho que, por temas de trabajo, necesito que la cabeza de una tabla se quede fija mientras que el contenido hace scroll.
En principio el estándar de HTML permite esto dándole propiedades overflow y altura a la etiqueta tbody, pero como todos sabemos, Micro$oft se pasa los estándares por el arco del triunfo.

Mi idea ha sido hacer 2 tablas dentros de 2 div, una con la cabecera y otra con el contenido; e igualar los anchos y sincronizar el scroll lateral.

Bueno, me he currado un codiguillo, mejorable. A ver que os parece. Lo he probado en IE7 y FF3 y funciona perfectamente en ambos.
Código javascript:
Ver original
  1. function ajustaT(cuerpo, cabeza)
  2.     {
  3.     var cu = document.getElementById(cuerpo);
  4.     var ca = document.getElementById(cabeza);
  5.     if (ca.rows[0].cells.length != cu.rows[0].cells.length) { alert('Las tablas no coinciden en cantidad de celdas'); return; }
  6.     var scrw = 14;
  7.     ca.width = cu.offsetWidth + scrw;
  8.     var newCell = ca.rows[0].insertCell(-1);
  9.     newCell.innerHTML = '';
  10.     newCell.width = scrw + 'px';
  11.     cu.parentNode.onscroll = function () { ca.parentNode.scrollLeft = cu.parentNode.scrollLeft; }
  12.     for (i=0; i<cu.rows[0].cells.length; i++) ca.rows[0].cells[i].width = cu.rows[0].cells[i].offsetWidth; 
  13.     }
  14.  
  15. onload = function () { ajustaT('bdy', 'hdr'); }

El HTML quedaría así:
Código HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="es">
<head>
<title>Tabla</title>
<script type="text/javascript" src="funciones.js"></script>
<style type="text/css">
div.tcabeza, div.tcuerpo { width:200px; }
div.tcabeza { border:1px solid #AAA; overflow:hidden; }
div.tcabeza table tr { color:#FFF; background-color:#336; text-align:center; font-weight:bold; }
div.tcuerpo { background-color:#AAF; border:1px solid #AAA; overflow:auto; height:300px; }
div.tcuerpo table tr.f0 { background-color:#FFF; }
div.tcuerpo table tr.f1 { background-color:#E0F4FE; }
</style>
</head>
<body>

<div class="tcabeza">
	<table summary="cabeza" id="hdr">
		<tr>
			<th>c1</th>
			<th>c2</th>
			<th>c3</th>
			<th>c4</th>
			<th>c5</th>
			<th>c6</th>
			<th>c7</th>
			<th>c8</th>
		</tr>
	</table>
</div>
<div class="tcuerpo">
	<table summary="cuerpo" id="bdy">
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f1">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>
		<tr class="f0">
			<td>asdf</td>
			<td>ghjkl</td>
			<td>qwerty</td>
			<td>uiop</td>
			<td>zxcv</td>
			<td>vbnm</td>
			<td>12345</td>
			<td>67890</td>
		</tr>

	</table>
</div>
</body>
</html> 

Última edición por mgusdl; 10/06/2009 a las 01:24
  #2 (permalink)  
Antiguo 01/10/2008, 10:02
Avatar de mgusdl  
Fecha de Ingreso: abril-2007
Ubicación: Malaga, España
Mensajes: 190
Antigüedad: 17 años
Puntos: 5
Respuesta: Aportación: cabecera de tabla fija

Tiene un pequeño fallo cuando la celdas de la cabecera son más anchas que las del cuerpo... Estoy en ello.
  #3 (permalink)  
Antiguo 01/10/2008, 15:10
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 7 meses
Puntos: 45
Respuesta: Aportación: cabecera de tabla fija

Hola mgusdl:

El aporte es interesante, pero ten en cuenta que la técnica sería tener un tabla HTML normal y corriente, y aplicar el script que nos haga falta. Si cambiamos la estructura HTML de poco nos servirá el script. Algo así, pero habría que mejorar un poco el estilo:

Código PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<
head>
<
meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" />
<
meta name="Author" content="derkeNuke" />
<
title>Página nueva</title>
<
style type="text/css">
table width600px;}
td padding5px; }
#tabla tbody { height: 300px; overflow-y: scroll; overflow-x: hidden; }
#tabla tbody tr { height: 40px; }
</style>
</
head>

<
body>



<
table id="tabla" border="1">
    <
thead>
        <
tr>
            <
th>c1</th>
            <
th>c2</th>
            <
th>c3</th>
            <
th>c4</th>
            <
th>c5</th>
            <
th>c6</th>
            <
th>c7</th>
            <
th>c8</th>
        </
tr>
    </
thead>
    <
tbody>
        <
tr class="f0">
            <
td>asdfa</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f1">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
        <
tr class="f0">
            <
td>asdf</td>
            <
td>ghjkl</td>
            <
td>qwerty</td>
            <
td>uiop</td>
            <
td>zxcv</td>
            <
td>vbnm</td>
            <
td>12345</td>
            <
td>67890</td>
        </
tr>
    </
tbody>
</
table>




<
script type="text/javascript">
<!--



// document.getElementById abreviado
function id(x) { return document.getElementById(x); }


function 
ajustaT(tablah) {
        
    
// Añado una fila que contendrá una celda que contendrá DIV que contendrá una copia del Tbody
    
var miFila document.createElement("TR");
    var 
miCelda document.createElement("TD");
    
miFila.appendChild(miCelda);
    
miCelda.style.padding "0";
    var 
elTbody tabla.getElementsByTagName("tbody")[0];
    
miCelda.colSpan elTbody.getElementsByTagName("TR")[0].getElementsByTagName("TD").length+1;
    
elTbody.appendChildmiFila );
    
    
// Añado el DIV a la celda que contendrá una copia del Tbody
    
var miDIV document.createElement("DIV");
    
miCelda.appendChild(miDIV);
    
miDIV.style.width "100%";
    
miDIV.style.height h+"px";
    
miDIV.style.overflowY "scroll"miDIV.style.overflowX "hidden";
    var 
tabla.cloneNode(true);
    
t.removeChildt.getElementsByTagName("THEAD")[0] );            // quitamos el HEAD
    
var nuevoTbody t.getElementsByTagName("tbody")[0];
    
nuevoTbody.removeChildnuevoTbody.lastChild );
    
miDIV.appendChild);

    
// Borro todas las filas del antiguo tbody excepto la mia
    
do {
        
elTbody.removeChildelTbody.childNodes[0] );
    } while( 
elTbody.childNodes.length );


}

window.onload = function() {
    if( 
document.all )
        
ajustaTid("tabla"), 300 );
}



// -->
</script>

</body>
</html> 
Tampoco está nada bien la condicional document.all, es sólo un ejemplo. Habría que buscar algo mejor. También podríamos implementar tu solución de separar en dos DIVs haciéndolo con javascript, ningún problema.


Saludos.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #4 (permalink)  
Antiguo 01/10/2008, 18:35
Avatar de buzu  
Fecha de Ingreso: octubre-2006
Ubicación: San Francisco, CA
Mensajes: 2.168
Antigüedad: 17 años, 7 meses
Puntos: 122
Respuesta: Aportación: cabecera de tabla fija

Interesante aporte, aun que el resultado final queda poco elegante. De cualquier modo no se me ocurre por el momento otra solución.
__________________
twitter: @imbuzu
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:08.