it-swarm.com.de

Machen Sie TBODY in Webkit-Browsern scrollbar

Ich kenne diese Frage , aber keine der Antworten funktionieren in Safari, Chrome usw.

Die akzeptierte Strategie ( wie hier gezeigt ) besteht darin, Körpergröße und Überlaufeigenschaften wie folgt festzulegen:

<table>
    <thead>
        <tr><th>This is the header and doesn't scroll</th></tr>
    </thead>
    <tbody style="height:100px; overflow:auto;">
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
    </tbody>
</table>

Leider funktioniert dies in keinem Webkit-Browser. Es gibt einen Fehlerbericht darüber, der keine hohe Priorität zu haben scheint (Juni 05).

Meine Frage ist also: Gibt es alternative Strategien, die tatsächlich funktionieren? Ich habe den Zwei-Tabellen-Ansatz ausprobiert, aber es kann nicht garantiert werden, dass der Header mit dem Inhalt übereinstimmt. Muss ich nur warten, bis Webkit das Problem behoben hat?

68
Andrew Ensley

Hier ist ein Arbeitsbeispiel:

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

Sie müssen den display: block dem thead> tr und tbody hinzufügen

32
Michael Koper

Die Verwendung der Anzeige: Blockstil funktioniert nur, wenn Sie 1 Spalte haben. Wenn Sie mehrere Datenspalten - mit mehreren Feldern - haben, erscheint display: Block, um alle Datenspalten scrollbar zu machen, aber unter der 1. Spalte (tut dies in Firefox - dies ist der einzige Browser, den ich kenne, der das Scrollen schön macht). Übrigens, unter Firefox - Sie können den Stil overflow-x: hidden verwenden, um den horizontalen Bildlauf zu unterdrücken.

Ich habe erkannt, dass das Problem, das ich erwähne, nur auftritt, wenn Sie keine Breite für die th & td-Elemente angeben. Wenn Sie die Spaltenbreiten festlegen können, funktioniert es. Problem für mich ist, dass ich die Spaltenbreiten nicht festlegen kann.

17
Martin

Versuchen Sie die erste Methode dieser Seite, reines CSS mit einer einzigen Tabelle (2 Divs um die Tabelle herum, und der Punkt ist absolut positioniert): http://www.cssplay.co.uk/menu/tablescroll.html Scheint auf FF4/IE9/IE8 zusätzlich zu IE7/FF3.6 zu funktionieren.

12
lsf

Ich sah Sean Haddys ausgezeichnete Lösung und erlaubte mir einige Änderungen vorzunehmen :

  • Verwenden Sie Klassen statt ID, sodass ein jQuery-Skript für mehrere Tabellen auf einer Seite wiederverwendet werden kann
  • Unterstützung für semantische HTML-Tabellenelemente wie caption, thead, tfoot und tbody wurde hinzugefügt
  • Bildlaufleiste optional, sodass sie nicht für Tabellen angezeigt wird, die "kürzer" sind als die Bildlaufhöhe
  • Angepasste Breite der Bildlaufleiste, um die Bildlaufleiste an den rechten Rand der Tabelle zu bringen
  • Konzept wurde durch .__ zugänglich gemacht.
    • using aria-hidden = "true" für den statischen Tabellenkopf der injizierten Daten
    • und lasse das Original an Ort und Stelle, einfach mit jQuery versteckt und aria-hidden="false" gesetzt
  • Beispiele für mehrere Tabellen mit unterschiedlichen Größen gezeigt

Sean hat das schwere Heben jedoch gemacht. Danke auch an Matt Burland für den Hinweis, dass er tfoot unterstützen muss.

Bitte sehen Sie selbst unter http://jsfiddle.net/jhfrench/eNP2N/

5
Jeromy French

Ich hatte das gleiche Problem und schrieb ein jQuery-Skript, um dies für mich zu tun ... verwendet zwei Tabellenelemente und formatiert die CSS entsprechend. Hoffe, das hilft anderen, die das gleiche Problem haben ...

http://jsfiddle.net/pe295/1/

5
Sean Haddy

A hatte vor langer Zeit das gleiche Problem und ich stellte schließlich den Ansatz für zwei Tische vor. Dies ist das Ergebnis: http://jsfiddle.net/bGr4V/3/ , es funktioniert für alle Browser (IE6 + incl).

