Html 滚动时保持标题元素始终在顶部?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8972643/
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
Keeping header element always on top when scrolling?
提问by DextrousDave
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!
先感谢您!
回答by Tim B James
I simple technique is to have the header row in a separate table
from the actual data.
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.
我的简单技术是将标题行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. Take a look at this one http://fixedheadertable.com/really simple to implement.
您还可以使用 jQuery 插件创建固定标题。看看这个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. Otherwise they would not match up since they are separate tables.
正如安德斯提到的,如果你按照我建议的路线走,你需要设置th
和td
元素的宽度。否则它们不会匹配,因为它们是单独的表。
回答by Elo
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". Then I've synchronized the scrollings with the "onscroll" event of the IFrame.
我在规划行标题(小时)和列标题(天)时遇到了问题。我想让两者都可见。该应用程序在 IFrame 中显示内容,因此我在 IFrame 外部创建了一个水平 DIV 和一个垂直 DIV,其样式为“溢出:隐藏”。然后我将滚动与 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. 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. So I've done a setTimeout to prevent headers to be redrawn too often :
我的解决方案没有那么简单,因为我必须在“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); }
}
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. But the mechanism have to be the same I think : needs a synchronization between scrolling positions.
也许可以不使用 IFRAME,而只使用 3 个 DIVS:每个标题一个,最后一个用于内容。但我认为机制必须相同:需要滚动位置之间的同步。
Best regards,
此致,
回答by Fenton
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
会丢失标题上的宽度。
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;
}
回答by Fenton
You can do this by make a div and fix the position . or it can also done by adding inline css
您可以通过制作一个 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>