当用户使用jQuery将其滚出视图时,表头将保持固定在顶部

136 html jquery html-table

我正在尝试设计一个HTML表格,当用户将其滚出视图时,标题将保留在页面顶部.例如,该表可能距离页面500像素,如何使其成为如果用户将标题滚出视图(浏览器不再以某种方式检测到它在窗口视图中),它将保持在顶部?任何人都可以给我一个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>
Run Code Online (Sandbox Code Playgroud)

所以在上面的例子中,<thead>如果它不在视图中,我希望滚动页面.

重要提示:我不是在寻找<tbody>具有滚动条(溢出:自动)的解决方案.

And*_*ker 128

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

HTML:

<table id="header-fixed"></table>
Run Code Online (Sandbox Code Playgroud)

CSS:

#header-fixed {
    position: fixed;
    top: 0px; display:none;
    background-color:white;
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
});
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我正在考虑这个但是如果标题列的宽度根据内容而改变怎么办?除非列宽已修复,否则您的标题行可能与内容行不对齐.只是一个想法. (60认同)
  • 如果列标题的名称短于列数据值,则此示例不起作用.尝试改变那个小提琴,使其具有像infoooooooo而不是信息的价值.我正在考虑克隆表时设置的某种硬编码宽度. (16认同)
  • 这可能有助于任何需要动态宽度的人,这就是我最后做的事情,它是@AndrewWhitaker的一个分支:http://jsfiddle.net/noahkoch/wLcjh/1/ (13认同)
  • 这有很大的局限性,其中最少的就是尝试在"窗口"以外的容器中使用该表.http://mkoryak.github.io/floatThead/有一个更普遍适用的解决方案. (5认同)

ent*_*opy 44

好吧,我试图获得相同的效果,而不采用固定大小的列或整个表具有固定的高度.

我提出的解决方案是黑客攻击.它包括复制整个表,然后隐藏除标题之外的所有内容,并使其具有固定的位置.

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>
Run Code Online (Sandbox Code Playgroud)

CSS

body { height: 1000px; }
thead{
    background-color:white;
}
Run Code Online (Sandbox Code Playgroud)

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); 
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 在<thead> <th>上添加边框的问题 (4认同)
  • 我首先尝试了,问题是标题中元素的大小取决于表的内容.如果您有一个包含大内容的行,则整个列(包括标题)都会增长.如果你只是克隆了那个你丢失了那些信息,你就无法获得所需的效果.请参阅Yzmir Ramirez对接受的答案的评论.这是我发现没有固定宽度列的唯一方法.我知道,它不干净,这就是我说我是黑客的方式. (3认同)

Iho*_*ich 34

纯CSS(不支持IE11):

table th {
    position: -webkit-sticky; // this is for all Safari (Desktop & iOS), not for Chrome
    position: sticky;
    top: 0;
    z-index: 5;
    background: #fff;
}
Run Code Online (Sandbox Code Playgroud)

  • 我无法让它发挥作用。从快速 google 看来,`position:sticky` 不适用于表格元素。 (4认同)
  • 申请为我工作:table thead tr th {...} (3认同)
  • 我什至没有看到这在 Chrome 中工作。检查工具显示 `-webkit-sticky` 作为 `position` 的无效值。 (2认同)
  • 将它应用于`tr`工作正常. (2认同)

roc*_*hus 25

我能够通过更改列宽来解决问题.我从安德鲁的解决方案开始(非常感谢!)然后添加一个小循环来设置克隆td的宽度:

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

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

  • 工作得很好,但我需要添加以下行$("#header-fixed").width($("#table-1").width()); 列正确排列. (4认同)

mko*_*yak 24

我写了一个执行此操作的插件.我已经开展了大约一年的工作,我认为它可以很好地处理所有角落情况:

  • 在具有溢出的容器内滚动
  • 在窗口内滚动
  • 注意调整窗口大小时会发生什么
  • 保持您的事件绑定到标题
  • 最重要的是,它不会强迫您更改表的css以使其正常工作

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

  • 仅供参考:我在最新版本中解决了IE9和10的问题. (2认同)
  • 你能制作一个不需要jQuery的版本吗? (2认同)
  • 可能是因为他没有使用jquery ...而且没有 - 我不会制作一个不使用jquery的版本. (2认同)