In this jsFiddle können Sie mit einer sauberen Version spielen.

Meine Lösung war, ein fixe Zelle<th class="fix"> </th> in thead hinzuzufügen, um den Bereich der Bildlaufleiste in der tbody zu füllen, und dann einer Spalte eine variable Breite (<td class="grow">) zu geben, so dass der Header fixe Zelle würde bei der Größenänderung nicht anders sein.

HTML:

<div class="fixed_table">
  <div class="head">
    <table>
      <thead>
        <tr>
          <th>Column header</th>
          <th class="grow">Column header</th>
          <th class="fix"> </th>
        </tr>
      </thead>
    </table>
  <div class="body">
    <table class="full_table">
      <caption class="caption">Caption</caption>
      <tbody>
        <tr>
          <td>Data</td>
          <td class="grow">Data</td>
        </tr>
        <tr>
          <td>...</td>
          <td>...</td>
        </tr>
        <tr>
          <td>...</td>
          <td>...</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

CSS: hat * und _ hack für ie6-7 und einen -webkit, der für den Header fix-cell spezifisch ist und jeweils die Bildlaufbreite angibt.

.fixed_table table {
  table-layout: fixed;
  width: auto;
  border-width: 0;
  padding: 0;
  border-collapse: collapse;
}

.fixed_table .body {
  overflow: scroll;
  overflow-x: hidden;
  max-height: 10.75em;
  min-height: 2.5em;
  padding-bottom: 0.8em;
  *padding-right: 17px; /*ie7 & ie6*/
  _padding-right: 0; /*ie6*/
  _height: 10em ;
}

.fixed_table th, .fixed_table td {
  width: 4.7em;
}

.fixed_table .grow {
  width: auto;
}

.fixed_table .fix {
  width: 16px;
  *width: 17px; /*ie7 & ie6*/
  _width: 16px; /*ie6*/
}

/* webkit specific */
@media screen and (-webkit-min-device-pixel-ratio:0) {
  .fixed_table .fix{ width: 17px }
}
3
I.G. Pascual

Ich dachte, ich würde meine Lösung in den Mix werfen - http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/ .

Es ist dieselbe grundlegende Route wie bei der Lösung von @Michael Koper, enthält jedoch eine Problemumgehung, sodass die Tabelle in IE wieder korrekt zu IE6 aussehen wird.

Ich löse das Breitenproblem, indem ich dem <table> einen table-layout: fixed gebe und den Zellen in jeder Spalte explizit die Breite zuweise. Nicht ideal, aber es erzeugt eine semantische Tabelle, die den Browser unabhängig davon ausrichtet, ob eine Bildlaufleiste erforderlich ist.

Demo: http://codepen.io/tjvantoll/pen/JEKIu

2
TJ VanToll

Für diese Frage mag es übertrieben sein, aber YUI bietet immer noch die beste kostenlose browserübergreifende Datentabelle. Es kann auch für schreibgeschützte Daten verwendet werden.

YUI 2 Datentabelle

YUI 3 Datentabelle

Klicken Sie auf die Beispiele, um scrollbare Beispiele anzuzeigen. Da ich ein Stackoverflow-Neuling bin, kann ich nur diese beiden Links posten.

1
user2030366

Das ist wirklich ziemlich hackig, aber vielleicht wird jemand irgendwo helfen ...

http://jsfiddle.net/yUHCq/1/

Es werden Spalten anstelle von Zeilen verwendet, sodass die Verarbeitung im Wesentlichen rückwärts erfolgt.

Übergangs-DOCTYPE für Kompatibilität mit IE hinzugefügt.

1
Matthew

Ich habe eine Javascript-Lösung für das obige Problem entwickelt 
das funktioniert nur in Firefox 7+, da ich nur in FF getestet habe 

Ich kam zu diesem Thread und fand eine Lösung, auf die gezeigt wurde Michael Koper

Bei dieser Lösung werden drei wichtige Dinge getan 
1) Spaltenbreite einstellen 
2) Die Anzeige adead> tr ist auf Block gesetzt
3) Die Körperanzeige ist auf Block gesetzt 

da andere dort Probleme mit der Fixierung der Breite erwähnt haben, bin ich auch in derselben Position; 
selbst ich kann die Breite nicht statisch festlegen 

