Ich habe an einem rahmenlosen Prototyp gearbeitet, den ich mit Ihnen teilen möchte. Er funktioniert in Firefox 4+, IE7-8 (habe 6 oder 9 nicht überprüft), Safari und Chrome.
Das größte ungelöste Problem ist die Frage, was zu tun ist, wenn die statischen Kopfzeilen nicht mehr genug Platz haben, um zu schrumpfen, bevor es die Datenspalten tun.
Für das eigentliche Projekt, an dem ich gearbeitet habe, habe ich mich ehrlich gesagt von dem scrollenden tbody zurückgezogen und bin mit Paginierung gegangen. aber ich hatte es mit 25+ Spalten mit Sortierung und potenziell 1000en von Zeilen zu tun.
Jedenfalls bin ich an diesem Punkt angelangt, bevor ich es aufgegeben habe. Bitte posten Sie Ihre Ergänzungen, wenn Sie es verbessern: Hoffentlich hilft das.
Link zu einem Beispiel
<!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>