如何在可滚动的div中冻结html表的第一列和最后一列?

Dam*_*isa 13 html javascript layout html-table

我有一个表有一个标题行,但也有一个标题列和一个总列,其中有几列.

像这样的东西:

Name    Score 1    Score 2  ...  Total
--------------------------------------
John       5          6            86
Will       3          7            82
Nick       7          1            74
Run Code Online (Sandbox Code Playgroud)

整个表在固定宽度的可滚动div中定义,因为可能有大量的"Score"行,并且我有一个固定宽度的页面布局.

<div id="tableWrapper" style="overflow-x: auto; width: 500px;">
    <table id="scoreTable">
        ...
    </table>
</div>
Run Code Online (Sandbox Code Playgroud)

我想要的是第一(Name)和last(Total)列在内部列滚动时保持可见.

谁能帮我这个?

编辑:我的意思是仅水平滚动 - 更改为指定.


更新:我已经为自己解决了这个问题,并在下面发布了答案.如果您需要更多信息,请告诉我 - 这有点痛苦,我讨厌别人必须重写所有内容.

oza*_*zan 5

我可以提出一个有点非正统的解决方案吗?

您如何考虑将'total'列放在'name'列之后,而不是在最后?这不会避免只需要滚动表的一部分吗?

这不完全是你所要求的,但也许这是一个充分的解决方案,因为替代方案会非常混乱.(例如,在表格之外放置'total'和'name'列会在不是所有行都具有相同高度时产生对齐问题.你可以用javascript来纠正这个问题但是你会进入一个全新的世界痛).

同样从UI的角度来看,'name'和'total'可能是最重要的数据,在这种情况下将它们组合在一起是有意义的,然后是总计的"细分".当然,我们似乎有一种直觉,即'总数'应该在它的组成部分之后,但我不认为如果订单被这样颠倒,它会给用户带来太多的混淆(尽管这是一个问题)您,基于您的产品和用户).

无论如何,需要考虑的事情.

编辑:

以下是一些更为非正统的解决方案,现在我认为我更了解你的意图:

  1. 分数得分.给出最近的十个,比如说和总数,以及一次提供10个旧分数的链接
  2. 只提供名称,总计和其他一些有意义的度量,例如mean和sd,然后为每个名称提供一个链接,显示与该名称对应的所有结果.然后,您还可以提供显示给定分数集的所有结果的链接,以便可以进行不同用户之间的比较.关键在于您只需要为每个视图提供1维数据,而不是拥有难以处理的2D数据集
  3. 使行可排序(使用jQuery UI很容易),这样如果我想比较Mary和Jane,我可以一个接一个地拖动和放置,所以我不需要继续向左和向右滚动以查看哪些分数对应于哪些名称
  4. 单击时突出显示一行,通过更改背景颜色或类似颜色,再次,这样我就不需要继续向左和向右滚动.

无论如何,你明白了.也许最好是寻找UI解决方案而不是扭曲的标记解决方案.最后,我会质疑一次向用户提供如此多的数据是多么重要,它的一部分需要以特定方式滚动才能使数据可读.也许您正在构建电子表格应用程序,并且您确实需要在单个视图中显示100x100矩阵.如果没有,你肯定会提出比我分割结果更有创意的方法.


Dam*_*isa 2

我尝试了一些方法(感谢所有提供帮助的人),以下是我使用 jQuery 得出的结果。它似乎在我测试过的所有浏览器中都运行良好。请随意接受并按照您的意愿使用它。我的下一步是将其变成一个可重用的 jQuery 插件。

概括:

我从一个包含所有内容的普通表格开始(Id="ladderTable"),然后编写了三种方法- 一个用于剥离第一列,一个用于剥离最后一列,一个用于固定行高。

stripFirstColumn方法创建一个新表 ( Id="nameTable" ),遍历原始表取出第一列,并将这些单元格添加到 nameTable 中。

stripLastColumn方法基本上执行相同的操作,只不过它取出最后一列并将单元格添加到名为TotalTable新表中。

fixHeights方法查看每个表中的每一行,计算最大高度,并将其应用于相关表

