ChatGPT解决这个技术问题 Extra ChatGPT

当用户使用 jQuery 将表头滚动到视图之外时,表头保持固定在顶部

我正在尝试设计一个 HTML 表格,当且仅当用户将其滚动出视图时,标题才会保留在页面顶部。例如,表格可能从页面向下 500 像素,我该如何制作,以便如果用户将标题滚动到视图之外(浏览器检测到它不再以某种方式出现在 windows 视图中),它将保持在顶部?任何人都可以给我一个Javascript解决方案吗?

<table>
  <thead>
    <tr>
      <th>Col1</th>
      <th>Col2</th>
      <th>Col3</th>
    </tr>
  </thead>
  <tbody>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
  </tbody>
</table>

因此,在上面的示例中,我希望 <thead> 在页面消失时随页面滚动。

重要提示:我正在寻找一种解决方案,其中 <tbody> 将具有滚动条 (overflow:auto)。


A
Andrew Whitaker

您可以通过点击 window 上的 scroll 事件处理程序并使用另一个具有固定位置的 table 在页面顶部显示标题来执行此类操作。

HTML:

<table id="header-fixed"></table>

CSS:

#header-fixed {
    position: fixed;
    top: 0px; display:none;
    background-color:white;
}

JavaScript:

var tableOffset = $("#table-1").offset().top;
var $header = $("#table-1 > thead").clone();
var $fixedHeader = $("#header-fixed").append($header);

$(window).bind("scroll", function() {
    var offset = $(this).scrollTop();

    if (offset >= tableOffset && $fixedHeader.is(":hidden")) {
        $fixedHeader.show();
    }
    else if (offset < tableOffset) {
        $fixedHeader.hide();
    }
});

当用户向下滚动到足以隐藏原始表头时,这将显示表头。当用户再次向上滚动页面足够远时,它将再次隐藏。

工作示例:http://jsfiddle.net/andrewwhitaker/fj8wM/


我在想这个,但是如果标题列的宽度根据内容发生变化怎么办?除非列宽是固定的,否则您的标题行可能不会与内容行对齐。只是一个想法。
如果列标题的名称短于列数据值,则此示例不起作用。尝试更改该小提琴以具有诸如 infoooooooo 之类的值而不是 info。我正在考虑克隆表格时设置的某种硬编码宽度。
这有很大的限制,其中最小的限制是在尝试使用 window 以外的容器中的表时。 mkoryak.github.io/floatThead 有一个更普遍适用的解决方案。
这可能会帮助任何需要动态 th 宽度的人,这是我最终所做的,它是 @AndrewWhitaker 的一个分支:jsfiddle.net/noahkoch/wLcjh/1
当原始单元格具有填充时,使用您的解决方案的@NoahKoch 固定标题仍可能不如原始标题那么宽。我改进了您的解决方案,为重复的单元格添加填充。 JSFiddle 的分支:jsfiddle.net/1n23m69u/2
I
Ihor Zenich

纯 CSS(不支持 IE11):

table th {
    position: -webkit-sticky; // this is for all Safari (Desktop & iOS), not for Chrome
    position: sticky;
    top: 0;
    z-index: 1; // any positive value, layer order is global
    background: #fff; // any bg-color to overlap
}

我什至没有看到这在 Chrome 中工作。检查工具将 -webkit-sticky 显示为 position 的无效值。
@carmenism -webkit-sticky 适用于 Safari(桌面和 iOS),不适用于 Chrome。 position: sticky 在 Chrome 版本 56 中有效。您应该设置两个规则:-webkit-stickysticky,其顺序与我的代码示例中的顺序完全相同。 Safari 获得 webkit-sticky,所有其他浏览器将其覆盖为 sticky
我无法让它工作。从快速 google 看来,position: sticky 不适用于表格元素。
申请 th 对我有用:table thead tr th{...}
您必须将其应用于 th 因为它不适用于 thead 或 tr
n
neubert

好吧,我试图在不使用固定大小的列或为整个表格设置固定高度的情况下获得相同的效果。

我想出的解决方案是 hack。它包括复制整个表格,然后隐藏除标题之外的所有内容,并使其具有固定位置。

HTML

<div id="table-container">
<table id="maintable">
    <thead>
        <tr>
            <th>Col1</th>
            <th>Col2</th>
            <th>Col3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
        <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
        <tr>
            <td>info</td>
            <td>some really long line here instead</td>
            <td>info</td>
        </tr>
        <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
                <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
                <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
        <tr>
            <td>info</td>
            <td>info</td>
            <td>info</td>
        </tr>
    </tbody>
