Воссоздайте iOS UITableView с HTML - PullRequest
8 голосов
/ 17 июля 2011

Я пытаюсь создать страницу, где есть несколько разделов, и когда вы прокручиваете заголовок, он всегда отображается вверху страницы (в фиксированном элементе).Я хочу добиться того же эффекта, что и на iPhone, когда при прокрутке он «выталкивает» старый заголовок и заменяет его.

Я видел, что это сделано со списками, но я хочу этос несколькими разделами HTML5.

Например:

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

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

У кого-нибудь есть идеи?

Спасибо

Ответы [ 3 ]

5 голосов
/ 15 августа 2013

enter image description here

Я давно хотел это сделать, и, увидев работу @ 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>
* ** 1013 1014 * CSS: * ** 1015 1016 *
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 голосов
/ 17 июля 2011

Вот, пожалуйста, довольно похоже:

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 на лету, когда они сталкиваются, что создаст иллюзию того, что один «выталкивает другой» of the way ", затем, как только предыдущий выйдет за пределы экрана, вы примените фиксированное позиционирование к новому заголовку. Эта демоверсия должна как минимум привести вас на правильный путь:)

Надеюсь, это поможет!

0 голосов
/ 17 июля 2011

Я не видел версию iphone, о которой вы говорите, но по тому, как вы ее описываете, я понимаю, на что это похоже.

Проблема, как я вижу, состоит в том, что заголовки имеют два контекста.Во-первых, они находятся на странице, а во-вторых, они находятся в фиксированном элементе вверху страницы.Также вы не сказали, но я предполагаю, что если бы вы прокручивали в противном случае, заголовки должны были бы измениться в противоположном направлении.

Один из подходов - дать фиксированному элементу фиксированную высоту и скрытое переполнение.Тогда есть innerdiv, который содержит копию всех заголовков страниц.Дайте внутреннему div относительное расположение.В javascript добавьте событие ко всем заголовкам, которые находятся на странице, которые запускаются, когда они достигают верхней части окна, чтобы вызвать анимацию.Используйте jQuery для анимации позиции innerdiv фиксированного элемента, чтобы он обнаруживал следующий заголовок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...