回到基础:如何用原生 DOM API 生成表格
栏目: JavaScript · 发布时间: 5年前
内容简介:翻译:疯狂的技术宅原文:怎样用原生 JavaScript 生成表格需?本文告诉你答案!
翻译:疯狂的技术宅
原文: https://www.valentinog.com/bl...
怎样用原生 JavaScript 生成表格需?本文告诉你答案!
这是一个 刷 JavaScript 经验值的好机会 :在技术面试中出现的最多的一个问题就是 怎样用原生 API 操作 DOM 。
在下面的教程中,我们将了解如何使用 JavaScript 生成表格,而无需依赖任何库或框架。
你将学到些什么
在本教程中,你将学习如何:
- 用 JavaScript 生成一个表格
- 用本机 DOM API 来操作表
要求
要学习本教程,你应该对 HTML 和 JavaScript 有基本的了解。
需求
Eloquent JavaScript 是一本非常好的 JavaScript 书籍。这本书很简洁,也不乏味,同时有大量的练习。以下练习改编自第 14 章,它被称为“构建表格”。
题目要求你用 JavaScript 构建一个 HTML 表。你的任务是依据 “mountains” 数组 中的数据生成表格,将 对象中的key对应到列 并且 每行一个对象 。
每个对象都是如下形式:
{ name: "Monte Falco", height: 1658, place: "Parco Foreste Casentinesi" }
我们有一个名称,一个高度和一个山峰所在的位置。但 HTML 表格是什么? HTML 表格是包含表格数据的元素,以行和列的形式显示。这意味着给出以下数组:
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... )。
感谢阅读并敬请期待后续!
欢迎继续阅读本专栏其它高赞文章:
- 12个令人惊叹的CSS实验项目
- 世界顶级公司的前端面试都问些什么
- CSS Flexbox 可视化手册
- 过节很无聊?还是用 JavaScript 写一个脑力小游戏吧!
- 从设计者的角度看 React
- CSS粘性定位是怎样工作的
- 一步步教你用HTML5 SVG实现动画效果
- 程序员30岁前月薪达不到30K,该何去何从
- 7个开放式的前端面试题
- React 教程:快速上手指南
本文首发微信公众号:jingchengyideng
欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- ElementUI 实现表格可编辑 Editable,增删改查编辑表格Grid
- 开源 UI 库中,唯一同时实现了大表格虚拟化和树表格的 Table 组件 原 荐
- html复杂表格
- PHP基础知识(表格)
- vue导出excel表格
- 如何批量采集网页表格数据?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
需求
[美] 亚德里安•斯莱沃斯基(Adrian J. Slywotzky)、[美]卡尔•韦伯 (Karl Weber) / 魏薇、龙志勇 / 浙江人民出版社 / 2013-6 / 64.9
《财富汇•需求:缔造伟大商业传奇的根本力量》内容简介:需求,是缔造伟大商业传奇的根本力量。《财富汇•需求:缔造伟大商业传奇的根本力量》呈现了人们无法拒绝、竞争对手无法复制的需求创造的六大关键,在人们无奈接受的现状和心中真正期待的理想的这道鸿沟之上,架设起了一道桥梁。 创造需求,需要解开一个谜团,这个谜团是人类学、心理学、科技、设计、经济学、基础设施以及其他众多因素综合而成的奇特组合。《财富汇......一起来看看 《需求》 这本书的介绍吧!