</table>
<div id="bottom_anchor"></div>
</div>

CSS

body { height: 1000px; }
thead{
    background-color:white;
}

javascript

function moveScroll(){
    var scroll = $(window).scrollTop();
    var anchor_top = $("#maintable").offset().top;
    var anchor_bottom = $("#bottom_anchor").offset().top;
    if (scroll>anchor_top && scroll<anchor_bottom) {
    clone_table = $("#clone");
    if(clone_table.length == 0){
        clone_table = $("#maintable").clone();
        clone_table.attr('id', 'clone');
        clone_table.css({position:'fixed',
                 'pointer-events': 'none',
                 top:0});
        clone_table.width($("#maintable").width());
        $("#table-container").append(clone_table);
        $("#clone").css({visibility:'hidden'});
        $("#clone thead").css({'visibility':'visible','pointer-events':'auto'});
    }
    } else {
    $("#clone").remove();
    }
}
$(window).scroll(moveScroll); 

见这里:http://jsfiddle.net/QHQGF/7/

编辑:更新了代码,以便 thead 可以接收指针事件(因此标题中的按钮和链接仍然有效)。这解决了 luhfluh 和 Joe M 报告的问题。

这里有新的 jsfiddle:http://jsfiddle.net/cjKEx/


我首先尝试过,问题在于标题中元素的大小取决于表的内容。如果您有一行内容很大,则整个列(包括标题)都会增长。如果您只克隆 thead,您会丢失该信息并且不会获得预期的效果。请参阅 Yzmir Ramirez 对已接受答案的评论。这是我发现没有固定宽度列的唯一方法。它不干净,我知道,这就是我所说的黑客攻击。
哦,我明白了。这种方法很棒,因为它适用于流体柱,我用谷歌搜索了一下,找不到另一个具有该功能的方法。无论如何,如果我能以某种方式完成它,我会在这里提到它
@luhfluh,是的,问题出在克隆表中的指针事件:无。这用于使点击通过克隆并到达原始表。将其还原到克隆表的标题中,以便标题(并且只有标题)可单击解决了该问题。我已经更新了我的帖子以反映这一点:)
在 上添加边框的问题
这个解决方案对我有用,一个小问题是表格是否延伸到屏幕右侧。如果用户向右滚动,标题不会滚动。否则很好。
m
mkoryak

我写了一个插件来做到这一点。我已经研究了大约一年,我认为它可以很好地处理所有极端情况:

在溢出的容器内滚动

在窗口内滚动

处理调整窗口大小时发生的情况

将您的事件绑定到标题

最重要的是,它不会强迫您更改表格的 css 以使其正常工作

以下是一些演示/文档:
http://mkoryak.github.io/floatThead/


看起来不错,但如果表已经运行其他插件(如我的情况)与插件的严格规则冲突,则无法正常工作
它适用于任何缓存其选择器的插件,这是好的插件应该做的。但是没有人再这样做了,因为young'ins 从来不用为IE6 编写任何jquery 插件。
效果很好,值得一提的是它与多维表一起工作得很好!唯一要指出的是,当您将其称为快速时,表格宽度会有些混乱。但这很容易通过一些回调来避免。
太棒了,节省了我很多时间,谢谢!
r
rockusbacchus

我能够解决更改列宽的问题。我从上面 Andrew 的解决方案开始(非常感谢!),然后添加了一个小循环来设置克隆 td 的宽度:

$("#header-fixed td").each(function(index){
    var index2 = index;
    $(this).width(function(index2){
        return $("#table-1 td").eq(index).width();
    });
});

这解决了问题,而不必克隆整个表并隐藏正文。我是 JavaScript 和 jQuery 的新手(以及堆栈溢出),所以任何评论都值得赞赏。


效果很好,但我需要添加以下行 $("#header-fixed").width($("#table-1").width());列正确排列。
j
josephting

这是迄今为止我找到的具有固定表头的最佳解决方案。

更新 5/11:修复了 Kerry Johnson 指出的水平滚动错误

代码笔:https://codepen.io/josephting/pen/demELL

