簡體   English   中英

帶有固定(凍結)列和標題的HTML表

[英]HTML table with fixed (frozen) columns and headers

我一直在網上搜索制作帶有固定(凍結)列和標題的表的方法。 好像我終於找到了解決方案並根據我的需要進行了修改。

有原來的小提琴是在這里

是我修改過的解決方案。 我在Chrome(版本:55.0.2883.87 m)和Firefox(版本:51.0.1)中測試了它。

問題是它在IE中不完全有效(版本:11.0.9600.18427)。 在水平滾動期間,標題的凍結部分也會滾動。 有人可以幫助我讓它在IE中工作嗎? 還有一個問題:這種方法可以安全使用嗎? 我的意思是如果它使用一些未指定的行為,那么一些未來的瀏覽器甚至一些現代瀏覽器可能以錯誤的方式顯示我的表,並且最好使用具有幾個不同表的安全解決方案並同步滾動位置和行高度。 UPD:還有一個問題:如何在移動設備上保持穩定?

以下是一些演示該方法的代碼:

 $(document).ready(function() { $('tbody').scroll(function(e) { //detect a scroll event on the tbody /* Setting the thead left value to the negative valule of tbody.scrollLeft will make it track the movement of the tbody element. Setting an elements left value to that of the tbody.scrollLeft left makes it maintain it's relative position at the left of the table. */ $('thead').css("left", -$("tbody").scrollLeft()); //fix the thead relative to the body scrolling $('thead th:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first cell of the header $('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first column of tdbody }); }); 
 .container { height:200px; width:400px; overflow: hidden; } table { position: relative; background-color: #aaa; border-collapse: collapse; table-layout: fixed; display: flex; flex-direction: column; height: 100%; width: 100%; } /*thead*/ thead { position: relative; display: block; /*seperates the header from the body allowing it to be positioned*/ } thead th { background-color: #99a; min-width: 120px; border: 1px solid #222; } thead th:nth-child(1) {/*first cell in the header*/ position: relative; background-color: #88b; } /*tbody*/ tbody { flex: 1; position: relative; display: block; /*seperates the tbody from the header*/ overflow: auto; } tbody td { background-color: #bbc; min-width: 120px; border: 1px solid #222; } tbody tr td:nth-child(1) { /*the first cell in each tr*/ position: relative; background-color: #99a; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> <div class="container"> <table> <thead> <tr> <th>Name<br/>123</th> <th>Town</th> <th>County</th> <th>Age</th> <th>Profession</th> <th>Anual Income</th> <th>Matital Status</th> <th>Children</th> </tr> <tr> <th>Name</th> <th>Town</th> <th>County</th> <th>Age<br/>123<br/>321</th> <th>Profession</th> <th>Anual Income</th> <th>Matital Status</th> <th>Children</th> </tr> </thead> <tbody> <tr> <td>John Smith</td> <td>Macelsfield</td> <td>Cheshire<br/>123</td> <td>52</td> <td>Brewer</td> <td>£47,000</td> <td>Married</td> <td>2</td> </tr> <tr> <td>Jenny Jones<br/>123<br/>312</td> <td>Threlkeld</td> <td>Cumbria</td> <td>34</td> <td>Shepherdess</td> <td>£28,000</td> <td>Single</td> <td>0</td> </tr> <tr> <td>Peter Frampton</td> <td>Avebury</td> <td>Wiltshire</td> <td>57</td> <td>Musician</td> <td>£124,000</td> <td>Married</td> <td>4</td> </tr> <tr> <td>Simon King</td> <td>Malvern</td> <td>Worchestershire</td> <td>48</td> <td>Naturalist</td> <td>£65,000</td> <td>Married</td> <td>2</td> </tr> <tr> <td>Lucy Diamond</td> <td>St Albans</td> <td>Hertfordshire</td> <td>67</td> <td>Pharmasist</td> <td>Retired</td> <td>Married</td> <td>3</td> </tr> <tr> <td>Austin Stevenson</td> <td>Edinburgh</td> <td>Lothian </td> <td>36</td> <td>Vigilante</td> <td>£86,000</td> <td>Single</td> <td>Unknown</td> </tr> <tr> <td>Wilma Rubble</td> <td>Bedford</td> <td>Bedfordshire</td> <td>43</td> <td>Housewife</td> <td>N/A</td> <td>Married</td> <td>1</td> </tr> <tr> <td>Kat Dibble</td> <td>Manhattan</td> <td>New York</td> <td>55</td> <td>Policewoman</td> <td>$36,000</td> <td>Single</td> <td>1</td> </tr> <tr> <td>Henry Bolingbroke</td> <td>Bolingbroke</td> <td>Lincolnshire</td> <td>45</td> <td>Landowner</td> <td>Lots</td> <td>Married</td> <td>6</td> </tr> <tr> <td>Alan Brisingamen</td> <td>Alderley</td> <td>Cheshire</td> <td>352</td> <td>Arcanist</td> <td>A pile of gems</td> <td>Single</td> <td>0</td> </tr> </tbody> </table> </div> </body> 

這非常奇特。 似乎有問題的代碼是這一行:

$('thead').css("left", -$("tbody").scrollLeft()); //fix the thead relative to the body scrolling

看起來IE11處理嵌套元素的相對位置(與Chrome和其他瀏覽器不同)。 在這種情況下,您將使用偏移相對定位來定位thead 您也定位thead th (它的兒童)的偏移和相對定位。 鉻似乎定位thead相對於table ,然后定位th相對於thead IE11,在另一方面,似乎被定位thead相對於table ,然后th剛剛繼承了相同的定位,無論其自身的定位。

對此的修復如下:在IE11上,為thead處理不同的定位。 而不是設置在父的定位thead ,設置在所述定位thead th元素。 這樣一來,你的第一個欄就不會被“逼”繼承thead的定位(在IE)。

$(document).ready(function() {
  var isIE11 = !!navigator.userAgent.match(/Trident.*rv\:11\./);
  var customScroller;
  if (isIE11)
    customScroller = function() {
      $('thead th').css("left", -$("tbody").scrollLeft()); //if using IE11, fix the th element 
    };
  else
    customScroller = function() {
      $('thead').css("left", -$("tbody").scrollLeft()); //if not using IE11, fix the thead element
    };

  $('tbody').scroll(function(e) { //detect a scroll event on the tbody
    /*
    Setting the thead left value to the negative valule of tbody.scrollLeft will make it track the movement
    of the tbody element. Setting an elements left value to that of the tbody.scrollLeft left makes it maintain             it's relative position at the left of the table.    
    */
    customScroller(); //fix the thead relative to the body scrolling
    $('thead th:nth-child(1)').css("left", $("tbody").scrollLeft());
//fix the first cell of the header
    $('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first column of tdbody
  });
});

以下是您的代碼的完整示例,顯示基於瀏覽器的不同處理:

https://jsfiddle.net/8tx4xfhx/5/

Alsol,很高興看到之前是否有人注意過這種行為。 看來IE11處理嵌套相對定位的方式與其他瀏覽器不同。 是否有某個規范定義了標准應該是什么? 應該像IE一樣繼承相對定位嗎? 或者相對定位是否總是相對於父母? 我會想到后者。 但是還必須考慮性能因素。

您應該參考jquery.floatThead.js嘗試下面的代碼示例。

                    var $demoTable = $("div.table-responsive table");
                    $demoTable.floatThead({
                        top: 200,
                        scrollContainer: function ($table) {                                
                            return $table.closest('.table-responsive');
                        },
                        position: 'absolute'
                    });

你需要獲取jquery.floatThead.js文件的引用並嘗試在表上應用它。

您可以通過以下鏈接查看此信息。 http://mkoryak.github.io/floatThead/

通常對於凍結的行和列,我總是更喜歡使用僅限css的解決方案以獲得最佳的瀏覽器兼容性。

我試圖用css-only解決方案在這里復制你的代碼。

我正在使用mac,因此無法訪問IE。 請驗證它是否正常工作。

更新小提琴: https//jsfiddle.net/nashcheez/bzuasLcz/81/

參考代碼:

 table { position: relative; width: 700px; background-color: #aaa; overflow: hidden; border-collapse: collapse; } /*thead*/ thead { position: relative; display: block; /*seperates the header from the body allowing it to be positioned*/ width: 700px; overflow: visible; } thead th { background-color: #99a; min-width: 120px; height: 36px; min-height: 36px; border: 1px solid #222; } thead th:nth-child(1) { /*first cell in the header*/ position: relative; display: block; background-color: #88b; } tbody tr td:nth-child(2) { margin-left: 124px; display: block; } /*tbody*/ tbody { display: block; width: 700px; height: 239px; overflow-y: auto; } tbody td { background-color: #bbc; min-width: 120px; border: 1px solid #222; height: 36px; min-height: 36px; } tbody tr td:nth-child(1) { /*the first cell in each tr*/ position: absolute; display: inline-block; background-color: #99a; } 
 <body> <table> <thead> <tr> <th>Name</th> <th>Town</th> <th>County</th> <th>Age</th> <th>Profession</th> <th>Anual Income</th> <th>Matital Status</th> <th>Children</th> </tr> </thead> <tbody> <tr> <td>John Smith</td> <td>Macelsfield</td> <td>Cheshire</td> <td>52</td> <td>Brewer</td> <td>£47,000</td> <td>Married</td> <td>2</td> </tr> <tr> <td>Jenny Jones</td> <td>Threlkeld</td> <td>Cumbria</td> <td>34</td> <td>Shepherdess</td> <td>£28,000</td> <td>Single</td> <td>0</td> </tr> <tr> <td>Peter Frampton</td> <td>Avebury</td> <td>Wiltshire</td> <td>57</td> <td>Musician</td> <td>£124,000</td> <td>Married</td> <td>4</td> </tr> <tr> <td>Simon King</td> <td>Malvern</td> <td>Worchestershire</td> <td>48</td> <td>Naturalist</td> <td>£65,000</td> <td>Married</td> <td>2</td> </tr> <tr> <td>Lucy Diamond</td> <td>St Albans</td> <td>Hertfordshire</td> <td>67</td> <td>Pharmasist</td> <td>Retired</td> <td>Married</td> <td>3</td> </tr> <tr> <td>Austin Stevenson</td> <td>Edinburgh</td> <td>Lothian</td> <td>36</td> <td>Vigilante</td> <td>£86,000</td> <td>Single</td> <td>Unknown</td> </tr> <tr> <td>Wilma Rubble</td> <td>Bedford</td> <td>Bedfordshire</td> <td>43</td> <td>Housewife</td> <td>N/A</td> <td>Married</td> <td>1</td> </tr> <tr> <td>Kat Dibble</td> <td>Manhattan</td> <td>New York</td> <td>55</td> <td>Policewoman</td> <td>$36,000</td> <td>Single</td> <td>1</td> </tr> <tr> <td>Henry Bolingbroke</td> <td>Bolingbroke</td> <td>Lincolnshire</td> <td>45</td> <td>Landowner</td> <td>Lots</td> <td>Married</td> <td>6</td> </tr> <tr> <td>Alan Brisingamen</td> <td>Alderley</td> <td>Cheshire</td> <td>352</td> <td>Arcanist</td> <td>A pile of gems</td> <td>Single</td> <td>0</td> </tr> </tbody> </table> </body> 

問題是IE不允許人們獨立於行整體調整行中單元格的left屬性。 我們可以通過使用IE中的開發人員窗口和Chrome中的開發人員窗口直接編輯DOM來看到這一點。

在Chrome中,當您向左和向右滾動時,您可以在元素查看器中看到元素本身的left屬性已更改,這將覆蓋所有CSS。 我們可以重新加載頁面並在同一屏幕中手動設置元素屬性: style:'left:300px' ,我們將看到標題單元格向右移動300px並將鼠標懸停在剩余的標題單元格上。 這是良好的行為和使該方法有效的行為。

如果我們在IE中做同樣的事情並添加style: 'left:300px'到第th個元素,我們將看到單元格不移動。 我們對該單元格的樣式屬性所做的任何操作都不會導致它在表格中留下它的位置。 IE的這個“功能”導致該方法失敗。 無論將哪些屬性應用於行內的元素,IE都堅持維護單元格順序。

訣竅是以一種讓所有瀏覽器都滿意的方式解決這個復雜問題。 有很多方法可以做到這一點,但我可能會使用兩個表,並使用DIV來定位它們以使邊匹配。 我會添加javascript,以便如果一個tbody向上或向下滾動它會以相同的方式影響另一個tbody。 如果它向右或向左滾動,第一個表沒有任何反應,它保存您的凍結列標題,右表按計划在滾動方向上移動。

通過使用兩個表,IE不再將您嘗試凍結的標頭與正在移動的標頭相關聯。 小心的CSS將偽裝你的黑客並使表格顯示為一個表格。

祝你好運,編碼愉快!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM