正如Firefox 4 changelog中提到的那样,不再支持可滚动的<tbody>
。
有一堆workarounds - javascript或2个单独的表 - 但它们都没有解决所有问题。 Javascript显然速度较慢(600行你可以忘记尝试滚动表格),2个表格的单元格宽度会有问题。
您知道是否有一些很酷的方法可以做到这一点?我们正在使用jsf / facelets,现在必须重做标签,从一个好主意开始会很棒: - )
答案 0 :(得分:4)
答案 1 :(得分:2)
PrimeFaces和RichFaces具有可滚动的数据表组件,它们通过ajax获取新行。
(无论如何,两个JSF组件库都使用jQuery)
答案 2 :(得分:2)
感谢MozillaZine的digitaldigs,我能够通过一些修改使其工作。 该修复程序适用于FF4,FF7和FF11。
我希望这有帮助! :)
我已修复的问题 - 1. scrollWidth对我不起作用所以不得不去找offsetWidth
滚动条宽度为16像素也没帮助将其删除。取而代之的是我的tbody风格 -
.scrollContent { 溢出 - X:隐藏; 溢出-Y:滚动; / *我只为Mozilla做过这个。如果应用,IE将显示2个滚动条* / 显示:块; }
对于#2的更改,我必须填充标题的最后一个单元格以容纳滚动条。
/ *我这样做只适用于Mozilla。不适用于IE * /
.fixedHeader tr th:last-child { padding-right:20px; }
我的固定标题表使用了很多colspan,因此无法设置宽度,所以我首先查找具有正确数量的单元格的正确行,然后进行处理。
我的代码如下所示:
function makeMeFixedHeader(){
var tbodys = document.getElementsByName("scrollTableBody");
if (tbodys){
for(var i=0;i<tbodys.length;i++){
// We can put logic here to check if the current height
// of tbody has crossed the specified limit or not
do_tbodyscroll(tbodys[i]);
}
}
}
function do_tbodyscroll(_tbody){
// get the table node
var table = _tbody.parentNode;
// Get the Last row in Thead ...
// COLGROUPS USING COLSPAN NOT YET SUPPORTED
var thead = table.getElementsByTagName("THEAD")[0];
var _rows = thead.getElementsByTagName("TR");
var tableheader = _rows[_rows.length - 1];
var headercells = tableheader.cells;
// rows of tbody
var _frows = _tbody.getElementsByTagName("TR");
// first row of tbody
var _fr = _tbody.getElementsByTagName("TR")[0];
//var _fr = _tbody.getElementsByName("scrollTableRow")[0];
// first row cells ..
var _frcells = _fr.cells;
if (_frcells.length < headercells.length){
var rowCount = 1;
while (rowCount < _frows.length){
// nth row of tbody
_fr = _tbody.getElementsByTagName("TR")[rowCount];
//var _fr = _tbody.getElementsByName("scrollTableRow")[rowCount];
// nth row cells ..
_frcells = _fr.cells;
if (headercells.length == _frcells.length){
break;
}
rowCount++;
}
}
// Apply width to header ..
for(var i=0; i<headercells.length; i++){
if (tableheader.cells[i].offsetWidth != _fr.cells[i].offsetWidth){
var lastColumn = (i == headercells.length-1)?true:false;
var changeWidth = (lastColumn)? ((rowCount >= 1)?true:false)
:true;
var headerW = tableheader.cells[i].offsetWidth;
var cellW = _fr.cells[i].offsetWidth;
if (headerW < cellW){
tableheader.cells[i].width = cellW;
_fr.cells[i].width = tableheader.cells[i].width;
if (lastColumn)
tableheader.cells[i].width = tableheader.cells[i].offsetWidth-20;
}else{
tableheader.cells[i].width = headerW;
_fr.cells[i].width = tableheader.cells[i].width;
if (lastColumn)
_fr.cells[i].width = tableheader.cells[i].offsetWidth-20;
}
}
}
//var j = headercells.length-1;
// ADD 16 Pixel of scroll bar to last column ..
//tableheader.cells[j].width = _fr.cells[j].offsetWidth + 20;
tableheader.style.display = "block";
_tbody.style.display = "block";
}
答案 3 :(得分:1)
尝试这个页面的第一个方法,带有单个表的纯CSS(表格周围有两个div,并且thead绝对定位):tablescroll 除了IE7 / FF3.6之外,似乎可以在FF4 / IE9 / IE8上工作。
答案 4 :(得分:1)
升级后,我被猛烈抨击了。嘘声。
我在管中发现了这一点。
此代码在FFX 4中有效。不在IE8中......可以修改。
答案 5 :(得分:0)
为什么不使用可滚动的div?也许这两个选项之一:
<table>
<row>
<cell>
<div of headers>
<div of content (scrollable)>
</cell>
</row>
</table>
或更简单:
<div of headers>
<div (scrollable)>
<table of content, no headers>
</div>
我不知道但是嘿,我不是Michaelangelo:)
答案 6 :(得分:0)
我参与了一个我想与你分享的无框架原型。 它适用于Firefox 4 +,IE7-8(尚未检查6或9)Safari和Chrome。
最大的未解决问题是当静态标头在数据列之前耗尽空间时要做什么。
对于我正在努力的实际项目坦率地说,我退出了滚动的tbody并且进行了分页。但我正在处理25列以上的排序和可能的1000行。
无论如何,在我放弃它之前,这就是我要去的地方。如果您改进,请发布您的补充: 希望这会有所帮助。
<!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>