簡體   English   中英

如何在 JavaScript 中顯式設置 HTML 表格列寬

[英]How to set HTML Table column widths explicitly in JavaScript

我在使用 JavaScript 操作時遇到了 HTML 表格的縮放問題。

我有一個 JavaScript 代碼塊,可以從 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

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

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');

我嘗試了幾種方法給這只貓剝皮,這是我的發現。 最終的解決方案最終變得非常干凈和高效,並帶有我在 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-width 和 max-width 以避免您不嘗試調整大小的列以保持表格大小不變

  • 您可以使用 element.style.xxxWidth 來執行此操作,但是正如 OP 所指出的,OP 中的簡單方法不能很好地擴展。

    • 解決這個問題的一種方法是只更新可視區域中的元素(我們稱之為“可視區域方法”)。 您可以通過比較父對象和您正在檢查的對象的 parent.getBoundingClientRect() 結果來做到這一點(參見例如如何判斷 DOM 元素在當前視口中是否可見?
    • 只要對 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 片段(注意,您也可以使用具有多個規則的單個樣式表來執行此操作,但我發現它更易於使用每列有一個單獨的樣式表,每列有一個規則)。

總的來說,在我看來,使用動態樣式表方法是贏家,原因如下:

  • 它在大到足以在 OP 中描述的“幼稚”方法下出現性能問題的表上表現良好(盡管我沒有比較其他方法在非常大的表上的性能)
  • 它很干凈:不需要更改 element.style,並且不會弄亂您的基本文檔 DOM,因為相關樣式元素已附加到相關表(需要測試跨瀏覽器)
  • 如果瀏覽器尚未自動優化其性能,則其設計應通過將性能挑戰留給瀏覽器來處理,從而使優化變得簡單

暫無
暫無

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

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