2012-01-23 23 views
5

He leído numerosos artículos sobre este tema y he intentado implementar algunos, pero parece que no puedo hacerlo bien. Tengo una tabla HTML sencilla, que compara los productos¿Mantener el elemento de encabezado siempre en la parte superior cuando se desplaza?

<table> 
    <tr> 
    <th>Product:</th> 
    <th>Product 1</th> 
    <th>Product 2</th> 
    <th>Product 3</th> 
    </tr> 
    <tr> 
    <td>Features</td> 
    <td>Product 1 features</td> 
    <td>Product 2 features</td> 
    <td>Product 3 features</td> 
    </tr> 
    and so the list goes on... 
</table> 

Lo que yo quiero es que la fila de encabezado para estar siempre en la parte superior de la ventana activa, que es la fila superior cuando me desplazo hacia abajo, ya que mis filas van bastante lejos. Quiero mantener los nombres de los productos en las etiquetas siempre visibles para que el usuario pueda relacionar el contenido con los diferentes productos en la fila superior todo el tiempo.

¡Gracias de antemano!

+0

Posible duplicado: http://stackoverflow.com/q/983031/214773 –

+0

@ JúlioSantos: No, ** ** esta cuestión no menciona jQuery (o incluso JavaScript) en todo . –

+0

Oh, OK, punto tomado. Añadiré una respuesta. –

Respuesta

6

I técnica sencilla es tener la fila de cabecera en una separada table partir de los datos reales. Esta tabla de cabecera se fija para tener su posición como fixed, y luego la siguiente tabla, que contiene los resultados, tiene su margin-top establecer el height de la tabla de cabecera.

Esto crea el efecto de la cabecera permanecer donde está y la tabla de desplazamiento.

Un ejemplo básico aquí: http://jsfiddle.net/zKDR4/2/

También puede crear una cabecera fija con plugins jQuery. Eche un vistazo a este http://fixedheadertable.com/ realmente simple de implementar.

Editar

Como Anders ha mencionado, si vas por mi ruta sugerida, tendrá que ajustar los anchos de los elementos th y td. De lo contrario, no coincidirían, ya que son tablas separadas.

+1

Esto no funcionará bien si los anchos th y td difieren, lo que generalmente hacen. Si las celdas (incluidos los encabezados) tienen un tamaño fijo e igual, esto funciona muy bien, sin embargo. (+1 aún, la mejor solución, creo, y también una buena sugerencia de jquery) –

+0

@ AndersHolmström, sí, necesitas establecer los anchos de 'th' y' td' en este caso. La mejor solución que creo es que utiliza un plugin jquery que construye la tabla de encabezado de la tabla para que los anchos sean correctos. –

+0

Estoy completamente de acuerdo. :) –

-2

Usted puede hacer esto crea un div y fijar la posición. o también puede hacerse mediante la adición de CSS en línea

<table style="position:fixed;"> 
    <tr> 
    <th>Product:</th> 
    <th>Product 1</th> 
    <th>Product 2</th> 
     <th>Product 3</th> 
    </tr> 
    <tr> 
    <td>Features</td> 
    <td>Product 1 features</td> 
    <td>Product 2 features</td> 
    <td>Product 3 features</td> 
    </tr> 
    </table> 
+2

Esto no hace lo que la pregunta plantea. Simplemente arregla la tabla completa en un lugar de la página. – srk

-1

He creado un ejemplo usando jsFiddle, que se puede view as a demo.

El único inconveniente es que deberá especificar tamaños de columna, ya que cuando usa position: fixed pierde los anchos en el encabezado.

Este es el CSS para el ejemplo, el HTML es el mismo que el que ha suministrado.

thead { 
    height: 1em; 
} 

thead tr { 
    position: fixed; 
    background-color: #FFF; 
} 
0