在文档就绪事件中,我按顺序调用了所有三个方法。请注意,所有三个表格都向左浮动,因此它们只会水平堆叠。

HTML 结构:

<h1>Current Ladder</h1> 
<div id="nameTableSpan" style="float:left;width:100px;border-right:2px solid gray;"></div> 
<div id="ladderDiv" style="float:left;width:423px;overflow:auto;border:1px solid gray;margin-top:-1px;"> 
    <table id="ladderTable" class="ladderTable">
        <thead> 
            <tr><td>Name</td><td>Round 1</td> ... <td>Round 50</td><td class="scoreTotal">Total</td></tr>
        </thead>
        <tr><td>Bob</td><td>11</td> ... <td>75</td><td>421</td></tr>
           ... (more scores)
    </table>
</div>
<div id="totalTableSpan" style="float:left;width:70px;border-left:2px solid gray;"></div> 
Run Code Online (Sandbox Code Playgroud)

jQuery:

function stripFirstColumn() {                
    // pull out first column:
    var nt = $('<table id="nameTable" cellpadding="3" cellspacing="0" style="width:100px;"></table>');
    $('#ladderTable tr').each(function(i)
    {
        nt.append('<tr><td style="color:'+$(this).children('td:first').css('color')+'">'+$(this).children('td:first').html()+'</td></tr>');
    });
    nt.appendTo('#nameTableSpan');
    // remove original first column
    $('#ladderTable tr').each(function(i)
    {
        $(this).children('td:first').remove();
    });
    $('#nameTable td:first').css('background-color','#8DB4B7');
}

function stripLastColumn() {                
    // pull out last column:
    var nt = $('<table id="totalTable" cellpadding="3" cellspacing="0" style="width:70px;"></table>');
    $('#ladderTable tr').each(function(i)
    {
        nt.append('<tr><td style="color:'+$(this).children('td:last').css('color')+'">'+$(this).children('td:last').html()+'</td></tr>');
    });
    nt.appendTo('#totalTableSpan');
    // remove original last column
    $('#ladderTable tr').each(function(i)
    {
        $(this).children('td:last').remove();
    });
    $('#totalTable td:first').css('background-color','#8DB4B7');
}

function fixHeights() {
    // change heights:
    var curRow = 1;
    $('#ladderTable tr').each(function(i){
        // get heights
        var c1 = $('#nameTable tr:nth-child('+curRow+')').height();    // column 1
        var c2 = $(this).height();    // column 2
        var c3 = $('#totalTable tr:nth-child('+curRow+')').height();    // column 3
        var maxHeight = Math.max(c1, Math.max(c2, c3));

        //$('#log').append('Row '+curRow+' c1=' + c1 +' c2=' + c2 +' c3=' + c3 +'  max height = '+maxHeight+'<br/>');

        // set heights
        //$('#nameTable tr:nth-child('+curRow+')').height(maxHeight);
        $('#nameTable tr:nth-child('+curRow+') td:first').height(maxHeight);
        //$('#log').append('NameTable: '+$('#nameTable tr:nth-child('+curRow+')').height()+'<br/>');
        //$(this).height(maxHeight);
        $(this).children('td:first').height(maxHeight);
        //$('#log').append('MainTable: '+$(this).height()+'<br/>');
        //$('#totalTable tr:nth-child('+curRow+')').height(maxHeight);
        $('#totalTable tr:nth-child('+curRow+') td:first').height(maxHeight);
        //$('#log').append('TotalTable: '+$('#totalTable tr:nth-child('+curRow+')').height()+'<br/>');

        curRow++;
    });

    if ($.browser.msie)
        $('#ladderDiv').height($('#ladderDiv').height()+18);
}

$(document).ready(function() {
    stripFirstColumn();
    stripLastColumn();
    fixHeights();
    $("#ladderDiv").attr('scrollLeft', $("#ladderDiv").attr('scrollWidth'));    // scroll to the last round
});
Run Code Online (Sandbox Code Playgroud)

如果您有任何疑问或有任何不清楚的地方,我非常乐意为您提供帮助。

我花了很长时间才发现没有什么东西是我可以真正重用的,所以写这篇文章花了更长的时间。我讨厌有人遇到同样的麻烦。