;(function($) { $.fn.fixMe = function() { return this.each(function() { var $this = $(this), $t_fixed; function init() { $this.wrap('< div class="container" />'); $t_fixed = $this.clone(); $t_fixed.find("tbody").remove().end().addClass("fixed").insertBefore($this ); resizeFixed(); } function resizeFixed() { $t_fixed.width($this.outerWidth()); $t_fixed.find("th").each(function(index) { $(this).css(" width",$this.find("th").eq(index).outerWidth()+"px"); }); } function scrollFixed() { var offsetY = $(this).scrollTop(), offsetX = $(this).scrollLeft(), tableOffsetTop = $this.offset().top, tableOffsetBottom = tableOffsetTop + $this.height() - $this.find("thead").height(), tableOffsetLeft = $this. offset().left; if(offsetY < tableOffsetTop || offsetY > tableOffsetBottom) $t_fixed.hide(); else if(offsetY >= tableOffsetTop && offsetY <= tableOffsetBottom && $t_fixed.is(":hidden")) $t_fixed .show(); $t_fixed.css("left", tableOffsetLeft - offsetX + "px"); } $(window).resize(resizeFixed); $(window).scr ol(滚动固定);在里面(); }); }; })(jQuery); $(document).ready(function(){ $("table").fixMe(); $(".up").click(function() { $('html, body').animate({ scrollTop: 0 }, 2000); }); }); body{ 字体:1.2em 正常 Arial,sans-serif;颜色:#34495E; } h1{ 文本对齐:中心;文本转换:大写;字母间距:-2px;字体大小:2.5em;边距:20px 0; } .container{ 宽度:90%;边距:自动; } 表{ 边框折叠:折叠;宽度:100%; } .blue{ 边框:2px 实心 #1ABC9C; } .blue thead{ 背景:#1ABC9C; } .purple{ 边框:2px 实心 #9B59B6; } .purple thead{ 背景:#9B59B6; } 头{ 颜色:白色; } th,td{ 文本对齐:中心;填充:5px 0; } tbody tr:nth-child(even){ 背景:#ECF0F1; } tbody tr:hover{ 背景:#BDC3C7;颜色:#FFFFFF; } .fixed{ 顶部:0;位置:固定;宽度:自动;显示:无;边框:无; } .scrollMore{ 边距顶部:600px; } .up{ 光标:指针; }

↓ SCROLL ↓

td>
Colonne 1 Colonne 2 Colonne 3
Non MaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMais Allo !
NonMais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
主要 Allo !
主要 Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !< /td>
主要 Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !< /td>
Non Mais Allo !
Non Mais Allo !

↓滚动更多 ↓

< /tr> < td>Mais < td>Allo ! < td>Allo ! < td>Non
Colonne 1 Colonne 2 Colonne 3
Non Mais Allo !
Non< /td> Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Allo !
Non Mais Allo!
Non Mais Allo !
Non Mais< /td> Allo !
Non Mais Allo !
主要 Allo !
主要
Non Mais Allo !
Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais< /td> Allo !
Non Mais Allo !
主要 Allo !
主要
Non Mais Allo !
Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non 主要 Allo!
主要 Allo!
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Mais Allo !
Non Ma是 Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !
Non Mais Allo !

↑ UP ↑


我修复了这个脚本,以便它可以处理 <th>具有边框和内边距的元素(否则它会将固定标头的 <th> 宽度设置得太宽)。只需在 resizeFixed() 函数定义中将 outerWidth 更改为 width
您可能还需要将 z-index 的 CSS 属性添加到 .fixed 类的某个正数,以便在您滚动时表格中页面加载后呈现的对象不会浮动在固定标题的顶部。
如何动态处理顶部位置。比方说,我需要向上滚动到我的主页固定标题内容下方。 .固定{顶部:0;}。
@VVijay您始终可以调整固定标题的位置。这里的想法是在页面滚动到您设置的位置时显示表头的固定副本。请参阅 scrollFixed() 函数。
@KerryJohnson 感谢您的注意。我做了一些更改,因此它支持水平滚动和动态列宽。
S
Srivats Shankar

这里已经有很多非常好的解决方案。但我在这些情况下使用的最简单的纯 CSS 解决方案之一如下:

table { /* 不仅可视化需要 */ border-collapse: collapse;宽度:100%; } table thead tr th { /* 重要 */ background-color: red;位置:粘性; z 指数:100;顶部:0; } td { /* 不仅可视化需要 */ padding: 1em; }

< td>info
Col1 Col2 Col3
信息 信息 信息
信息 信息 信息< /td>
info info info
info info
info info info
info info info
info info 信息
信息 信息 信息
信息 info info
info info info
info info info
info 信息 信息

因为对 JavaScript 没有要求,所以它大大简化了这种情况。您基本上需要关注第二个 CSS 规则,它包含确保无论滚动空间如何,表头都保持在顶部的条件。

详细阐述每个规则。 position 旨在向浏览器指示头部对象、它的行和它的单元格都需要粘在顶部。这必然需要伴随着 top,它向浏览器指定头部将停留在页面或视口的顶部。此外,您可以添加 z-index 以确保头部的内容始终保持在顶部。

背景颜色只是为了说明这一点。您无需使用任何额外的 JavaScript 即可获得此效果。 2016 年之后的大多数主要浏览器都支持此功能。


J
Janning

最好的解决方案是使用这个 jquery 插件:

https://github.com/jmosbech/StickyTableHeaders

这个插件对我们很有用,我们尝试了很多其他解决方案。我们在 IE、Chrome 和 Firefox 中对其进行了测试


您是否知道任何解决方案也可以在标题中保留敲除数据绑定控件的功能?
对我不起作用:标题在表格之外并粘在浏览器(窗口)的顶部,即使使用“scrollableArea”选项也是如此。我看到这在没有额外评论的情况下之前提到过。也许它需要一个他使用的 CSS 并且无法使其工作。
A
Abhi Das

我找到了一个不使用 JQuery 并且仅使用 CSS 的简单解决方案。

您必须将固定内容放在“th”标签内并添加 CSS

table th {
    position:sticky;
    top:0;
    z-index:1;
    border-top:0;
    background: #ededed;
}
   

position、z-index 和 top 属性就足够了。但是您可以应用其余部分以获得更好的视图。


这与两年前发布的 Ihor Zenich's answer 有何不同?
L
Lok Yan Wong

我找到了一个名为 Sticky Table Headers 的简单 jQuery 库。两行代码,它完全符合我的要求。上面的解决方案不管理列宽,因此如果您的表格单元格占用大量空间,则持久标题的结果大小将与您的表格宽度不匹配。

http://plugins.jquery.com/StickyTableHeaders/

此处的使用信息:https://github.com/jmosbech/StickyTableHeaders


x
xelilof

你可以使用这种方法,纯 HTML 和 CSS 不需要 JS :)

.table-fixed-header { display: flex; justify-content: 之间的空格; margin-right: 18px } .table-fixed { display: flex; justify-content: 之间的空格;高度:150px;溢出:滚动; } .column { 弹性基础:24%;边框半径:5px;填充:5px;文本对齐:居中; } .column .title { 边框底部:2px 灰色实体;边框顶部:2px 灰色实体;文本对齐:居中;显示:块;字体粗细:粗体; } .cell { 填充:5px;右边框:1px 实心;左边框:1px 实心; } .cell:nth-of-type(even) { background-color: lightgrey; } 固定标题Bin < /head>

col 1
col 2
col 3
col 4
alpha
beta
ceta
alpha
beta
ceta
alpha
beta
ceta
alpha
beta
< div class="cell">ceta
alpha
beta
ceta
b eta
beta
beta
alpha
beta
ceta


s
seeit360

我也遇到了同样的问题,即没有使用 entropy 的代码显示边框格式,但做了一些小修复,现在表格可以扩展并显示您可以添加的所有 css 样式规则。

在 CSS 中添加:

#maintable{width: 100%}    

那么这里是新的javascript:

    function moveScroll(){
    var scroll = $(window).scrollTop();
    var anchor_top = $("#maintable").offset().top;
    var anchor_bottom = $("#bottom_anchor").offset().top;
    if (scroll > anchor_top && scroll < anchor_bottom) {
        clone_table = $("#clone");
        if(clone_table.length === 0) {          
            clone_table = $("#maintable").clone();
            clone_table.attr({id: "clone"})
            .css({
                position: "fixed",
                "pointer-events": "none",
                 top:0
            })
            .width($("#maintable").width());

            $("#table-container").append(clone_table);
            // dont hide the whole table or you lose border style & 
            // actively match the inline width to the #maintable width if the 
            // container holding the table (window, iframe, div) changes width          
            $("#clone").width($("#maintable").width());
            // only the clone thead remains visible
            $("#clone thead").css({
                visibility:"visible"
            });
            // clone tbody is hidden
            $("#clone tbody").css({
                visibility:"hidden"
            });
            // add support for a tfoot element
            // and hide its cloned version too
            var footEl = $("#clone tfoot");
            if(footEl.length){
                footEl.css({
                    visibility:"hidden"
                });
            }
        }
    } 
    else {
        $("#clone").remove();
    }
}
$(window).scroll(moveScroll);

