【问题标题】:Keeping header element always on top when scrolling?滚动时保持标题元素始终位于顶部?
【发布时间】:2012-01-23 13:48:06
【问题描述】:

我已阅读有关此主题的大量文章并尝试实施一些,但我似乎无法做到正确。我有一个简单的 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>

我想要的是标题行始终位于活动窗口的顶部,即向下滚动时的顶行,因为我的行向下走得很远。我想让标签中的产品名称始终可见,以便用户可以始终将内容与最顶行中的不同产品相关联。

提前谢谢你!

【问题讨论】:

  • @JúlioSantos:不,这个问题根本没有提到 jQuery(甚至 JavaScript)。
  • 哦,好的,重点。我会添加一个答案。

标签: html css


【解决方案1】:

我的简单技术是将标题行与实际数据分开table。 这个头表被设置为它的位置为fixed,然后下面的表格,它保存了结果,它的margin-top设置了头表的height

这会产生标题停留在原处和表格滚动的效果。

这里有一个基本示例:http://jsfiddle.net/zKDR4/2/

您还可以使用 jQuery 插件创建固定标题。看看这个http://fixedheadertable.com/ 实现起来真的很简单。

编辑

正如 Anders 所提到的,如果您沿着我建议的路线走,您将需要设置 thtd 元素的宽度。否则它们将不匹配,因为它们是单独的表。

【讨论】:

  • 如果 th 和 td 的宽度不同(通常情况下),这将无法正常工作。如果单元格(包括标题)具有固定且相等的大小,那么这非常有效。 (+1 仍然是我认为的最佳解决方案,也是不错的 jquery 提示)
  • @AndersHolmström 是的,在这种情况下,您需要设置 thtd 的宽度。我觉得最好的解决方案是使用一个 jquery 插件,它从表中构建标题表,以便宽度正确。
  • 好的答案谢谢,它运作良好。但是,在小屏幕(手机屏幕)上观看时,您必须水平滚动。现在这带来了一个问题,因为当您水平滚动时,固定标题也会水平滚动(因为它是固定的,并且部分超出了窗口)。我如何只垂直修复它?
  • 对于移动屏幕,我会尝试摆脱水平滚动。查看响应式 CSS。
【解决方案2】:

我在计划行标题(小时)和列标题(天)时遇到了问题。 我想让两者都可见。 该应用程序在 IFrame 中显示内容,因此我在 IFrame 之外创建了一个水平 DIV 和一个垂直 DIV,其样式为“溢出:隐藏”。 然后我将滚动与 IFrame 的“onscroll”事件同步。

这是我将标题与滚动同步的代码:

window.onscroll = function () {

        try {
            // - Scroll days header (on the top) horizontally
            var offsetX = (document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft; // Source: http://stackoverflow.com/questions/2717252/document-body-scrolltop-is-always-0-in-ie-even-when-scrolling
            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: http://stackoverflow.com/questions/2717252/document-body-scrolltop-is-always-0-in-ie-even-when-scrolling
            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 个 DIVS:每个标题一个,最后一个用于内容。但我认为机制必须相同:需要滚动位置之间的同步。

最好的问候,

【讨论】:

    【解决方案3】:

    我已经创建了一个使用 JSFiddle 的示例,您可以view as a demo

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

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

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

    【讨论】:

      【解决方案4】:

      您可以通过制作一个 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>
      

      【讨论】:

      • 这不符合问题的要求。它只是将整个表格固定到页面上的一个位置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 2012-03-18
      • 2020-07-21
      相关资源
      最近更新 更多