jos*_*ing 16

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

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

Codepen: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).scroll(scrollFixed);
         init();
      });
   };
})(jQuery);

$(document).ready(function(){
   $("table").fixMe();
   $(".up").click(function() {
      $('html, body').animate({
      scrollTop: 0
   }, 2000);
 });
});
Run Code Online (Sandbox Code Playgroud)
body{
  font:1.2em normal Arial,sans-serif;
  color:#34495E;
}

h1{
  text-align:center;
  text-transform:uppercase;
  letter-spacing:-2px;
  font-size:2.5em;
  margin:20px 0;
}

.container{
  width:90%;
  margin:auto;
}

table{
  border-collapse:collapse;
  width:100%;
}

.blue{
  border:2px solid #1ABC9C;
}

.blue thead{
  background:#1ABC9C;
}

.purple{
  border:2px solid #9B59B6;
}

.purple thead{
  background:#9B59B6;
}

thead{
  color:white;
}

th,td{
  text-align:center;
  padding:5px 0;
}

tbody tr:nth-child(even){
  background:#ECF0F1;
}

tbody tr:hover{
background:#BDC3C7;
  color:#FFFFFF;
}

.fixed{
  top:0;
  position:fixed;
  width:auto;
  display:none;
  border:none;
}

.scrollMore{
  margin-top:600px;
}

.up{
  cursor:pointer;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>&darr; SCROLL &darr;</h1>
<table class="blue">
  <thead>
    <tr>
      <th>Colonne 1</th>
      <th>Colonne 2</th>
      <th>Colonne 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>MaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
  </tbody>
</table>

<h1 class="scrollMore">&darr; SCROLL MORE &darr;</h1>
<table class="purple">
  <thead>
    <tr>
      <th>Colonne 1</th>
      <th>Colonne 2</th>
      <th>Colonne 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
  </tbody>
</table>
<h1 class="up scrollMore">&uarr; UP &uarr;</h1>
Run Code Online (Sandbox Code Playgroud)

  • @KerryJohnson感谢您的来信。我进行了一些更改,使其支持水平滚动和动态列宽。 (2认同)

Jan*_*ing 7

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

https://github.com/jmosbech/StickyTableHeaders

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


Abh*_*Das 6

我找到了一个不使用JQuery而只使用CSS的简单解决方案。

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

table th {
    position:sticky;
    top:0;
    z-index:1;
    border-top:0;
    background: #ededed;
}
   
Run Code Online (Sandbox Code Playgroud)

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

  • 这与 [Ihor Zenich 的答案](/sf/ask/329657331/ -view-with-jque/43786376#43786376),这是两年前发布的? (3认同)

小智 5

我找到了一个名为Sticky Table Headers的简单jQuery库。两行代码,它确实实现了我想要的功能。上面的解决方案不管理列宽,因此,如果表单元格占用大量空间,则持久标头的最终大小将与表的宽度不匹配。

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

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


Sri*_*kar 5

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

table {
  /* Not required only for visualizing */
  border-collapse: collapse;
  width: 100%;
}

table thead tr th {
  /* Important */
  background-color: red;
  position: sticky;
  z-index: 100;
  top: 0;
}

td {
  /* Not required only for visualizing */
  padding: 1em;
}
Run Code Online (Sandbox Code Playgroud)
<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>
     <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>
     <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>
     <tr>
       <td>info</td>
       <td>info</td>
       <td>info</td>
     </tr>
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

由于不需要JavaScript,因此可以大大简化这种情况。从本质上讲,您需要关注第二条 CSS规则,其中包含确保无论滚动空间如何,表头均保持在顶部的条件。

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

背景颜色仅是为了说明这一点。您无需使用任何其他JavaScript即可获得此效果。2016年之后,大多数主流浏览器均支持此功能。

  • 我认为这是最简单、最干净的答案,总有一种简单的方法来解决一个问题,就是这样。尽管我将 ng-repeat 与 angularjs 一起使用,但它的工作方式就像一个魅力。 (2认同)

归档时间:

查看次数:

412672 次

最近记录:

6 年 前