就标题中的边框格式而言,这确实比熵的解决方案更好。但是,在当前的 Firefox(但不是 Chrome)中,一旦滚动开始,它就会在表格下方创建可见的单元格边框伪影。
此解决方案有效。但是当窗口很小时,克隆的标题不会水平滚动,有什么建议可以解决这个问题吗?
B
Ben Gripka

这是一个基于公认答案的解决方案。它更正:列宽、匹配的表格样式以及表格在容器 div 中滚动的时间。

用法

确保您的表格具有 <thead> 标记,因为只会修复广告内容。

$("#header-fixed").fixHeader();

Java脚本

//Custom JQuery Plugin
(function ($) {
    $.fn.fixHeader = function () {
        return this.each(function () {
            var $table = $(this);
            var $sp = $table.scrollParent();
            var tableOffset = $table.position().top;
            var $tableFixed = $("<table />")
                .prop('class', $table.prop('class'))
                .css({ position: "fixed", "table-layout": "fixed", display: "none", "margin-top": "0px" });
            $table.before($tableFixed);
            $tableFixed.append($table.find("thead").clone());

            $sp.bind("scroll", function () {
                var offset = $(this).scrollTop();

                if (offset > tableOffset && $tableFixed.is(":hidden")) {
                    $tableFixed.show();
                    var p = $table.position();
                    var offset = $sp.offset();

                    //Set the left and width to match the source table and the top to match the scroll parent
                    $tableFixed.css({ left: p.left + "px", top: (offset ? offset.top : 0) + "px", }).width($table.width());

                    //Set the width of each column to match the source table
                    $.each($table.find('th, td'), function (i, th) {
                        $($tableFixed.find('th, td')[i]).width($(th).width());
                    });

                }
                else if (offset <= tableOffset && !$tableFixed.is(":hidden")) {
                    $tableFixed.hide();
                }
            });
        });
    };
})(jQuery);

这对我来说效果很好。唯一的问题是需要水平滚动的表格。我在 JSFiddle 中进行了更新 jsfiddle.net/4mgneob1/1 我减去 $sp.scrollLeft() 得到从左侧滚动的数量,因此当向下滚动时,固定表的位置正确。如果固定表格可见以调整左侧位置,还添加了水平滚动时的检查。我无法解决的另一个问题是当表格超出视口时,固定表格应该隐藏,直到用户向上滚动。
获得Uncaught TypeError: $table.scrollParent is not a function
A
Alexey Shmalko

这将帮助您拥有一个固定的标题,它也可以与数据一起水平滚动。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Shubh</title>



<script type="text/javascript">
    var lastSeen = [ 0, 0 ];
    function checkScroll(div1, div2) {
        if (!div1 || !div2)
            return;
        var control = null;
        if (div1.scrollLeft != lastSeen[0])
            control = div1;
        else if (div2.scrollLeft != lastSeen[1])
            control = div2;
        if (control == null)
            return;
        else
            div1.scrollLeft = div2.scrollLeft = control.scrollLeft;
        lastSeen[0] = div1.scrollLeft;
        lastSeen[1] = div2.scrollLeft;
    }

    window
            .setInterval(
                    "checkScroll(document.getElementById('innertablediv'), document.getElementById('headertable'))",
                    1);
</script>

<style type="text/css">
#full {
    width: 400px;
    height: 300px;
}

#innertablediv {
    height: 200px;
    overflow: auto;
}

#headertable {
    overflow: hidden;
}
</style>
</head>
<body>

    <div id="full">




        <div id="headertable">
            <table border="1" bgcolor="grey" width="150px" id="headertable">
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>

                    <td>&nbsp;&nbsp;&nbsp;</td>
                </tr>

            </table>
        </div>




        <div id="innertablediv">

            <table border="1" id="innertableid">
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>
                <tr>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                    <td>shubh, ansh</td>
                </tr>

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

这将帮助您拥有一个固定的标题,它也可以与数据一起水平滚动。
J
JustWe
function fix_table_header_position(){
 var width_list = [];
 $("th").each(function(){
    width_list.push($(this).width());
 });
 $("tr:first").css("position", "absolute");
 $("tr:first").css("z-index", "1000");
 $("th, td").each(function(index){
    $(this).width(width_list[index]);
 });

 $("tr:first").after("<tr height=" + $("tr:first").height() + "></tr>");}

这是我的解决方案


L
Leo Lloyd Andrade

聚会有点晚了,但这里有一个实现,它可以在同一页面上处理多个表并且“jank”免费(使用 requestAnimationFrame)。此外,无需在列上提供任何宽度。水平滚动也可以。

标头在 div 中定义,因此您可以在需要时自由添加任何标记(如按钮)。这是所需的所有 HTML:

<div class="tbl-resp">
  <table id="tbl1" class="tbl-resp__tbl">
     <thead>
      <tr>
        <th>col 1</th>
        <th>col 2</th>
        <th>col 3</th>
      </tr>
    </thead> 
  </table>
</div>

https://jsfiddle.net/lloydleo/bk5pt5gs/


P
Piotr C.

在这个解决方案中,固定标题是动态创建的,内容和样式是从 THEAD 克隆的

您只需要两行,例如:

var $myfixedHeader = $("#Ttodo").FixedHeader(); //create fixed header $(window).scroll($myfixedHeader.moveScroll); //bind function to scroll event

我的 jquery 插件 FixedHeader 和 getStyleObject 下面提供你可以放入文件 .js

// JAVASCRIPT /* * getStyleObject jQuery JavaScript 库插件 * 来自:http://upshots.org/?p=112 基本用法:$.fn.copyCSS = function(source){ var styles = $(source).getStyleObject (); this.css(样式); } */ (function($){ $.fn.getStyleObject = function(){ var dom = this.get(0); var style; var returns = {}; if(window.getComputedStyle){ var camelize = function( a,b){ return b.toUpperCase(); }; style = window.getComputedStyle(dom, null); for(var i = 0, l = style.length; i < l; i++){ var prop = style[ i]; var camel = prop.replace(/\-([az])/g, camelize); var val = style.getPropertyValue(prop); return[camel] = val; }; return return; }; if( style = dom.currentStyle){ for(var prop in style){ returns[prop] = style[prop]; }; return returns; }; return this.css(); } })(jQuery); //长表浮动表头 PiotrC (function ( $ ) { var tableTop,tableBottom,ClnH; $.fn.FixedHeader = function(){ tableTop=this.offset().top, tableBottom=this.outerHeight()+tableTop ; //添加固定头 this.after('

'); //克隆头 ClnH=$("#fixH").html(this.find("thead") .clone()); //设置样式 ClnH.css({'position':'fixed', 'top':'0', 'zIndex':'60', 'display':'none', 'border-崩溃':this.css('border-collapse'),'border-spacing':this.css('border-spacing'),'margin-left':this.css('margin-left'),'width ': this.css('width') }); //重写头部的样式单元 $.each(this.find("thead>tr>th"), function(ind,val){ $(ClnH.find( 'tr>th')[ind]).css($(val).getStyleObject()); }); return ClnH;} $.fn.moveScroll=function(){ var offset = $(window).scrollTop( ); if (offset > tableTop && offsettableBottom){ if(!ClnH.is(':hid den'))ClnH.hide(); } }; })( jQuery ); var $myfixedHeader = $("#repTb").FixedHeader(); $(window).scroll($myfixedHeader.moveScroll); /* CSS - 只重要 不透明背景 */ #repTB{border-collapse: 分离;border-spacing: 0;} #repTb thead,#fixH thead{background: #e0e0e0 linear-gradient(#d8d8d8 0%, #e0e0e0 25%, #e0e0e0 75%, #d8d8d8 100%) 重复滚动 0 0;border:1px solid #CCCCCC;} #repTb td{border:1px solid black}

example

< td>信息
Col1Column2描述
infoinfoinfo< /td>
信息信息信息
信息信息
信息信息信息
信息信息信息
信息信息 信息
信息信息信息
信息信息信息
信息信息信息
信息信息信息
i nfoinfoinfo


N
Novice_JS

