trabajé en un prototipo frameworkless quiero compartir con ustedes. Está funcionando en Firefox 4+, IE7-8 (no se han comprobado 6 o 9) Safari y Chrome.
El mayor problema no resuelto es qué hacer cuando los encabezados estáticos se quedan sin espacio para contraerse antes que las columnas de datos.
Para el proyecto real en el que estaba trabajando francamente me retiré del cuerpo de desplazamiento y fui con la paginación. pero estaba lidiando con más de 25 columnas con clasificación y potencialmente miles de filas.
De todos modos aquí es donde llegué antes de que lo abandonara. Por favor, publique sus adiciones si lo mejora: Espero que esto ayude.
Link to an example
<!DOCTYPE html>
<html>
<head>
<title>Table with Fixed Header Prototype</title>
<script type="text/javascript">
</script>
<style type="text/css">
.tableContainer{
background:#eee;
width:80%;
}
.scrollContainer{
width:100%;
height:500px; /** The only thing required */
}
.staticHeaderTable{
-moz-box-shadow: 1px 4px 5px #cccccc;
-webkit-box-shadow:1px 4px 5px #cccccc;
box-shadow: 1px 4px 5px #cccccc;
position: relative;
z-index: 10;
}
/*****************************************************/
/**** Generic styles outside of problem scope ****/
table{border-collapse: collapse;font:normal 12px sans-serif;}
th,td{padding:2px; height:20px;border:1px solid #dddddd;}
th{background:#ffcc00;}
</style>
</head>
<body>
<script>
function makeStaticTableHeaders(tableId){
// Overall Container : wraps everything
var tableContainer = document.createElement("div");
tableContainer.className = "tableContainer";
// Scrolling Container : must have a height.(Set in CSSS in this sample) this contains the table without the head or foot
var scrollContainer = document.createElement("div");
scrollContainer.className = "scrollContainer";
scrollContainer.style.overflowY = "auto"; // just Y since IE7 doesn't add the scrollbar to the width.
scrollContainer.style.overflowX = "hidden"; // IE7 override. consider a CSS fix
scrollContainer.style.width = "100%";
// Identifies the actual table to wrap from the dom. exits if it can't be found
var dataTable = document.getElementById(tableId);
if(typeof(dataTable) == "undefined"){
return false;
}
dataTable.style.width = "100%";
// Identify the header. If there is none, there is no point in this so exit.
var header = dataTable.getElementsByTagName("thead");
if (header.length == 0){
return false;
}
for (var i = 0; i < header.length; i++)
{
if(header[i].className.indexOf("static") != -1){
header = header[i];
break;
}
if(i == header.length - 1){
header = header[i];// failsafe
}
}
// If we are still here, we begin the process of altering the DOM elements
// 1. Insert the tableContainer in front of the dataTable
dataTable.parentNode.insertBefore(tableContainer, dataTable);
// 2. Insert the scrollContainer into the table container
tableContainer.appendChild(scrollContainer);
// 3. get the thead tr and create staticHeaderTable with the tr
var headerRow = header.getElementsByTagName("tr")[header.getElementsByTagName("tr").length - 1]; // gets last tr in case there is more than one
var staticHeaderTable = document.createElement("table");
staticHeaderTable.className = "staticHeaderTable";
staticHeaderTable.appendChild(header);
staticHeaderTable.style.width = "100%";
// 4. Put the staticHeaderTable in the scrollContanier
tableContainer.insertBefore(staticHeaderTable, scrollContainer);
// 5. take the datatable out of the dom and put it in the scrollContainer
scrollContainer.appendChild(dataTable);
// 6. footer(optional)
var footer = dataTable.getElementsByTagName("tfoot");
if (footer.length > 0){
for (var i = 0; i < footer.length; i++)
{
if(footer[i].className.indexOf("static") != -1){
footer = footer[i];
break;
}
if(i == footer.length - 1){
footer = footer[i];// failsafe
}
}
// TODO: footer assumes columns are not linked to the data columns.
var staticFooterTable = document.createElement("table");
staticFooterTable.className = "staticFooterTable";
staticFooterTable.appendChild(footer);
staticFooterTable.style.width = "100%";
tableContainer.appendChild(staticFooterTable);
}
function tableResize(){
var firsttableRow = dataTable.getElementsByTagName("tbody")[0].getElementsByTagName("tr")[0];
var extra = headerRow.offsetWidth - firsttableRow.offsetWidth;
var headerCells = (headerRow.getElementsByTagName("td").length > 0)? headerRow.getElementsByTagName("td") : headerRow.getElementsByTagName("th");
for(var i=0; i <headerCells.length;i++){
headerCells[i].style.width = firsttableRow.getElementsByTagName("td")[i].offsetWidth + ((i==headerCells.length-1)? extra: 0) + "px";
}
};
if(window.addEventListener) {window.addEventListener("resize", tableResize, false);}
else{window.attachEvent("onresize", tableResize);}
tableResize();
}
window.onload = function(){
var staticTable = makeStaticTableHeaders("dataTable");
}
</script>
<h2>Datatable</h2>
<table id="dataTable" class="dataTable">
<thead class="static">
<tr>
<th>Header 1 A long One</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell Content 1 All the good Stuff is in here</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>End of Cell Content 1</td>
<td>End of Cell Content 2</td>
<td>End of Cell Content 3</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3">Footer Is Here</td>
</tr>
</tfoot>
</table>
</body>
</html>
Noooo! ¡Todo navegador debería soportar esto! Es una gran característica. :( –
Acabo de descubrir este problema, arruiné una página que anteriormente funcionaba, y estoy de acuerdo: ¡Noooooooooooo! –
No puedo creer que no haya una manera simple de crear lo que es un elemento de interfaz tan obvio y extremadamente útil:/ – Jake