que tenían el problema de la planificación con los encabezados de fila (horas) y títulos de las columnas (días). Quería mantener visibles los dos. La aplicación muestra el contenido en un iframe, por lo que he creado un DIV horizontal y vertical de un DIV fuera del marco flotante con un estilo "overflow: hidden". Luego he sincronizado las permutas con el evento "onscroll" del IFrame.

Aquí está mi código para sincronizar los encabezados con desplazamiento:

window.onscroll = function() { 

     try { 
      // - Scroll days header (on the top) horizontally 
      var offsetX = (document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft; // Source: http://stackoverflow.com/questions/2717252/document-body-scrolltop-is-always-0-in-ie-even-when-scrolling 
      var header1Div = window.parent.document.getElementById("EntetesColonnes"); 
      header1Div.scrollLeft = offsetX; 

      // - Scroll hours header (on the left) vertically 
      var offsetY = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop; // Source: http://stackoverflow.com/questions/2717252/document-body-scrolltop-is-always-0-in-ie-even-when-scrolling 
      var header2Div = window.parent.document.getElementById("HeaderHoursLeft"); 
      header2Div.scrollTop = offsetY; 
     } 
     catch (ex) { 
      alert("FrmPlanningChirurgien/window.onscroll: " + ex.message); 
     } 
    } 

Mi solución no es tan simple, porque tenía que poner en "onResize" el ancho de DIV horizontal y la altura del DIV vertical. Entonces esto induce una mayor complejidad, ya que onResize se puede disparar muchas veces por segundo, y este evento incluso se dispara en IE8 cuando se produce el desplazamiento. así que he hecho un setTimeout para evitar que las tuberías principales a ser redibujado con demasiada frecuencia:

var PREVIOUS_frameWidth = 0; 
var PREVIOUS_frameHeight = 0; 
var timerMakeHeaders = null; 

window.onresize = function() { 
    try { 

     var frameWidth = CROSS.getWindowWidth(); 
     var frameHeight = CROSS.getWindowHeight(); 

     if (frameWidth != PREVIOUS_frameWidth || frameHeight != PREVIOUS_frameHeight) { 

      // - *** Launch headers creation method 
      // - If there is another query to redraw, the Timer is stopped and recreated. 
      // - The headers are only redrawn when Timer fires. 
      if (timerMakeHeaders != null) { 
       window.clearTimeout(timerMakeHeaders); 
       timerMakeHeaders = null; 
      } 
      timerMakeHeaders = window.setTimeout(makeHeaders, 50); 

      // - *** Store new values 
      PREVIOUS_frameWidth = frameWidth; 
      PREVIOUS_frameHeight = frameHeight; 
     } 
    } catch (e) { alert("Erreur window.onresize/FrmPlanningChirurgien.aspx : " + e.message); } 
} 

Y, finalmente, el método makeHeaders() tener que cambiar el tamaño de DIVs:

function makeHeaders() { 

    // (...) 

    var frame = window.parent.document.getElementById("CalendarFrame"); 
    var iframeRect = frame.getBoundingClientRect(); 
    headerDiv.style.width = iframeRect.right - iframeRect.left - 20; // The 20 pixels are here for the vertical scrollbar width 
    headerDiv.scrollLeft = frame.scrollLeft; 

    // (...) 


    var headerHourDiv = window.parent.document.getElementById("HeaderHoursLeft"); 
    var newHeight = iframeRect.bottom - iframeRect.top - 20 - 7; // The VISIBLE width for the DIV must be equal to IFRAME Width minus the scroll width or height 
    headerHourDiv.style.height = newHeight; 
    headerHourDiv.scrollTop = frame.scrollTop;  


} 
catch (e) { 
    alert("makeHeaders: " + e.message); 
} } 

Tal vez podría ser posible no utilizar un IFRAME, y usar solo 3 DIVS: uno para cada encabezado y el último para el contenido. Pero el mecanismo tiene que ser el mismo, creo: necesita una sincronización entre las posiciones de desplazamiento.

Saludos,

Cuestiones relacionadas