创建与主表具有相同标题的额外表。只需将thead 放入新表中,其中包含一行和所有标题。做绝对位置和背景白色。对于主表,将其放在一个 div 中并使用一些高度和溢出-y 滚动。这样,我们的新表将克服主表的标题并留在那里。将所有内容包围在一个 div 中。下面是执行此操作的粗略代码。

      <div class="col-sm-8">

        <table id="header-fixed" class="table table-bordered table-hover" style="width: 351px;position: absolute;background: white;">
        <thead>
        <tr>
            <th>Col1</th>
            <th>Col2</th>
            <th>Col3</th>
        </tr>
    </thead>
      </table>


    <div style="height: 300px;overflow-y: scroll;">
          <table id="tableMain" class="table table-bordered table-hover" style="table-layout:fixed;overflow-wrap: break-word;cursor:pointer">
<thead>
    <tr>
      <th>Col1</th>
      <th>Col2</th>
      <th>Col3</th>
    </tr>
  </thead>
  <tbody>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
  </tbody>

                                    </table>
              </div>
        </div>

r
revilodesign.de

div.wrapper { 填充:20px; } table.scroll thead { 宽度:100%;背景:#FC6822; } table.scroll thead tr:after { content: '';溢出-y:滚动;可见性:隐藏; } table.scroll thead th { flex: 1 auto;显示:块;颜色:#fff; } table.scroll tbody { 显示:块;宽度:100%;溢出-y:自动;高度:自动;最大高度:200px; } table.scroll thead tr,table.scroll tbody tr { 显示:弹性; } table.scroll tbody tr td { flex: 1 auto;自动换行:休息; } table.scroll thead tr th,table.scroll tbody tr td { 宽度:25%;填充:5px;文本左对齐;边框底部:1px 实心 rgba(0,0,0,0.3); }

Name Vorname Beruf Alter
Müller Marie Künstlerin 26
Meier Stefan Chemiker 52
施密特 Sabrine Studentin 38
Mustermann Max Lehrer 41
Müller Marie Künstlerin 26
Meier Stefan Chemiker< /td> 52
Schmidt Sabrine Studentin 38
Mustermann Max Lehrer 41
Müller Marie Künstlerin 26
Meier Stefan Chemiker 52
Schmidt Sabrine Studentin 38
Mustermann Max Lehrer 41

演示: css fixed table header demo


J
J Benjamín Samayoa

解决您的问题

tbody {
  display: table-caption;
  height: 200px;
  caption-side: bottom;
  overflow: auto;
}

S
Sandip Solanki

在我的情况下,我只使用 css 解决方案:

首先我们需要这样的表格格式:

<table>
<thead><tr><th></th></tr></thead>
<tbody><tr><td></td><tr></tbody>
</table>

并应用这个 css :

tbody {
    display:block;
    max-height:280px;
    overflow-x: hidden;
    overflow-y: auto;
    }
    thead, tbody tr {
        display:table;
        width:100%;
        table-layout:fixed;
    }

并且标题是固定的


D
Daniel Budzyński

这可以通过使用样式属性转换来实现。您所要做的就是将您的表格包装成一些具有固定高度和溢出设置为自动的 div,例如:

.tableWrapper {
  overflow: auto;
  height: calc( 100% - 10rem );
}

然后您可以将 onscroll 处理程序附加到它,在这里您可以找到用 <div class="tableWrapper"></div> 包装的每个表的方法:

  fixTables () {
    document.querySelectorAll('.tableWrapper').forEach((tableWrapper) => {
      tableWrapper.addEventListener('scroll', () => {
        var translate = 'translate(0,' + tableWrapper.scrollTop + 'px)'
        tableWrapper.querySelector('thead').style.transform = translate
      })
    })
  }

这是一个实际的工作示例(我使用引导程序使其更漂亮):fiddle

对于那些也想支持 IE 和 Edge 的人,这里是片段:

  fixTables () {
    const tableWrappers = document.querySelectorAll('.tableWrapper')
    for (let i = 0, len = tableWrappers.length; i < len; i++) {
      tableWrappers[i].addEventListener('scroll', () => {
        const translate = 'translate(0,' + tableWrappers[i].scrollTop + 'px)'
        const headers = tableWrappers[i].querySelectorAll('thead th')
        for (let i = 0, len = headers.length; i < len; i++) {
          headers[i].style.transform = translate
        }
      })
    }
  }

在 IE 和 Edge 中滚动有点迟钝......但它可以工作

这是帮助我找出答案的答案:answer


J
Jeffrey Roosendaal

我已经尝试了大多数这些解决方案,并最终找到(IMO)最好的、现代的解决方案:

CSS 网格

使用 CSS 网格,您可以定义一个“网格”,您最终可以为具有固定标题和可滚动内容的表格创建一个不错的、无 javascript 的跨浏览器解决方案。标题高度甚至可以是动态的。

CSS:显示为网格,并设置template-rows个数:

.grid {
    display: grid;
    grid-template-rows: 50px auto; // For fixed height header
    grid-template-rows: auto auto; // For dynamic height header
}

HTML:创建一个网格容器并定义rows个数:

<div class="grid">
    <div></div>
    <div></div>
</div>

这是工作示例:

CSS

body {
  margin: 0px;
  padding: 0px;
  text-align: center;
}

.table {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-rows: 50px auto;
}
.table-heading {
  background-color: #ddd;
}
.table-content {
  overflow-x: hidden;
  overflow-y: scroll;
}

HTML

<html>
    <head>
    </head>
    <body>
        <div class="table">
            <div class="table-heading">
                HEADING
            </div>
            <div class="table-content">
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
                CONTENT - CONTENT - CONTENT <br/>
            </div>
        </div>
    </body>
</html>

H
Henrik Haftmann

我已经尝试过使用转换:翻译。虽然它在 Firefox 和 Chrome 中运行良好,但在 IE11 中根本没有任何功能。没有双滚动条。支持表格 tfoot 和标题。纯 Javascript,没有 jQuery。

http://jsfiddle.net/wbLqzrfb/42/

thead.style.transform="translate(0,"+(dY-top-1)+"px)";

L
Lexsoul

我找到了没有 jquery 的解决方案

HTML

<table class="fixed_header">
  <thead>
    <tr>
      <th>Col 1</th>
      <th>Col 2</th>
      <th>Col 3</th>
      <th>Col 4</th>
      <th>Col 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>row 1-0</td>
      <td>row 1-1</td>
      <td>row 1-2</td>
      <td>row 1-3</td>
      <td>row 1-4</td>
    </tr>
    <tr>
      <td>row 2-0</td>
      <td>row 2-1</td>
      <td>row 2-2</td>
      <td>row 2-3</td>
      <td>row 2-4</td>
    </tr>
    <tr>
      <td>row 3-0</td>
      <td>row 3-1</td>
      <td>row 3-2</td>
      <td>row 3-3</td>
      <td>row 3-4</td>
    </tr>
    <tr>
      <td>row 4-0</td>
      <td>row 4-1</td>
      <td>row 4-2</td>
      <td>row 4-3</td>
      <td>row 4-4</td>
    </tr>
    <tr>
      <td>row 5-0</td>
      <td>row 5-1</td>
      <td>row 5-2</td>
      <td>row 5-3</td>
      <td>row 5-4</td>
    </tr>
    <tr>
      <td>row 6-0</td>
      <td>row 6-1</td>
      <td>row 6-2</td>
      <td>row 6-3</td>
      <td>row 6-4</td>
    </tr>
    <tr>
      <td>row 7-0</td>
      <td>row 7-1</td>
      <td>row 7-2</td>
      <td>row 7-3</td>
      <td>row 7-4</td>
    </tr>
  </tbody>
</table>

CSS

.fixed_header{
    width: 400px;
    table-layout: fixed;
    border-collapse: collapse;
}

.fixed_header tbody{
  display:block;
  width: 100%;
  overflow: auto;
  height: 100px;
}

.fixed_header thead tr {
   display: block;
}

.fixed_header thead {
  background: black;
  color:#fff;
}

.fixed_header th, .fixed_header td {
  padding: 5px;
  text-align: left;
  width: 200px;
}

您可以在此处看到它的工作原理:https://jsfiddle.net/lexsoul/fqbsty3h

来源:https://medium.com/@vembarrajan/html-css-tricks-scroll-able-table-body-tbody-d23182ae0fbc


V
VigneshKarthik Kasiviswanathan

最简单的 CSS,这也适用于单行和多行表头

 /* CSS */

.fix-head-table thead { 
    position: sticky;
    top: 0;
}

.fix-head-table thead th{ 
    box-shadow: inset 0px 0px 0px 0.5px rgb(192 192 192);
    border: none;
}

您可以根据需要修改开发人员窗口 css(检查元素)中的 box-shadow inset "0.5px" 阴影扩散值以及该颜色