2011-01-31 17 views
18

Bueno, como se menciona en el Firefox 4 changelog, ya no habrá soporte para el desplazamiento <tbody> 's.FireFox 4 ya no es compatible con TBody desplazable: ¿soluciones temporales?

Hay un montón de workarounds - javascript o 2 tablas separadas, pero ninguno de ellos resuelve todos los problemas. Javascript es obviamente más lento (con 600 filas puede olvidarse de intentar desplazar una tabla), y 2 tablas serán problemáticas con el ancho de la celda.

¿Sabes si hay alguna forma genial de hacer esto? Estamos utilizando JSF/facelets y ahora tenemos que volver a hacer las etiquetas, a partir de una buena idea sería impresionante :-)

+13

Noooo! ¡Todo navegador debería soportar esto! Es una gran característica. :( –

+1

Acabo de descubrir este problema, arruiné una página que anteriormente funcionaba, y estoy de acuerdo: ¡Noooooooooooo! –

+2

No puedo creer que no haya una manera simple de crear lo que es un elemento de interfaz tan obvio y extremadamente útil:/ – Jake

Respuesta

2

PrimeFaces y RichFaces tienen componentes DataTable desplazables, que va a buscar nuevas filas de ajax.

(ambas bibliotecas de componentes JSF utiliza jQuery bajo las sábanas de todos modos)

+0

Esto realmente me hace pensar que incluso estos proyectos tienen sus pequeños problemas con él. richfaces demo, toda la pantalla parpadea en blanco cuando se desplaza por el número de fila visible. No hay ni siquiera desplazamiento del mouse allí. La demostración de Primefaces no está alineada correctamente para m el inicio (encabezado y cuerpo). Sin cambio de tamaño – Toskan

+0

@Toskan: El host de demostración Richfaces es de hecho pobre. – BalusC

+0

La implementación de bajo nivel debe ser reparada, no la API. –

0

por qué no utilizar un div desplazable? Tal vez una de estas dos opciones:

<table> 
<row> 
    <cell> 
    <div of headers> 
    <div of content (scrollable)> 
    </cell> 
</row> 
</table> 

o más simple:

<div of headers> 
<div (scrollable)> 
<table of content, no headers> 
</div> 

No es bastante que sé pero bueno no soy Miguel :)

+0

y yo no funciona tan bien :-) – Toskan

4

Sé que está tratando de evitar js/implementaciones de tablas separadas, pero fue el único que pude encontrar que funcionó en varios navegadores. Pruebe http://www.tablefixedheader.com/. Es una solución jquery y funcionó, en mis pruebas limitadas, en IE6/IE8/FF3. (No ha probado FF4).

1

Prueba el primer método de esta página, CSS puro con una sola tabla (2 divs alrededor de la mesa, y la thead se positionned absoluto): tablescroll parece funcionar en FF4/IE9/IE8 además de IE7/FF3 .6.

+1