also dachte ich, ich werde die Breite dynamisch korrigieren (nachdem die Tabelle im Browser gerendert wird)

folgendes ist die Lösung in Javascript, die nur in FF funktioniert
(ich habe nur in FF getestet, ich habe keinen Zugriff auf andere Browser) 

       function test1(){                
            var tbodys = document.getElementsByTagName("TBODY");
            for(var i=0;i<tbodys.length;i++){
                do_tbodyscroll(tbodys[i]);
            }
        }


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

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

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

            // Width array , width of each element is stored in this array 
            var widtharray = new Array(_frcells.length);

            for(var i=0;i<_frcells.length;i++){                    
                widtharray[i] = _frcells[i].scrollWidth;
            }                

            // Apply width to first row                  
            for(var i=0;i<_frcells.length;i++){
                _frcells[i].width = widtharray[i];                   
            }                 

            // 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;

            // Apply width to header ..                                
            for(var i=0;i<headercells.length;i++){
                headercells[i].width = widtharray[i];
            }

            // ADD 16 Pixel of scroll bar to last column ..
            headercells[headercells.length -1 ].width = widtharray[headercells.length -1] + 16;

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

Diese Lösung ermittelt die Breite der Spalten im Browser 
und setzen Sie die Spaltenbreite (Kopfzeile und erste Reihe) erneut auf die gleiche Breite. 
nachdem die Breite eingestellt ist; Die Kopf- und Körperanzeige ist auf Block gesetzt 

Hoffen Sie, dass diese Lösung für Sie alle nützlich ist. 
Wenn Sie es auf andere Browser erweitern können, antworten Sie bitte auf diesen Beitrag 

1

Lassen Sie die Tabelle zeichnen, berechnen Sie die Spaltenbreite und setzen Sie sie in jede Überschrift. Überschriften werden mit Unterteilungen erstellt, und dann können wir die Tabelle frei scrollen lassen.

<!DOCTYPE html>
<html>
<head>
<style>
.t_heading{
  margin-top: 20px;
  font-family: Verdana, Geneva, sans-serif;
  background-color: #4CAF50;
}

.heading{
  background-color: #4CAF50;
  color: white;
  float:left;
  padding: 8px 0PX 8PX 0PX;
  border-bottom: 1px solid #ddd;
  height: 20px;
  text-align: left;
}

.t_data{
  overflow-y: scroll;
  overflow-x: hidden;
  height:0px;
  width: 100%;

}

.t_content{
    border-collapse: collapse;
    font-family: Verdana, Geneva, sans-serif;
    width: 100%;
}

.column1,.column2,.column3,.column4{
    padding: 8px 0PX 8PX 0PX;
    text-align: left;
    border-bottom: 1px solid #ddd;
}
.t_row:hover{
  background-color:#f5f5f5;
}
</style>
<script>
function setBody(){
    var body = document.body,
    html = document.documentElement;

    var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
    height = height-300;
    /*
     ** By changing the subtraction value, You can fit the table in to the screen correctly.
     ** Make sure not to come the hscroll.
     ** Or you can set fixed height with css for the div as your wish.
     */
    document.getElementById("t_data").style.height = height+"px";

    setColumnWidth("column1");
    setColumnWidth("column2");
    setColumnWidth("column3");
    setColumnWidth("column4");
}

function setColumnWidth(o){
        var object = o;
        var x = document.getElementsByClassName(object);
        var y = x[0].clientWidth;
        document.getElementById(object).style.width = y+"px";
 }
</script>
</head>

