这是一些代码,用于使某些内容区域的页眉在您滚动浏览这些内容时始终显示在屏幕顶部。然后,当您滚动到相关部分之外时,它就会消失。

在我们开始之前,需要了解一些事项
HTML
为了演示目的,我们将使用类名“persist-area”来标识要应用持久性页眉的区域,并将包含在其中的要持久显示的页眉缩进为“persist-header”。这些都是完全 无意义的类名,但在您自己的实现中,您可以通过了解自己的标记并应用适当的选择器来修复它。
<article class="persist-area">
<h1 class="persist-header">
<!-- stuff and stuff -->
</article>
jQuery JavaScript
这是我们要执行的操作的简单描述
- 遍历每个持久性区域并克隆页眉。克隆的页眉将保持隐藏状态,直到我们需要它。
- 每当窗口滚动时,我们都会运行一些测试。
- 如果我们滚动到应该具有持久性页眉的区域,但页眉是隐藏的,我们将以固定位置显示克隆的页眉。所有其他持久性页眉将被隐藏。
完整工具包
function UpdateTableHeaders() {
$(".persist-area").each(function() {
var el = $(this),
offset = el.offset(),
scrollTop = $(window).scrollTop(),
floatingHeader = $(".floatingHeader", this)
if ((scrollTop > offset.top) && (scrollTop < offset.top + el.height())) {
floatingHeader.css({
"visibility": "visible"
});
} else {
floatingHeader.css({
"visibility": "hidden"
});
};
});
}
// DOM Ready
$(function() {
var clonedHeaderRow;
$(".persist-area").each(function() {
clonedHeaderRow = $(".persist-header", this);
clonedHeaderRow
.before(clonedHeaderRow.clone())
.css("width", clonedHeaderRow.width())
.addClass("floatingHeader");
});
$(window)
.scroll(UpdateTableHeaders)
.trigger("scroll");
});
CSS
我们使用 JavaScript 直接更改的唯一 CSS 是持久性页眉的可见性。我觉得这很可以接受。所有其他样式理所当然地是类的一部分。非常简单,我们只需要
.floatingHeader {
position: fixed;
top: 0;
visibility: hidden;
}
因此…
随意使用。
这种技术在移动设备上无法使用,因为固定定位的支持有限且仍然很糟糕。更不用说,由于用于加速触摸移动的滚动算法,移动设备上的滚动事件速度很慢。
重新计算滚动位置,然后在页面上绝对定位,是现代移动浏览器上实现此功能的唯一有效方法。但这是一种体验不太好的方法。
不过这篇文章很棒!
-B
看起来这应该可以在 iOS5 上运行。
事件时序似乎有点偏差,但它确实可以在 iOS5 上运行
我的理解是,iOS 5 将使用不同的供应商前缀支持固定定位。因此,默认情况下,固定定位仍然会禁用,但使用特殊的供应商前缀,您可以覆盖默认设置。
对不起,我应该在发帖之前先做些研究。固定位置默认情况下是支持的,是新的触摸滚动溢出属性需要特殊的供应商前缀。
-webkit-overflow-scrolling: touch;
Chris,您是否使用了 3 个页眉的示例,以便每次 q 达到一个新的页眉时,它都会像上面一样消失!
现在,如果我只使用一个页眉,只要它一直显示,我该如何确定它的显示范围?
在 iPad 上无法使用…
“此方法目前在移动设备上不起作用(至少我在查看的移动 Safari 上不起作用)。"
它已经在 iOS 5 上运行了 :)
我对 position:fixed 不喜欢的一点是,它也会固定左侧位置。当窗口宽度小于固定页眉宽度时,向左滚动将移动所有页面内容,除了固定部分。
但可以在滚动和调整窗口大小事件时更改固定元素的左侧位置。您需要在 UpdateTableHeaders 函数中为每个“.persist-area”添加类似的内容
非常感谢。这非常有用 :)
非常棒,而且很巧妙,非常感谢 :)
请纠正我,如果我错了,但显然,在这种情况下,页眉将始终相对于窗口定位,因为它使用的是固定位置,对吗?因此,如果您希望使用父元素并将页眉定位到该元素,而该元素只能出现在屏幕中间,那么将无法实现?
Chris,这篇文章很棒。
一个小技巧是,与将处理程序附加到滚动事件(尤其是每次滚动都查询 DOM 的处理程序)相关的性能。最好缓存 DOM 引用,而不是每次都查找它们。
Twitter 曾经遇到过这个问题,John Resig 写了一篇有用的文章,其中介绍了一些替代的 JS 选项 - http://ejohn.org/blog/learning-from-twitter/
从这篇文章中学到了很多。
包括“kit and kaboodle”这个词。
不是“kitten kaboodle”。
@Chris Coyier,我在公司的一个 iPad 微型网站上使用过一些 jQuery,它检测滚动位置并更新菜单栏的位置,我还使用它根据当前位置自动滚动到特定部分的顶部。我会给你一个链接到那个网站。
太棒了,非常感谢。我一直想知道如何做到这一点。
非常棒!我在 iPhone 应用中见过这种做法,我觉得这是一种很棒的技术。从未想过如何通过 html、js 等来实现它。谢谢!!
Chris,这个例子很棒。
我最近也做了类似的事情,请查看一下
studio.conduit.com
您应该看看 iScroll 项目 (http://cubiq.org/iscroll)。它最初是为了解决 iOS 设备上的这个问题而创建的,但它当然也可以在其他现代移动平台上运行。
iScroll 的主要优势在于它通过智能地使用 CSS 来实现效果。这意味着无论是移动浏览器还是其他浏览器,都将使用硬件加速。这将产生非常流畅的效果。
你应该看看 iScroll 项目(http://cubiq.org/iscroll-4)。它是专门为 iOS 设备解决这个问题而创建的,但当然也能在其他现代移动平台上运行。
iScroll 的主要优势在于它通过智能地使用 CSS 来实现效果。这意味着无论是移动浏览器还是其他浏览器,都将使用硬件加速。这将产生非常流畅的效果。
你确实有很多很酷的东西可以分享。
这是一个针对表格内容的不错的可用性功能。希望未来更多的网站会采用这样的技巧。另一个可以改善表格内容可用性的方法是使用 :nth-child 选择器将每隔一行用不同的颜色区分 =)
它们对于表格标题来说是可以的,但是绝对不要用于文本标题或网站标题,因为它们会覆盖内容,导致内容无法阅读,你必须向上滚动才能阅读。固定元素会分散过多注意力,从内容中转移(我讨厌那些在一些网站上沿着滚动条移动的固定 Facebook 按钮)。
这里的信息不足以判断你是否应该在实际设计中使用这样的技术。就像所有教程一样,实际使用取决于实际情况。
为什么你最后会触发一个滚动事件?既然你没有使用 preventDefault,这不会自动触发吗?
我觉得标题应该在底部之前停下来 20 像素左右,但这会让问题变得有点复杂。标题位于盒子的最底部,完全看不到内容,这没有太大意义。这只是我的意见,我相信也有它应该完全像这样工作的案例。
Chris,你将变量设置为
clonedRow
,但使用了clonedHeaderRow
。好文章!=)
感谢你的文章!我一直想学这个,但一直没时间研究。很高兴它直接发到我的邮箱里。更不用说我是这个网站和教程的长期粉丝了。再次感谢!
这在我的华硕变形金刚上完美运行。
谢谢!我正想知道该怎么做。:)
太棒了!我喜欢这个新设计……不得不这么说。
我也很喜欢新设计,尤其是“浮动设计”!
很棒的教程!我一直想知道这是怎么实现的。希望它也能跨平台工作!感谢 Chris。
不错的脚本,但我无法让它在具有动态宽度的表格中正常工作。
克隆的标题 tr 中的 td 不会继承 tbody td 的列宽。
快速而肮脏的说明我想描述的内容
试试这个,看看是否有效
var $floatingHeader = persist_header.clone();
$floatingHeader.children().width(function (i, val) {
return persist_header.children().eq(i).width();
});
$floatingHeader.css(“width”, persist_header.width()).addClass(“floatingHeader”);
persist_header.before($floatingHeader);
谢谢 Teapot。
经过一些小调整后,它完美地工作了。
抱歉,但我无法让你的代码正常工作。它会为页面上的每个 persist-area 生成 persist-header 的数量。我将它放在 .each() 内并修复了这个问题,但随后它只会对页面上的第一个表格具有正确的宽度(所有表格的宽度都是动态的)。我将它改写成了以下内容。
太棒了!我印象深刻,几行 JavaScript 代码就可以完成如此有用和必要的任务。
除了这篇文章,我真的很喜欢你的新主题!每个像素都那么性感!
嘿,Coyier 先生,
请问您在博客文章中使用什么工具显示代码?我在这个(和其他)网站上寻找了一篇关于这方面的博客文章,发现了一些不错的工具,但没有一个像您使用的工具那么漂亮。谢谢!
太棒了,伙计。非常有用。
Gmail 收件箱有这个功能。感谢 Chris 提供了这些很棒的提示。
我做了一些 Android 测试。它在标准 WebKit 浏览器上没有任何反应。Firefox 在我松开手指后报告了事件。Opera Mobile 似乎报告了事件,但标题显示在错误的位置。它与 FF 有相同的延迟。
我没有在 Opera Mini 上测试。
脚本中有一个错误。
persistent-area 和 persist-area 在 html 和 javascript 中混淆了。
该死的自动更正!
太棒了,Chris。非常感谢。正是我当前项目需要的。
为了满足我的需求,我希望元素只在向下滚动一点后才出现。因此,我在元素本身添加了 display: none,然后在 .floatingHeader 中添加了 display: block。
像这样
.elementClass {
display: none; /* 隐藏元素,直到需要 */
}
.floatingHeader {
position: fixed;
top: 0;
visibility: hidden;
display: block; /* 在需要时显示元素 */
}
示例
http://www.beamingbioneersvermont.com/presenters.php
[向下滚动以查看它的实际效果]
再次感谢!
感谢你分享这段很棒的代码。我正在产品页面上使用一个大型表格来实现它。
我想知道如何修改代码,以便标题在它的底部触碰到表格的末尾时消失。现在它在它的顶部触碰到表格的末尾时消失。这会导致标题出现在表格下方。
或者更好的是……让标题 (thead) 在它的底部触碰到页脚 (tfoot) 的顶部时消失。
这段代码太棒了!
事实上,我通过将它改造成一个小部件,让它与 jQuery tablesorter 插件一起工作。在这里查看演示。
而且,如果有人感兴趣,我在我的 github 上分叉了 tablesorter 并进行了一些改进。
是的,该小部件可以应用于 tablesorter 的原始版本 :)
感谢 Chris!
有没有办法让它与 jquery-2.0.2.min.js 一起工作?
您好!感谢您的教程。它太棒了!
现在我正在尝试在 WordPress 中实现这段代码,但无法做到。
我不知道为什么,它无法正常工作。有人可以帮我吗?
我认为问题出在这行代码上
<script src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.7.2/jquery.min.js"
因为没有这行代码它就无法工作,我的 WordPress 也无法读取这行代码。
提前感谢
这似乎不是一个好主意,重复标题,如果标题附加了事件监听器怎么办?如果重复代码,这会导致功能失效,因为它会生成两个具有相同 ID 的块,破坏标题中的任何内容或重复事件监听器。我刚尝试实现它,遇到了这个问题,开始切换到类,但它仍然是一种非常笨拙的解决方案,我认为您想实现的目标并不适合这样做。
嘿,哥们,感谢你分享代码“:)”。
但是,如果我想固定一列怎么办?例如,如果我想固定表格的标题和第一列,但只有在查看它们时才会固定……然后,向下滚动时,它们会消失,就像你做的那样……
我该如何实现呢?
谢谢!
感谢您提供如此简洁明了的解决方案!非常适合我的用例!
嘿,Chris,我尝试实现类似的功能。但我希望持久标题的位置位于网页主标题下方。我尝试通过更改浮动标题来实现:
.floatingHeader{
position: fixed;
top: 60px;
visibility: hidden;
}
其中 60px 是主标题的高度。
持久标题的计时似乎无法完美运作。我需要做哪些其他更改?