2014-09-24 98 views
0

我在使用JavaScript處理HTML表格時遇到了縮放問題。如何在JavaScript中明確設置HTML表格列寬度

我有一個JavaScript代碼blob,從JSON數組動態創建一個表。 它修復了標題並允許表體滾動,並且它工作正常。

標題是一個單獨的表格,我強烈控制單元格寬度以確保標題表格的單元格與主體表格單元格匹配。

主體表單元格都顯式設置其寬度。
我迭代表中的行,然後將該循環內的單元格交織,並設置每個單元格的寬度。

此迭代不縮放,因爲行數增加到100,列數增加到40個,我聽到Firefox抱怨腳本掛起或沒有響應。它沒有響應,因爲它忙於設置所有單元寬度。

nz.dynatable.setTableColumnWidths = function (table, arrayColumnWidths) { 
    // Iterate the table and set width settings for each cell 
    for (var i = 0; i < table.rows.length; ++i) { 
     for (var j = 0; j < table.rows[i].cells.length; ++j) { 
      var width = arrayColumnWidths[j] || 0; 
      table.rows[i].cells[j].style.width = width.toString() + "px"; 
     } 
    } 
} 

問:是否可以爲一行中的表設置單元格寬度,並讓表中的所有其他單元格與此一致? Firefox是否因爲更改單元格寬度而導致重新計算每個循環中的表大小?

完整的代碼塊是在公共GitHub庫:https://github.com/Hiblet/DynaTable

+2

你嘗試只做第一排?這是普通的表格行爲。 – isherwood 2014-09-24 17:21:30

+0

是的,這是舊學校的伎倆,只是在第一行設置你的寬度 - 並祈禱沒有涉及到的集體:P 任何人都使用colgroup了? – wwwmarty 2014-09-24 18:06:22

+0

沒有集體,這一切都在我的控制之下。會給第一行一個去,如果這樣做會大大加快這一部分。將明天嘗試,謝謝你的回覆。 – 2014-09-24 22:52:21

回答

0

試試這個:我有同樣的問題,這是幫助我:

let tables = document.getElementsByClassName("table"); 

if(tables.length == 2){ 
    let firstTableCol = tables[0].querySelectorAll('colgroup col'); 
    let secondTableCol = tables[1].querySelectorAll('tr')[0].querySelectorAll('td'); 
    if(firstTableCol.length == secondTableCol.length){ 
     for(let index = 0; index < firstTableCol.length; index++){ 
      firstTableCol[index].style.width = secondTableCol[index].offsetWidth + "px"; 
     } 
    }else 
     console.log('cols count mismatch'); 
}else 
    console.log('count of tables are bigger than 2'); 
+0

我通過緩存當前列寬度並將它們滾動到重建表格來解決此問題。我想我會重寫我的內部表更新代碼來更新數據,而不是表格和數據,因爲構建HTML似乎是問題所在。 – 2017-08-10 15:19:16

0

我嘗試了一些方法對皮膚這隻貓這裏是我的發現。最終的解決方案最終變得非常乾淨和高效,我在Chrome上測試的警告,而不是其他瀏覽器,以及適度大,但不是巨大的表。總之,使用CSS如以下設置5列寬70,並使用JavaScript來修改CSS:

table#my_table th:nth-child(5), table#my_table td:nth-child(5){ max-width:70px; min-width:70px;} 

更多細節:

  • 您需要同時設置MIN-寬度和最大寬度,以避免列你不會嘗試調整時髦的東西,以保持表大小恆定

  • 你可以做到這一點使用element.style.xxxWidth,但一個簡單的方法,如在就像OP所指出的那樣,OP不能很好地擴展。

    • 解決此問題的一種方法是僅更新可視區域中的元素(我們稱之爲「可視區域方法」)。您可以通過比較父對象和您正在檢查的對象的parent.getBoundingClientRect()結果(請參閱,例如How to tell if a DOM element is visible in the current viewport?
    • 我可以做到這一點,只要調用getBoundingClientRect()()這是昂貴的)保持在最低限度(即每個柱子一次,而不是每個單元)。因爲我不想在更新可查看單元格後維護更新單元格和不更新單元格的緩存,我會使用異步函數調用更新不可查看單元格。這樣,UI顯得更爲敏感,即使它仍然在做的東西在後臺
  • 然而,任何涉及到element.style.xxxWidth直接的變化感到凌亂,尤其是具有添加代碼只更新後可視元素。此外,儘管這種變化的表現要好得多,但它似乎仍然可能是次優的。所以,我最終使用的最終解決方案是做到以下幾點(我們稱之爲「動態樣式辦法」):

    • 假定每個表都有一個唯一的元素ID
    • 通過創建一個初始化表新欄位(document.createElement('style'))。包含一個規則的樣式,該規則只會爲具有該ID的表格選擇該列,例如用於與表ID「MY_TABLE」,第5列(cellIndex 4),以寬度設定爲70:

      table#my_table th:nth-child(5), table#my_table td:nth-child(5){ max-width:70px; min-width:70px;} 
      
    • 新創建styleElements添加到表元件(未在文件),因此,如果該表是從DOM中刪除,這些額外的樣式也消失

    • 若要更改列寬,唯一需要更改的是相關styleElement的規則0的maxWidth/minWidth塊(注意,您也可以使用一個具有多個規則的樣式表,但我發現每個列使用單獨的樣式表更容易一個規則)。

總體而言,使用動態樣式表的方式在我看來贏家,原因如下:

  • 它是足夠大,可以根據「天真的性能問題表表現良好「的方法(雖然我沒有比較其他方法在非常大的表上的性能)
  • 它是乾淨的:沒有element.style變化是必需的,它不會混亂你的基本文檔DOM作爲相關樣式元素附加到相關選項卡樂(需要測試跨瀏覽器)
  • 如果它的性能是不是已經自動瀏覽器進行了優化,其設計應優化直截了當留下的性能挑戰到瀏覽器處理