<body onload="setBody()">
<div class="t_heading">
<div class="heading"  id="column1">Heading 1</div>
<div class="heading"  id="column2">Heading 2</div>
<div class="heading"  id="column3">Heading 3</div>
<div class="heading"  id="column4">Heading 4</div>
</div>
<div class="t_data" id="t_data">
<table class="t_content">
    <tr class='t_row'>
        <td class='column1'>Column1 Row 0</td>
        <td class='column2'>Column2 Row 0</td>
        <td class='column3'>Column3 Row 0</td>
        <td class='column4'>Column4 Row 0</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 1</td>
        <td class='column2'>Column2 Row 1</td>
        <td class='column3'>Column3 Row 1</td>
        <td class='column4'>Column4 Row 1</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 2</td>
        <td class='column2'>Column2 Row 2</td>
        <td class='column3'>Column3 Row 2</td>
        <td class='column4'>Column4 Row 2</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 3</td>
        <td class='column2'>Column2 Row 3</td>
        <td class='column3'>Column3 Row 3</td>
        <td class='column4'>Column4 Row 3</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 4</td>
        <td class='column2'>Column2 Row 4</td>
        <td class='column3'>Column3 Row 4</td>
        <td class='column4'>Column4 Row 4</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 5</td>
        <td class='column2'>Column2 Row 5</td>
        <td class='column3'>Column3 Row 5</td>
        <td class='column4'>Column4 Row 5</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 6</td>
        <td class='column2'>Column2 Row 6</td>
        <td class='column3'>Column3 Row 6</td>
        <td class='column4'>Column4 Row 6</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 7</td>
        <td class='column2'>Column2 Row 7</td>
        <td class='column3'>Column3 Row 7</td>
        <td class='column4'>Column4 Row 7</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 8</td>
        <td class='column2'>Column2 Row 8</td>
        <td class='column3'>Column3 Row 8</td>
        <td class='column4'>Column4 Row 8</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 9</td>
        <td class='column2'>Column2 Row 9</td>
        <td class='column3'>Column3 Row 9</td>
        <td class='column4'>Column4 Row 9</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 10</td>
        <td class='column2'>Column2 Row 10</td>
        <td class='column3'>Column3 Row 10</td>
        <td class='column4'>Column4 Row 10</td>
    </tr>
<!--
<?php
$data = array();
for($a = 0; $a<50; $a++)
{
    $data[$a] = array();
    $data[$a][0] = "Column1 Row ".$a;
    $data[$a][1] = "Column2 Row ".$a;
    $data[$a][2] = "Column3 Row ".$a;
    $data[$a][3] = "Column4 Row ".$a;
}
/*
 ** supose you have data in an array.. which red from database. The table will draw using array data. Or you can draw the table manualy.
 ** tip: If using manual table, No need of
 ** 'var x = document.getElementsByClassName(object); var y = x[0].clientWidth;'.
 ** You can just set ID of first row's cells in to some name and use it to read width.
 */
for($i=0;$i<sizeof($data);$i++){
    echo "<tr class='t_row'><td class='column1'>".$data[$i][0]."</td><td class='column2'>".$data[$i][1]."</td><td class='column3'>".$data[$i][2]."</td><td class='column4'>".$data[$i][3]."</td></tr>";
}
?>
-->
</table>
</div>
</body>
</html>
0
Salitha Prasad

Hinzufügen display:block; Dadurch wird auch die unnötige horizontale Bildlaufleiste in FireFox entfernt. Sie wissen sicherlich auch, dass keines der Beispiele in MSIE 8 funktioniert.

<table>
    <thead>
        <tr><th>This is the header and doesn't scroll</th></tr>
    </thead>
    <tbody style="height:100px; overflow:auto;display:block;">
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
    </tbody>
</table>
0
mmcglynn

Wenn jemand es braucht, um im IE -Markierungsmodus zu arbeiten, habe ich hier I.G. geändert und vereinfacht. Pascuals Code zur Arbeit:

.fixed_table{
       overflow: scroll;
       overflow-x: hidden;
       max-height: 300px;
       height: 300px;
       min-height: 50px;
       padding-right:0;
}
#datatable td 
{
       padding:3px;
       text-align: center;
       width: 9%;
       vertical-align: middle;
       background-color: #343435; 
       color: #E0E0E3;
       overflow:hidden;
} 
<div class="head">
    <table>
        <thead>
            <tr>
                <th>Time (GMT)</th>
                <th>Price</th>
            </tr>
        </thead>
    </table>
</div>
<div class="fixed_table">
    <table id="datatable" cellspacing="1" cellpadding="1">
        <tbody></tbody>
    </table>
</div>
0
Ronen Festinger

Es gibt hier ein Beispiel, das in IE5 +, Firefox und Chrome funktioniert. Es werden jedoch Spalten mit fester Breite verwendet . http://www.cssplay.co.uk/menu/tablescroll.html

0
user1491819