滚动时如何使页面头部保持在顶部?

5

我已经阅读了许多关于这个主题的文章,并尝试实现了一些,但我似乎做不对。我有一个简单的HTML表格,用来比较产品:

<table>
  <tr>
    <th>Product:</th>
    <th>Product 1</th>
    <th>Product 2</th>
    <th>Product 3</th>
  </tr>
  <tr>
    <td>Features</td>
    <td>Product 1 features</td>
    <td>Product 2 features</td>
    <td>Product 3 features</td>
   </tr>
   and so the list goes on...
 </table>

我想要的是表头始终置于活动窗口顶部,也就是说,在我向下滚动时,顶行应该保持不变,因为我的行数相当多。我想让产品名称一直显示在标签中,以便用户能够将内容与不同产品相关联并始终在顶部行中查看。
谢谢!

可能是重复问题:http://stackoverflow.com/q/983031/214773 - Julio Santos
@JúlioSantos:不,这个问题根本没有提到jQuery(甚至JavaScript)。 - T.J. Crowder
哦,好的,我明白了。我会添加一个答案。 - Julio Santos
4个回答

6
一个简单的技巧是将头部行放在一个独立的中,与实际数据分开。
fixedmargin-topheight

http://jsfiddle.net/zKDR4/2/http://fixedheadertable.com/编辑thtd
这个头部表格设置其位置为,然后下面的表格,即包含结果的表格,将其设置为头部表格的。这样可以创建头部保持原位而表格滚动的效果。一个基本的示例在这里: 你也可以使用jQuery插件创建固定的头部。看看这个非常简单实用。 正如Anders所提到的,如果你按照我的建议进行操作,你需要设置和元素的宽度。否则它们不会匹配,因为它们是分开的表格。

2
如果th和td的宽度不同,这种方法将无法很好地工作,而它们通常是不同的。然而,如果单元格(包括标题)具有固定且相等的大小,则此方法非常有效。 (+1仍然是最佳解决方案,我认为,也是一个不错的jquery提示) - Anders Arpi
@AndersHolmström 是的,在这种情况下,您需要设置 thtd 的宽度。我认为最好的解决方案是使用一个 jQuery 插件,该插件从表格中构建标题表格,以便宽度正确。 - Tim B James
1
好的答案,谢谢,它运行良好。然而,在小屏幕(移动屏幕)上查看时,您必须水平滚动。现在这就带来了一个问题,因为当您水平滚动时,固定的标题也会水平滚动(因为它是固定的,并且部分超出窗口)。我该如何仅垂直固定它? - DextrousDave
对于移动屏幕,我会尽量避免水平滚动。可以研究响应式CSS。 - Tim B James

0

我遇到了一个问题,需要在行标题(小时)和列标题(天)的计划中保持可见性。

应用程序在IFrame中显示内容,因此我创建了一个水平DIV和一个垂直DIV,在IFrame外部使用样式“overflow:hidden”。

然后,我使用IFrame的“onscroll”事件同步滚动。

以下是我的代码以使标题与滚动同步:

window.onscroll = function () {

        try {
            // - Scroll days header (on the top) horizontally
            var offsetX = (document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft; // Source: https://dev59.com/F3E85IYBdhLWcg3wkkU8
            var header1Div = window.parent.document.getElementById("EntetesColonnes");
            header1Div.scrollLeft = offsetX;

            // - Scroll hours header (on the left) vertically 
            var offsetY = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop; // Source: https://dev59.com/F3E85IYBdhLWcg3wkkU8
            var header2Div = window.parent.document.getElementById("HeaderHoursLeft");
            header2Div.scrollTop = offsetY;
        }
        catch (ex) {
            alert("FrmPlanningChirurgien/window.onscroll: " + ex.message);
        }
    }

我的解决方案并不简单,因为我必须在“onresize”中设置水平DIV的宽度和垂直DIV的高度。 然后这就引起了更多的复杂性,因为onResize可能会每秒钟触发很多次,并且当滚动发生时,甚至在IE8中也会触发此事件。 因此,我使用了setTimeout来防止标题过于频繁地重新绘制:

var PREVIOUS_frameWidth = 0;
var PREVIOUS_frameHeight = 0;
var timerMakeHeaders = null;

window.onresize = function () {
    try {

        var frameWidth = CROSS.getWindowWidth();
        var frameHeight = CROSS.getWindowHeight();

        if (frameWidth != PREVIOUS_frameWidth || frameHeight != PREVIOUS_frameHeight) {

            // - *** Launch headers creation method
            // - If there is another query to redraw, the Timer is stopped and recreated.
            // - The headers are only redrawn when Timer fires.
            if (timerMakeHeaders != null) {
                window.clearTimeout(timerMakeHeaders);
                timerMakeHeaders = null;
            }
            timerMakeHeaders = window.setTimeout(makeHeaders, 50); 

            // - *** Store new values
            PREVIOUS_frameWidth = frameWidth;
            PREVIOUS_frameHeight = frameHeight;
        }
    } catch (e) { alert("Erreur window.onresize/FrmPlanningChirurgien.aspx : " + e.message); }
}

最后,makeHeaders() 方法必须调整 DIV 的大小。
function makeHeaders() {

    // (...)

    var frame = window.parent.document.getElementById("CalendarFrame"); 
    var iframeRect = frame.getBoundingClientRect(); 
    headerDiv.style.width = iframeRect.right - iframeRect.left - 20; // The 20 pixels are here for the vertical scrollbar width
    headerDiv.scrollLeft = frame.scrollLeft;

    // (...)


    var headerHourDiv = window.parent.document.getElementById("HeaderHoursLeft");
    var newHeight = iframeRect.bottom - iframeRect.top - 20 - 7; // The VISIBLE width for the DIV must be equal to IFRAME Width minus the scroll width or height
    headerHourDiv.style.height = newHeight; 
    headerHourDiv.scrollTop = frame.scrollTop;       


}
catch (e) {
    alert("makeHeaders: " + e.message);
}    }

也许可以不使用IFRAME,仅使用3个DIV:一个用于每个标题,最后一个用于内容。但我认为机制必须相同:需要在滚动位置之间进行同步。
此致敬礼,

-1

我已经使用JSFiddle创建了一个示例,您可以查看演示

唯一的缺点是,当您使用position: fixed时,您需要指定列大小,因为您会失去标题的宽度。

这是示例的CSS,HTML与您提供的相同。

thead {
    height: 1em;
}

thead tr {
    position: fixed;
    background-color: #FFF;
}

-2
你可以通过创建一个 div 并固定其位置来实现此目的,或者也可以通过添加内联 CSS 来完成。
<table style="position:fixed;">
  <tr>
     <th>Product:</th>
     <th>Product 1</th>
     <th>Product 2</th>
      <th>Product 3</th>
  </tr>
  <tr>
    <td>Features</td>
     <td>Product 1 features</td>
     <td>Product 2 features</td>
     <td>Product 3 features</td>
   </tr>
  </table>

2
这并不是问题所要求的。它只是将整个表格固定在页面上的一个位置。 - srk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接