我正在尝试创建一个页面,其中有多个部分,当您滚动标题时,您所在的标题始终显示在页面顶部(在固定元素中)。我希望获得与iPhone相同的效果,当你滚动它时“推”旧标题并取而代之。
我已经看过它完成了列表,但我想用多个HTML5部分来完成它。
例如:
<section>
<h1>Header 1</h1>
<p>Text for section</p>
</section>
<section>
<h1>Header 2</h1>
<p>Text for section</p>
</section>
有没有人有任何想法?
由于
答案 0 :(得分:5)
我很想做这件事,看到@ AlienWebguy的作品激励我最终接受它。他的JSFiddle令人印象深刻,但需要做很多工作。我认为这个解决方案已经可以在我的生产应用程序中使用了。
http://jsfiddle.net/RichardBronosky/VMnnr/
<强> HTML:强>
<body>
<div class="tableview">
<div id="header1" class="header">
<h2>Header 1</h2>
</div>
<div id="header1_content">
<p>
header1_content1
</p>
<p>
header1_content2
</p>
<p>
header1_content3
</p>
</div>
<div id="header2" class="header">
<h2>Header 2</h2>
</div>
<div id="header2_content">
<p>
header2_content1
</p>
<p>
header2_content2
</p>
<p>
header2_content3
</p>
</div>
<div id="header3" class="header">
<h2>Header 3</h2>
</div>
<div id="header3_content">
<p>
header3_content1
</p>
<p>
header3_content2
</p>
<p>
header3_content3
</p>
</div>
</div>
</body>
<强> CSS:强>
body {
font-family:Helvetica,Arial,san-serif;
}
div.tableview {
background-color:#CCC;
}
.tableview p:nth-child(odd) {
background-color:#FFF;
}
.tableview p:nth-child(even) {
background-color:#F0F0F0;
}
.tableview p {
padding:8px;
margin:1px 0px 1px 0px;
}
body, .tableview p:last-of-type, .tableview p:first-of-type, .tableview .header h2 {
margin:0px;
}
.tableview .header {
background-color:#333;
color:#FFF;
width:100%;
position:relative;
}
.tableview .header h2 {
padding:8px 4px 8px 4px;
}
.tableview .fixed {
position:fixed;
top:0;
left:0;
}
JAVASCRIPT :(依赖于jQuery)
// From: http://jsfiddle.net/AlienWebguy/mvtP7/1/ via: http://stackoverflow.com/questions/6720847
$(function(){
var lastScrollTop = 0;
// When the first header is given a fixed position, the inline content that follows with shift up.
el = $('.header').first();
// To over come this: clone it, make it invisible, remove id tags from it and its children, attach it before the original
el.before(el.clone(false).css({'visibility':'hidden'}).removeAttr("id").find("*").removeAttr("id").end()).addClass('fixed');
$(window).scroll(function(event){
var currentScrollTop = $(this).scrollTop();
$('.header').each(function(){
if($(this).hasClass('fixed')){
if (currentScrollTop > lastScrollTop){
console.log('scrolling down');
var _next_header = $(this).nextUntil('.header').next('.header');
if($(_next_header).length > 0){
if($('body').scrollTop() > $(_next_header).offset().top){
console.log("Bottom of header hit top of next header")
$(this).removeClass('fixed');
$(_next_header).addClass('fixed');
}
}
} else {
console.log('scrolling up');
var _prev_header = $(this).prevUntil('.header').prev('.header');
if($(_prev_header ).length > 0){
if($('body').scrollTop() < $('.fixed').next().offset().top-$('.fixed').height()){
console.log("Top of header hit bottom of previous content box")
$(this).removeClass('fixed');
$(_prev_header).addClass('fixed');
}
}
}
}
});
lastScrollTop = currentScrollTop;
});
});
答案 1 :(得分:2)
你走了,非常相似:
http://jsfiddle.net/AlienWebguy/mvtP7/1/
<强> HTML:强>
<div id="header1" class="header fixed">
<h2>Header1</h2>
</div>
<div id="header1_content">
<p>Lorem ipsum dolor sit amet...</p>
</div>
<div id="header2" class="header relative">
<h2>Header2</h2>
</div>
<div id="header2_content">
<p>Lorem ipsum dolor sit amet...</p>
</div>
<div id="header3" class="header relative">
<h2>Header3</h2>
</div>
<div id="header3_content">
<p>Lorem ipsum dolor sit amet...</p>
</div>
<强> CSS:强>
p {
background-color:#F0F0F0;
}
.header {
background-color:#CCC;
width:100%;
top:0;
left:0;
}
.header h2 {
margin:20px;
}
.fixed {
position:fixed;
}
.relative {
position:static;
}
#header1_content {
margin-top:80px;
}
<强> JQuery的:强>
$(function(){
var lastScrollTop = 0;
$(window).scroll(function(event){
var currentScrollTop = $(this).scrollTop();
if (currentScrollTop > lastScrollTop){
// Scrolling down
$('.header').each(function(){
if($(this).hasClass('fixed'))
{
var _next_header = $(this).nextUntil('.header').next('.header');
if($(_next_header).length > 0)
{
if(($(this).offset().top + $(this).height()) >= $(_next_header).offset().top)
{
// Bottom of header hit top of next header
$(this).removeClass('fixed').addClass('relative');
$(_next_header).removeClass('relative').addClass('fixed');
}
}
}
});
}
else
{
// Scrolling up
$('.header').each(function(){
if($(this).hasClass('fixed'))
{
var _prev_header = $(this).prevUntil('.header').prev('.header');
if($(_prev_header ).length > 0)
{
if($(this).offset().top <= ($('#' + $(_prev_header).attr('id') + '_content').offset().top + $(this).height()))
{
// Top of header hit bottom of previous content box
$(this).removeClass('fixed').addClass('relative');
$(_prev_header).removeClass('relative').addClass('fixed');
}
}
}
});
}
lastScrollTop = currentScrollTop;
});
});
基本上我们正在做的是创建一些基本的碰撞检测。当我们向下滚动时,我们检测当前标题的底部是否与下一个标题的顶部发生碰撞。如果是,我们将其换掉。当我们向上滚动时,我们检测当前标题的顶部是否与前一个内容容器的底部碰撞并进行交换。
将其提升到更高级别以更准确地模拟iPhone菜单,你可能想要在它们碰撞时动态地重新定位DOM中的标题,这会产生一个“推动另一个”的错觉的方式“,然后一旦前一个离开屏幕,你将固定定位应用于新的标题。这个演示应该至少让你走上正确的轨道:)
希望这有帮助!
答案 2 :(得分:0)
我还没有看到你谈到的iphone版本,但从你如何描述它我已经知道它是什么样的。
我看到的问题是标题有两个上下文。首先它们位于页面中,其次它们位于页面顶部的固定元素中。你还没有说,但我认为如果你要滚动另一个方向,标题将不得不改变相反的方向。
一种方法是给固定元素一个固定的高度和隐藏的溢出。然后有一个innerdiv,其中包含所有页面标题的副本。给内部div相对定位。在javascript中,向页面中的所有标题添加一个事件,当它们到达窗口顶部以触发动画时触发。使用jQuery为固定元素的innerdiv的位置设置动画,以便显示下一个标题。