【问题标题】:Recreate the iOS UITableView with HTML使用 HTML 重新创建 iOS UITableView
【发布时间】:2011-07-16 23:05:31
【问题描述】:

我正在尝试创建一个包含多个部分的页面,并且当您滚动时,您所在的标题始终显示在页面顶部(在固定元素中)。我想达到与 iPhone 上相同的效果,当您滚动它时,它会将旧标题“推开”并替换它。

我已经看到它是用列表完成的,但我想用多个 HTML5 部分来完成。

例如:

<section>
<h1>Header 1</h1>
<p>Text for section</p>
</section>

<section>
<h1>Header 2</h1>
<p>Text for section</p>
</section>

有人知道吗?

谢谢

【问题讨论】:

标签: jquery iphone html uitableview header


【解决方案1】:

我想这样做很久了,看到@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;
    });
});

【讨论】:

【解决方案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 中动态重新定位标题,当它们发生碰撞时,这会产生一种“将另一个推出”的错觉的方式”,然后一旦前一个离开屏幕,您就会将固定定位应用于新标题。这个演示至少应该让你走上正轨:)

希望这会有所帮助!

【讨论】:

  • 不幸的是,当您滚动内容时,它的编码方式会跳动。
  • 这不应该太难适应内容的一些定位:)
  • 我下面的回答解决了这个问题。但是,我必须同意,如果您仍然要使用 jquery,@tborychowski 发现的插件看起来非常可靠。 polarblau.github.io/stickySectionHeaders
【解决方案3】:

我没有看过你说的iphone版本,但从你的描述我知道它是什么样子的。

我看到的问题是标题有两个上下文。首先它们在页面中,其次它们在页面顶部的固定元素中。您还没有说,但我认为如果您要以其他方式滚动,标题将不得不朝相反的方向改变。

一种方法是给固定元素一个固定的高度和隐藏的溢出。然后有一个包含所有页面标题副本的 innerdiv。给内部 div 相对定位。在 javascript 中,向页面中的所有标题添加一个事件,当它们到达窗口顶部以触发动画时触发。使用 jQuery 为固定元素的 innerdiv 的位置设置动画,使其显示下一个标题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多