Agradable, pero tiene que especificar el ancho de las columnas :( – Joril

1

Acabo de golpeado con esto después de que actualicé. Abucheo.

Encontré esto en los tubos.

Este código está funcionando en FFX 4. No en IE8 ... podría ser modificado.

http://www.imaputz.com/cssStuff/bigFourVersion.html

+0

Experimenté un poco con esto y estoy retrocediendo de este. Se basa en saber el número de columnas Estoy trabajando con tablas donde el recuento de columnas es variable y prolongado. – Itumac

0

trabajé en un prototipo frameworkless quiero compartir con ustedes. Está funcionando en Firefox 4+, IE7-8 (no se han comprobado 6 o 9) Safari y Chrome.

El mayor problema no resuelto es qué hacer cuando los encabezados estáticos se quedan sin espacio para contraerse antes que las columnas de datos.

Para el proyecto real en el que estaba trabajando francamente me retiré del cuerpo de desplazamiento y fui con la paginación. pero estaba lidiando con más de 25 columnas con clasificación y potencialmente miles de filas.

De todos modos aquí es donde llegué antes de que lo abandonara. Por favor, publique sus adiciones si lo mejora: Espero que esto ayude.

Link to an example

<!DOCTYPE html> 
<html> 
    <head> 
     <title>Table with Fixed Header Prototype</title> 
     <script type="text/javascript"> 
     </script> 
     <style type="text/css"> 
      .tableContainer{ 
       background:#eee; 
       width:80%; 
      } 
      .scrollContainer{ 
       width:100%; 
       height:500px; /** The only thing required */ 
      } 
      .staticHeaderTable{ 
       -moz-box-shadow: 1px 4px 5px #cccccc; 
       -webkit-box-shadow:1px 4px 5px #cccccc; 
       box-shadow: 1px 4px 5px #cccccc; 
       position: relative; 
       z-index: 10; 
      } 
     /*****************************************************/ 
     /**** Generic styles outside of problem scope ****/ 

      table{border-collapse: collapse;font:normal 12px sans-serif;} 
      th,td{padding:2px; height:20px;border:1px solid #dddddd;} 
      th{background:#ffcc00;} 
     </style> 
    </head> 
<body> 
<script> 
function makeStaticTableHeaders(tableId){ 
// Overall Container : wraps everything 
    var tableContainer = document.createElement("div"); 
     tableContainer.className = "tableContainer"; 

// Scrolling Container : must have a height.(Set in CSSS in this sample) this contains the table without the head or foot 
    var scrollContainer = document.createElement("div"); 
     scrollContainer.className = "scrollContainer"; 
     scrollContainer.style.overflowY = "auto"; // just Y since IE7 doesn't add the scrollbar to the width. 
     scrollContainer.style.overflowX = "hidden"; // IE7 override. consider a CSS fix 
     scrollContainer.style.width = "100%"; 

// Identifies the actual table to wrap from the dom. exits if it can't be found 
    var dataTable = document.getElementById(tableId); 
    if(typeof(dataTable) == "undefined"){ 
     return false; 
    } 
    dataTable.style.width = "100%"; 

// Identify the header. If there is none, there is no point in this so exit. 
    var header = dataTable.getElementsByTagName("thead"); 
    if (header.length == 0){ 
     return false; 
    } 
    for (var i = 0; i < header.length; i++) 
    { 
     if(header[i].className.indexOf("static") != -1){ 
      header = header[i]; 
      break; 
     } 
     if(i == header.length - 1){ 
      header = header[i];// failsafe 
     } 
    } 
// If we are still here, we begin the process of altering the DOM elements 
    // 1. Insert the tableContainer in front of the dataTable 
    dataTable.parentNode.insertBefore(tableContainer, dataTable); 

    // 2. Insert the scrollContainer into the table container 
    tableContainer.appendChild(scrollContainer); 
    // 3. get the thead tr and create staticHeaderTable with the tr 
    var headerRow = header.getElementsByTagName("tr")[header.getElementsByTagName("tr").length - 1]; // gets last tr in case there is more than one 
    var staticHeaderTable = document.createElement("table"); 
     staticHeaderTable.className = "staticHeaderTable"; 
     staticHeaderTable.appendChild(header); 
     staticHeaderTable.style.width = "100%"; 

    // 4. Put the staticHeaderTable in the scrollContanier 
    tableContainer.insertBefore(staticHeaderTable, scrollContainer); 

    // 5. take the datatable out of the dom and put it in the scrollContainer 
    scrollContainer.appendChild(dataTable); 

    // 6. footer(optional) 
    var footer = dataTable.getElementsByTagName("tfoot"); 
    if (footer.length > 0){ 
     for (var i = 0; i < footer.length; i++) 
     { 
      if(footer[i].className.indexOf("static") != -1){ 
       footer = footer[i]; 
       break; 
      } 
      if(i == footer.length - 1){ 
       footer = footer[i];// failsafe 
      } 
     } 
     // TODO: footer assumes columns are not linked to the data columns.  
     var staticFooterTable = document.createElement("table"); 
      staticFooterTable.className = "staticFooterTable"; 
      staticFooterTable.appendChild(footer); 
      staticFooterTable.style.width = "100%"; 
      tableContainer.appendChild(staticFooterTable); 
    } 


    function tableResize(){ 
     var firsttableRow = dataTable.getElementsByTagName("tbody")[0].getElementsByTagName("tr")[0]; 
     var extra = headerRow.offsetWidth - firsttableRow.offsetWidth; 
     var headerCells = (headerRow.getElementsByTagName("td").length > 0)? headerRow.getElementsByTagName("td") : headerRow.getElementsByTagName("th"); 
     for(var i=0; i <headerCells.length;i++){ 
      headerCells[i].style.width = firsttableRow.getElementsByTagName("td")[i].offsetWidth + ((i==headerCells.length-1)? extra: 0) + "px"; 
     } 
    }; 
    if(window.addEventListener) {window.addEventListener("resize", tableResize, false);} 
    else{window.attachEvent("onresize", tableResize);} 
    tableResize(); 
} 

window.onload = function(){ 
    var staticTable = makeStaticTableHeaders("dataTable"); 
} 

</script> 
<h2>Datatable</h2> 

    <table id="dataTable" class="dataTable"> 
     <thead class="static"> 
      <tr> 
       <th>Header 1 A long One</th> 
       <th>Header 2</th> 
       <th>Header 3</th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
       <td>Cell Content 1 All the good Stuff is in here</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 

      </tr> 
      <tr> 
       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 

       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 

       <td>And Repeat 3</td> 
      </tr> 
      <tr> 
       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 
      </tr> 

      <tr> 
       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>Even More Cell Content 1</td> 

       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 
       <td>And Repeat 3</td> 

      </tr> 
      <tr> 
       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 
      </tr> 
      <tr> 

       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 

       <td>Even More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 
       <td>And Repeat 3</td> 
      </tr> 

      <tr> 
       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>More Cell Content 1</td> 

       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 

      </tr> 
      <tr> 
       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 
       <td>And Repeat 3</td> 
      </tr> 
      <tr> 

       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 

       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 
      </tr> 

      <tr> 
       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 
       <td>And Repeat 3</td> 
      </tr> 
      <tr> 
       <td>Cell Content 1</td> 

       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 

      </tr> 
      <tr> 
       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 
      </tr> 
      <tr> 

       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 
       <td>And Repeat 3</td> 
      </tr> 
      <tr> 
       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 

       <td>Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 

      <tr> 
       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>And Repeat 1</td> 

       <td>And Repeat 2</td> 
       <td>And Repeat 3</td> 
      </tr> 
      <tr> 
       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 

      </tr> 
      <tr> 
       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 

       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 

       <td>And Repeat 3</td> 
      </tr> 
      <tr> 
       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 
      </tr> 

      <tr> 
       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>Even More Cell Content 1</td> 

       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 
       <td>And Repeat 3</td> 

      </tr> 
      <tr> 
       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 
      </tr> 
      <tr> 

       <td>More Cell Content 1</td> 
       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 

       <td>Even More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>And Repeat 1</td> 
       <td>And Repeat 2</td> 
       <td>And Repeat 3</td> 
      </tr> 

      <tr> 
       <td>Cell Content 1</td> 
       <td>Cell Content 2</td> 
       <td>Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>More Cell Content 1</td> 

       <td>More Cell Content 2</td> 
       <td>More Cell Content 3</td> 
      </tr> 
      <tr> 
       <td>Even More Cell Content 1</td> 
       <td>Even More Cell Content 2</td> 
       <td>Even More Cell Content 3</td> 

      </tr> 
      <tr> 
       <td>End of Cell Content 1</td> 
       <td>End of Cell Content 2</td> 
       <td>End of Cell Content 3</td> 
      </tr> 
     </tbody> 
     <tfoot> 
      <tr> 
       <td colspan="3">Footer Is Here</td> 
      </tr> 
     </tfoot> 
    </table> 
</body> 
</html> 
2

Gracias a digitaldigs de MozillaZine, que era capaz de hacer que funcione con pocas modificaciones. La corrección funciona muy bien para FF4, FF7 y FF11.

Espero que esto ayude! :)

temas que he fija 1. scrollWidth no funcionó para mí, así que ir a offsetWidth

  1. Barra de desplazamiento ancho de 16 píxeles tampoco estaba ayudando por lo quitó. En su lugar hizo que mi estilo tbody as-

    .scrollContent { overflow-x: hidden; overflow-y: scroll;/* Hice esto solo por Mozilla. IE mostrará 2 barras de desplazamiento si se aplica */ pantalla: bloque; }

  2. Con el cambio n. ° 2, tuve que rellenar la última celda del encabezado para acomodar la barra de desplazamiento.

    /* Hice esto solo para Mozilla. No para IE */

    .fixedHeader tr th: last-child { relleno-derecho: 20px; }

  3. Mi tabla de cabecera fija tiene colspan usado mucho y por lo tanto no fue capaz de establecer el ancho, por lo que primero busco una fila correcta con el número correcto de celdas y luego proceso.

Mi código es similar a continuación:

function makeMeFixedHeader(){ 
    var tbodys = document.getElementsByName("scrollTableBody"); 
    if (tbodys){ 
     for(var i=0;i<tbodys.length;i++){ 
      // We can put logic here to check if the current height 
      // of tbody has crossed the specified limit or not 
      do_tbodyscroll(tbodys[i]); 
     } 
    } 
} 


function do_tbodyscroll(_tbody){ 
    // get the table node 
    var table = _tbody.parentNode; 

    // Get the Last row in Thead ... 
    // COLGROUPS USING COLSPAN NOT YET SUPPORTED 
    var thead = table.getElementsByTagName("THEAD")[0]; 
    var _rows = thead.getElementsByTagName("TR"); 
    var tableheader = _rows[_rows.length - 1]; 
    var headercells = tableheader.cells; 

    // rows of tbody 
    var _frows = _tbody.getElementsByTagName("TR"); 

    // first row of tbody 
    var _fr = _tbody.getElementsByTagName("TR")[0]; 
    //var _fr = _tbody.getElementsByName("scrollTableRow")[0]; 

    // first row cells .. 
    var _frcells = _fr.cells; 

    if (_frcells.length < headercells.length){ 
     var rowCount = 1; 
     while (rowCount < _frows.length){ 
      // nth row of tbody 
      _fr = _tbody.getElementsByTagName("TR")[rowCount]; 
      //var _fr = _tbody.getElementsByName("scrollTableRow")[rowCount]; 

      // nth row cells .. 
      _frcells = _fr.cells; 

      if (headercells.length == _frcells.length){ 
       break; 
      } 
      rowCount++; 
     } 
    } 

    // Apply width to header .. 
    for(var i=0; i<headercells.length; i++){  
     if (tableheader.cells[i].offsetWidth != _fr.cells[i].offsetWidth){ 
      var lastColumn = (i == headercells.length-1)?true:false; 
      var changeWidth = (lastColumn)? ((rowCount >= 1)?true:false) 
        :true; 
      var headerW = tableheader.cells[i].offsetWidth; 
      var cellW = _fr.cells[i].offsetWidth; 

      if (headerW < cellW){ 
       tableheader.cells[i].width = cellW; 
       _fr.cells[i].width = tableheader.cells[i].width; 

       if (lastColumn) 
        tableheader.cells[i].width = tableheader.cells[i].offsetWidth-20; 

      }else{ 
       tableheader.cells[i].width = headerW; 
       _fr.cells[i].width = tableheader.cells[i].width; 

       if (lastColumn) 
        _fr.cells[i].width = tableheader.cells[i].offsetWidth-20; 
      } 
     } 
    } 

    //var j = headercells.length-1; 
    // ADD 16 Pixel of scroll bar to last column .. 
    //tableheader.cells[j].width = _fr.cells[j].offsetWidth + 20; 

    tableheader.style.display = "block"; 
    _tbody.style.display = "block"; 
} 
+0

si proporciona un violín, podría examinarlo. Creo que utilicé un enfoque similar. – Toskan

Cuestiones relacionadas