翻譯:瘋狂的技術宅
原文: https://www.valentinog.com/bl...
本文首發微信公衆號:jingchengyideng
歡迎關注,天天都給你推送新鮮的前端技術文章javascript
怎樣用原生 JavaScript 生成表格需?本文告訴你答案!html
這是一個刷 JavaScript 經驗值的好機會:在技術面試中出現的最多的一個問題就是怎樣用原生 API 操做 DOM 。前端
在下面的教程中,咱們將瞭解如何使用 JavaScript 生成表格,而無需依賴任何庫或框架。java
在本教程中,你將學習如何:git
要學習本教程,你應該對 HTML 和 JavaScript 有基本的瞭解。程序員
Eloquent JavaScript 是一本很是好的 JavaScript 書籍。這本書很簡潔,也不乏味,同時有大量的練習。如下練習改編自第 14 章,它被稱爲「構建表格」。github
題目要求你用 JavaScript 構建一個 HTML 表。你的任務是依據 「mountains」 數組中的數據生成表格,將對象中的key對應到列而且每行一個對象。面試
每一個對象都是以下形式:json
{ name: "Monte Falco", height: 1658, place: "Parco Foreste Casentinesi" }
咱們有一個名稱,一個高度和一個山峯所在的位置。但 HTML 表格是什麼? HTML 表格是包含表格數據的元素,以行和列的形式顯示。這意味着給出如下數組:bootstrap
let mountains = [ { name: "Monte Falco", height: 1658, place: "Parco Foreste Casentinesi" }, { name: "Monte Falterona", height: 1654, place: "Parco Foreste Casentinesi" } ];
咱們打算生成下表:
<table> <thead> <tr> <th>name</th> <th>height</th> <th>place</th> </tr> </thead> <tbody> <tr> <td>Monte Falco</td> <td>1658</td> <td>Parco Foreste Casentinesi</td> </tr> <tr> <td>Monte Falterona</td> <td>1654</td> <td>Parco Foreste Casentinesi</td> </tr> </tbody> </table>
如你所見,該表有一個 thead(表頭),其中包含一個具備三個th(表格標題)的 tr(表格行) 。
而後是tbody(表體) 中包含一堆 tr(表格行)。每一個表格行包含必定數量的 td元素(表格單元格)。
有了這些要求,就能夠開始編寫 JavaScript 文件了。咱們的起點能夠是如下 HTML:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Build a table</title> </head> <body> <table> <!-- here goes our data! --> </table> </body> <script src="build-table.js"></script> </html>
將文件另存爲 build-table.html 並繼續下一部分。
在與 build-table.html 相同的文件夾中建立一個名爲 build-table.js 的新文件,並在文件定義數組:
let mountains = [ { name: "Monte Falco", height: 1658, place: "Parco Foreste Casentinesi" }, { name: "Monte Falterona", height: 1654, place: "Parco Foreste Casentinesi" }, { name: "Poggio Scali", height: 1520, place: "Parco Foreste Casentinesi" }, { name: "Pratomagno", height: 1592, place: "Parco Foreste Casentinesi" }, { name: "Monte Amiata", height: 1738, place: "Siena" } ];
第一個目標是生成表頭。咱們知道本機方法 createElement()
會建立傳遞給它的任何元素。假設咱們要建立一個表頭,能夠用 document.createElement(‘thead’)
。不過還有更好的辦法嗎?
讓咱們先到 MDN 上查閱一下 element table reference 。你能夠看到表格的DOM接口是 HTMLTableElement。
HTMLTableElement
的有趣之處在於它公開的方法中有 createTHead()。沒錯!createTHead
返回與給定表關聯的表頭元素,更 6 的是,若是表中不存在頭的話,createTHead
會幫咱們建立一個。
有了這些知識,接下來在咱們的文件中建立一個函數,將 table
做爲參數。鑑於咱們的需求,能夠在其中建立一個新的 thead
:
function generateTableHead(table) { let thead = table.createTHead(); }
如今找到咱們的表格(記住在 build-table.html 中有一個)並將其傳給咱們的函數:
function generateTableHead(table) { let thead = table.createTHead(); } let table = document.querySelector("table"); generateTableHead(table);
若是你在瀏覽器中打開 build-table.html,在屏幕上還看不到任何內容,不過能夠在開發者工具中看處處理的結果。填充表頭的工做只作了一半,能夠看到表頭中填充了一堆 th
。每一個表頭必須映射到對象描述數據組成的 key 上。
信息已經存在於數組 mountains 中的第一個對象內部。能夠迭代第一個對象的 key:
let mountains = [ { name: "Monte Falco", height: 1658, place: "Parco Foreste Casentinesi" }, // ];
而後用獲得的 key 生成三個表頭。可是要先在 thead
中添加一行!這時候該用 document.createElement(「TR」)
了吧?不不不。HTMLTableRowElement
提供了一個 insertRow() 方法,能夠在表頭上調用。讓咱們重構一下 generateTableHead
函數:
function generateTableHead(table) { let thead = table.createTHead(); let row = thead.insertRow(); }
新行應包含三個 th
(表頭),須要手動建立,對於每一個 th
元素,咱們將附加一個文本節點。這個函數可使用另外一個參數來進行迭代:
function generateTableHead(table, data) { let thead = table.createTHead(); let row = thead.insertRow(); for (let key of data) { let th = document.createElement("th"); let text = document.createTextNode(key); th.appendChild(text); row.appendChild(th); } } let table = document.querySelector("table"); let data = Object.keys(mountains[0]); generateTableHead(table, data);
保存文件並刷新 build-table.html:你應該看到你的表頭中被填充了 name、height 和 place。 有時用 React 和 Vue 偷懶的感受真好,直接操做 DOM 是多麼艱難和繁瑣。不過咱們的工做尚未完成。
接下來該填表了......
爲了填充表格能夠遵循一樣的方法,但此次咱們須要迭代 mountains 數組中的每一個對象。當進入 for…of 循環時,將爲每一個項目建立一個新行。
要建立行,你將用到 insertRow()。
但咱們不能止步於此。在主循環內部,須要一個內循環,此次要用到 for... in 。內部循環迭代當前對象的每一個 key,同時它:
使用 HTMLTableRowElement 的另外一個方法 insertCell() 建立單元格。
也就是說經過以上邏輯能夠填充咱們的表。打開 build-table.js 並建立一個名爲 generateTable
的新函數。命名能夠與咱們現有的函數相同:
function generateTable(table, data) { for (let element of data) { let row = table.insertRow(); for (key in element) { let cell = row.insertCell(); let text = document.createTextNode(element[key]); cell.appendChild(text); } } }
能夠這樣調用它:
generateTable(table, mountains);
最後來看看完整的代碼:
let mountains = [ { name: "Monte Falco", height: 1658, place: "Parco Foreste Casentinesi" }, { name: "Monte Falterona", height: 1654, place: "Parco Foreste Casentinesi" }, { name: "Poggio Scali", height: 1520, place: "Parco Foreste Casentinesi" }, { name: "Pratomagno", height: 1592, place: "Parco Foreste Casentinesi" }, { name: "Monte Amiata", height: 1738, place: "Siena" } ]; function generateTableHead(table, data) { let thead = table.createTHead(); let row = thead.insertRow(); for (let key of data) { let th = document.createElement("th"); let text = document.createTextNode(key); th.appendChild(text); row.appendChild(th); } } function generateTable(table, data) { for (let element of data) { let row = table.insertRow(); for (key in element) { let cell = row.insertCell(); let text = document.createTextNode(element[key]); cell.appendChild(text); } } } let table = document.querySelector("table"); let data = Object.keys(mountains[0]); generateTableHead(table, data); generateTable(table, mountains);
你以爲它能工做嗎?讓咱們來試試看:
呃……看起來行被附加到了表頭而不是表體。另外沒有table body!
可是若是切換函數調用順序會怎麼樣呢?試試吧:
// omitted for brevity let table = document.querySelector("table"); let data = Object.keys(mountains[0]); generateTable(table, mountains); // generate the table first generateTableHead(table, data); // then the head
再次刷新瀏覽器:
好使!另外還獲得了一個 tbody
。爲何會這樣?當你在空表上調用 insertRow()
時,這些方法會爲自動你建立一個tbody
(若是沒有的話)。
作得好!不過咱們的代碼可能沒進行很好的組織(有太多的全局綁定),這些將會在下一篇文章中提到。
到此爲止,你應該可以在不依賴任何外部庫的狀況下操做HTML表了。恭喜!
在本教程中,咱們學到了如何用原生 JavaScript 生成表格。 HTML 表格在DOM中由 HTMLTableElement 體現。這個接口公開了不少有用的方法,其中 createTHead 用於操做表頭,insertRow 用來插入行。
另外 HTML 表格的行繼承自 HTMLTableRowElement。這個接口有兩種方法,其中最重要的是 insertCell。
給定一個對象數組,可使用 for…of
循環來迭代生成行。對於每一個對象,咱們可使用 for … in
生成單元格。
咱們有一些帶有全局綁定的代碼(請參閱執行上下文和調用堆棧以獲取更多信息)。在下一篇文章中,咱們將看到怎樣重構這些代碼。
jQuery正逐漸消失。 Bootstrap將在版本5中刪除它。 原生DOM API 愈來愈好了,替換之前用 jQuery 作的事情是可行的,沒有(幾乎)任何額外的依賴。
但即便沒有 jQuery 也很容易掉進坑裏。有人說你不該該在沒有 $shinyNewLibrary
的狀況下去操縱 DOM。實際上每一個認真的 JavaScript 開發人員都應該知道原生 DOM API,以及如何使用 JavaScript 操做 DOM 。這些問題在技術面試中很容易被問到,你不想所以被拒絕吧?
本教程的代碼可在 Github 下載(https://github.com/valentinog...)。
感謝閱讀並敬請期待後續!