jQuery 修复页面滚动上的标题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2382083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:22:59  来源:igfitidea点击:

Fix thead on page scroll

jquery

提问by egidiocs

Situation: A page with a table with several rows. I want to fix thead when thead reach the top of the page when scrolling, using jquery or any given scripting. I don't want to overflow the table itself.

情况:一个页面有一个多行的表格。我想在滚动时,使用 jquery 或任何给定的脚本,当 thead 到达页面顶部时修复 thead。我不想让桌子本身溢出。

回答by James Thatcher

You can use Lobstrosity's code with a slight modification: position: fixedinstead of absolute.

您可以使用 Lobstrosity 的代码稍加修改:position: fixed而不是absolute.

position: fixedis now widely adopted by all browsers including IE8 and onwards. BTW fixed renders much nicer on mobile/tablet devices than position: absolute.

position: fixed现在被包括 IE8 在内的所有浏览器广泛采用。BTW fixed 在移动/平板设备上的渲染效果比position: absolute.

I found that on a table with dynamic widths for each column, the absolutely positioned <thead> would lose the widths of the rest of the columns, so to fix this I came up with the following code:

我发现在每列都有动态宽度的表格上,绝对定位的 <thead> 会丢失其余列的宽度,因此为了解决这个问题,我想出了以下代码:

What this code does is as follows:

这段代码的作用如下:

Determines the widths of each column in your table by looking up the CSS widths of the first <tbody> <tr> <td> row and storing these in an array for later. When the user scrolls the class 'fixed' is added to the <thead> (Default browser behaviour will alter the widths of the <th>'s and they won't match up with the <tbody>. So to fix this we retroactively set the widths of the <th> to the values we've read earlier.

通过查找第一个 <tbody> <tr> <td> 行的 CSS 宽度并将它们存储在一个数组中以供以后确定表中每列的宽度。当用户滚动时,'fixed' 类被添加到 <thead>(默认浏览器行为会改变 <th> 的宽度,它们不会与 <tbody> 匹配。所以为了解决这个问题,我们追溯将 <th> 的宽度设置为我们之前读过的值。

Anyway here's the code:

无论如何这里的代码:

CSS

CSS

table.entries {width: 100%;border-spacing: 0px;margin:0;}
table.entries thead.fixed {position:fixed;top:0;}

HTML

HTML

<table class="entries" id="entriestable">
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Location</th>
            <th>DOB</th>
            <th>Opt&nbsp;in</th>
            <th>Added</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="name">Ricky Bobby</td>
            <td>[email protected]</td>
            <td class="addy"><i>Kent, GB</i></td>
            <td class="dob">20/08/1984</td>
            <td>Yes</td>
            <td class="date">4 hours ago</td>
        </tr>
    </tbody>
</table>

JavaScript

JavaScript

TableThing = function(params) {
    settings = {
        table: $('#entriestable'),
        thead: []
    };

    this.fixThead = function() {
        // empty our array to begin with
        settings.thead = [];
        // loop over the first row of td's in &lt;tbody> and get the widths of individual &lt;td>'s
        $('tbody tr:eq(1) td', settings.table).each( function(i,v){
            settings.thead.push($(v).width());
        });

        // now loop over our array setting the widths we've got to the &lt;th>'s
        for(i=0;i<settings.thead.length;i++) {
            $('thead th:eq('+i+')', settings.table).width(settings.thead[i]);
        }

        // here we attach to the scroll, adding the class 'fixed' to the &lt;thead> 
        $(window).scroll(function() {
            var windowTop = $(window).scrollTop();

            if (windowTop > settings.table.offset().top) {
                $("thead", settings.table).addClass("fixed");
            }
            else {
                $("thead", settings.table).removeClass("fixed");
            }
        });
    }
}
$(function(){
    var table = new TableThing();
    table.fixThead();
    $(window).resize(function(){
        table.fixThead();
    });
});

回答by Lobstrosity

Here's something that kind ofworks (quickly tested in FF 3.5, Chrome 3, and IE 8) that you might be able to tailor to your needs.

这是您可以根据自己的需要进行定制有效方法(在 FF 3.5、Chrome 3 和 IE 8 中快速测试)。

It uses absolute positioning of the thead. When the theadbecomes absolutely positioned, this basically removes it from the original flow of the tableand the widths of all the tbodytds adjust accordingly. So you get ugly behavior if you don't specify column widths or if any column's header is wider than any other cell in that column.

它使用thead. 当sthead变为绝对定位时,这基本上将其从s的原始流中移除,table并且所有tbodytds的宽度都会相应调整。因此,如果您不指定列宽或者任何列的标题比该列中的任何其他单元格都宽,则会出现丑陋的行为。

CSS

CSS

#Grid thead.Fixed
{
    position: absolute;
}

HTML

HTML

<table id="Grid">
    <thead>
        <tr>
            <td>A</td>
            <td>B</td>
            <td>C</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <!-- etc. -->
    </tbody>
</table>

jQuery

jQuery

$(function() {
    var table = $("#Grid");

    $(window).scroll(function() {
        var windowTop = $(window).scrollTop();

        if (windowTop > table.offset().top) {
            $("thead", table).addClass("Fixed").css("top", windowTop);
        }
        else {
            $("thead", table).removeClass("Fixed");
        }
    });
});

I noticed that it does not work in IE unless you specify a strict XHTML doctype:

我注意到它在 IE 中不起作用,除非您指定严格的 XHTML 文档类型:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <!-- etc. -->

回答by Lukas Ignatavi?ius

(function ($) {
    $.fn.fixedHeader = function () {
        return this.filter('table').each(function () {
            var that = this;
            var $head = $('<div></div>').addClass('head');
            $(this).before($head);
            $('th', this).each(function () {
                var $el = $(this);
                var $div = $('<div></div>').width($el.outerWidth()).text(
                $el.text());
                $head.append($div);
            });
            $(window).on('scroll', function () {
                var $that = $(that);
                var w = $(window).scrollTop();
                var o = $('th', that).first().offset().top;
                var tableO = $that.offset().top + $that.height();
                if (o < w && tableO > w) {
                    $head.show();
                } else {
                    $head.hide();
                }
            });
        });
    };
})(jQuery);

You can use this jquery plugin (you need to adapt .head style to your thead style). Working example here: http://jsfiddle.net/lukasi/7K52p/1/

您可以使用此 jquery 插件(您需要将 .head 样式调整为您的 thead 样式)。这里的工作示例:http: //jsfiddle.net/lukasi/7K52p/1/