2011-07-16 16 views
8

Estoy intentando crear una página en la que hay varias secciones y mientras se desplaza, el encabezado en el que se encuentra siempre se muestra en la parte superior de la página (en un elemento fijo). Quiero lograr el mismo efecto que en el iPhone, ya que cuando lo desplazas "empuja" el viejo encabezado fuera del camino y lo reemplaza.Recrear el UITableView de iOS con HTML

Lo he visto hecho con listas, pero quiero hacerlo con múltiples secciones HTML5.

Por ejemplo:

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

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

¿Alguien tiene alguna idea?

Gracias

+2

Ha intentado nada – meo

+4

el mejor que he encontrado: http://polarblau.github.io/stickySectionHeaders/ – tborychowski

Respuesta

2

Aquí tiene, bastante similares:

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; 
    }); 
}); 

Así que, esencialmente lo que estamos haciendo es crear algo de la detección básica de colisión. Cuando nos desplazamos hacia abajo, detectamos si la parte inferior del encabezado actual colisiona con la parte superior del siguiente encabezado. Si lo hace, lo cambiamos. Cuando nos desplazamos hacia arriba, detectamos si la parte superior del encabezado actual colisiona con la parte inferior del contenedor de contenido anterior y realiza el intercambio.

Llevando esto al siguiente nivel para emular con mayor precisión el menú del iPhone, probablemente desee volver a colocar los encabezados dentro del DOM sobre la marcha cuando colisionen, lo que daría la ilusión de que uno "empuja al otro fuera del camino ", una vez que el anterior está fuera de la pantalla, aplicaría el posicionamiento fijo al nuevo encabezado. Esta demo debería llevarlo por el camino correcto al menos :)

Espero que esto ayude!

+0

1 Bien hecho @AlienWebguy –

+1

desgracia con la forma en que se codifica como se desplaza el contenido salta de las . –

+0

que no debería ser demasiado difícil de acomodar con cierto posicionamiento del contenido :) – AlienWebguy

0

no he visto la versión iPhone se habla sino de cómo lo describes tengo una idea de lo que es.

El problema es que los encabezados tienen dos contextos. Primero están en la página y en segundo lugar están en un elemento fijo en la parte superior de la página. Tampoco lo ha dicho, pero supongo que si tuviera que desplazarse hacia el otro lado, los encabezados tendrían que cambiar en la dirección opuesta.

Un enfoque sería dar al elemento fijo una altura fija y un desbordamiento oculto. Luego, tenga un innerdiv que contenga una copia de todos los encabezados de página. Dar el posicionamiento relativo div interno. En javascript, agregue un evento a todos los encabezados que están en la página que se dispara cuando llegan a la parte superior de la ventana para activar la animación. Use jQuery para animar la posición del innerdiv del elemento fijo para que revele el siguiente encabezado.

5

enter image description here

Yo he querido hacer esto desde hace mucho tiempo y ver el trabajo de @ AlienWebguy me inspiró para finalmente adoptan.Su JSFiddle fue impresionante, pero necesitaba mucho trabajo. Creo que esta solución está casi lista para usar en mi aplicación de producción.

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: (se basa en 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

Si va a utilizar jquery de todos modos, puede considerar usar este complemento: http://polarblau.github.io/stickySectionHeaders –

Cuestiones relacionadas