简体   繁体   English

滚动时保持标题元素始终在顶部?

[英]Keeping header element always on top when scrolling?

I've read numerous articles on this topic and tried implementing a few, but I just can't seem to get it right. 我已经阅读了很多关于这个主题的文章并试图实现一些,但我似乎无法做到正确。 I have a simple HTML table, which compares products: 我有一个简单的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>

What I want is for the header row to always be on top of the active window, that is the top row when I scroll down, since my rows go down quite far. 我想要的是标题行始终位于活动窗口的顶部,这是我向下滚动时的顶行,因为我的行向下走得很远。 I want to keep the product names in the tags always visible so that a user can relate the content to the different products in the very top row all the time. 我希望标签中的产品名称始终可见,以便用户可以始终将内容与最上一行中的不同产品相关联。

Thank you in advance! 先感谢您!

I simple technique is to have the header row in a separate table from the actual data. 我简单的技术是将标题行放在与实际数据不同的table This header table is set to have it's position as fixed , and then the table below, which holds the results, has it's margin-top set the height of the header table. 这个标题表被设置为fixed它的位置,然后下面的表格保存结果,它的margin-top设置了标题表的height

This creates the effect of the header staying where it is and the table scrolling. 这会产生标题保持原样和表格滚动的效果。

A basic example here: http://jsfiddle.net/zKDR4/2/ 这里有一个基本的例子: http//jsfiddle.net/zKDR4/2/

You can also create a fixed header with jQuery plugins. 您还可以使用jQuery插件创建固定标头。 Take a look at this one http://fixedheadertable.com/ really simple to implement. 看看这个http://fixedheadertable.com/真的很简单实现。

Edit 编辑

As Anders has mentioned, if you go down my suggested route, you will need to set the widths of the th and td elements. 正如Anders所提到的,如果你沿着我建议的路线走下去,你需要设置thtd元素的宽度。 Otherwise they would not match up since they are separate tables. 否则他们不会匹配,因为他们是单独的表。

I had the problem for a planning with row headers (hours) and column headers (days). 我遇到了行标题(小时)和列标题(天)的规划问题。 I wanted to keep visible the both. 我想保持两者的可见性。 The application shows the content in an IFrame, so I've created an horizontal DIV and a vertical DIV outside the IFrame with a style "overflow:hidden". 应用程序在IFrame中显示内容,因此我在IFrame外部创建了一个水平DIV和一个垂直DIV,其样式为“overflow:hidden”。 Then I've synchronized the scrollings with the "onscroll" event of the IFrame. 然后我将滚动与IFrame的“onscroll”事件同步。

Here is my code to synchronize headers with scrolling: 这是我的代码,用于将标题与滚动同步:

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);
        }
    }

My solution is not that simple, because I had to set in "onresize" the width of horizontal DIV and the height of vertical DIV. 我的解决方案并不那么简单,因为我必须在“onresize”中设置水平DIV的宽度和垂直DIV的高度。 Then this induces more complexity, because onResize could be fired a lot of times per second, and this event is even fired in IE8 when scrolling occurs. 然后这会引起更多的复杂性,因为onResize每秒可能被触发很多次,并且当滚动发生时甚至会在IE8中触发此事件。 So I've done a setTimeout to prevent headers to be redrawn too often : 所以我做了一个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); }
}

And finally the makeHeaders() method have to resize DIVs : 最后, 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);
}    }

Perhaps it could be possible not to use an IFRAME, and to use only 3 DIVS: one for each header, and the last one for the content. 也许有可能不使用IFRAME,并且只使用3个DIVS:每个标题一个,内容的最后一个。 But the mechanism have to be the same I think : needs a synchronization between scrolling positions. 但我认为机制必须相同:需要滚动位置之间的同步。

Best regards, 最好的祝福,

I have created an example using JSFiddle, which you can view as a demo . 我使用JSFiddle创建了一个示例,您可以将其视为演示

The only downside is that you will need to specify column sizes as when you use position: fixed you lose the widths on the header. 唯一的缺点是,当您使用position: fixed时,您需要指定列大小position: fixed丢失标题上的宽度。

This is the CSS for the example, the HTML is the same as that you have supplied. 这是示例的CSS,HTML与您提供的相同。

thead {
    height: 1em;
}

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

You can do this by make a div and fix the position . 你可以通过制作div来修复位置。 or it can also done by adding inline css 或者它也可以通过添加内联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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM