拓冰建站拓冰建站
首页 / 资讯中心 / 正文

The JavaScript Way 第 13 章精讲:深入浏览器背后的 DOM(文档对象模型)

教程文档【免费下载链接】thejswayThe JavaScript Way book项目地址https://gitcode.com/gh_mirrors/th/thejsway点击查看免费下载导读本文基于《The JavaScript Way》一书的第 13 章「Discover the DOM」为你完整讲解网页在浏览器中的结构化表示——DOMDocument Object Model文档对象模型。你将理解浏览器如何把 HTML 代码转换为可编程的树形结构掌握document根对象、节点类型判断nodeType、子节点遍历childNodes与父节点访问parentNode等核心技术并最终完成一个实战练习showChild()。读完本文你就能用 JavaScript 直接访问并理解任意网页的内部结构为后续章节的动态修改页面chapter14.md「Traverse the DOM」、chapter15.md「Modify page structure」打下坚实基础。什么是 DOM网页的结构化表示 编程接口在 chapter12.md「Whats a web page?」中你已经了解到网页是由 HTML 标签与文本组成的文档浏览器是访问网页的软件。但浏览器真正在幕后做的事情远不止显示——当你请求一个网页时浏览器会经历以下过程解析 HTML 代码把文本流解析成带层级关系的标签结构构建结构表示为这个结构建立一棵内存中的树渲染显示把这棵树绘制到浏览器窗口暴露编程接口把这棵树以对象的形式开放给 JavaScript让程序可以动态增删元素、修改样式。正是第 4 步让网页从静态文档变成交互式网页。这个步骤背后依赖的标准化模型就是DOMDOMDocument Object Model定义了网页的结构以及与之交互的方式本质上是一套编程接口APIApplication Programming Interface。JavaScript 是与 DOM 交互的首选语言。值得注意的历史背景原书引言在 Web 早期每个浏览器都有自己的 DOM 实现这让当时的 JavaScript 开发者头疼不已。直到 1998 年通过 W3C万维网联盟的努力第一版统一 DOM 规范诞生。如今所有现代浏览器都遵循标准化的 DOM跨浏览器开发网页的黑暗时代已经结束。网页的树形结构元素节点与文本节点一段 HTML 是一组嵌套的标签。我们可以把它表示成一种层级结构称为树tree。以本书第 13 章的示例页面为例完整代码见 manuscript/chapter13.md!doctype html html head meta charsetutf-8 titleMy web page/title /head body h1My web page/h1 pHello! My names Baptiste./p pI live in the great city of a hrefhttps://en.wikipedia.org/wiki/BordeauxBordeaux/a./p /body /html浏览器加载后页面显示效果如下html元素将文档定义为 HTML并包含两个子元素head和body它们又各自包含若干子元素。把这种嵌套关系画成树就是下图在这棵树中每个实体称为一个节点node分为两种类型节点类型图中颜色对应内容能否拥有子节点元素节点element node蓝色HTML 标签如body、p可以其子节点称为子节点child nodes / children文本节点text node红色页面的文本内容不能文本节点没有子节点从这张结构图中可以看到title节点下挂着文本节点 My web pageh1下同样挂着文本节点 My web page而第二个p段落节点则拥有三个子节点——文本节点 I live in the great city of、a元素节点其下再挂文本节点 Bordeaux、以及文本节点 .。树形结构直观揭示了 HTML 的嵌套本质这也是接下来用 JavaScript 导航 DOM 的基础。用 JavaScript 初探 DOMDOM 将网页表示为一棵对象层级结构每个对象对应嵌套 HTML 元素树中的一个节点这些对象拥有可被 JavaScript 操作的属性properties和方法methods。通过document变量访问 DOM当 JavaScript 程序运行在浏览器环境中时可以通过变量document访问 DOM 的根部。这个变量对应 HTML 中的html元素且本身是一个对象带有head与body属性分别指向页面的head和body元素const h document.head; // h variable contains the contents of the DOMs head const b document.body; // b variable contains the contents of the DOMs body用nodeType判断节点的类型每个 DOM 对象都有属性nodeType用于标识节点类型。其取值可以是常量document.ELEMENT_NODE元素节点即 HTML 标签或document.TEXT_NODE文本节点if (document.body.nodeType document.ELEMENT_NODE) { console.log(Body is an element node!); } else { console.log(Body is a textual node!); }运行结果为正如预期body是 HTML 标签因此nodeType为document.ELEMENT_NODE。实际开发中nodeType常用于写通用遍历函数前先校验节点类型本章末的练习就要用到它。用childNodes访问子节点每个元素类型的 DOM 对象都有属性childNodes这是一个有序集合包含该节点的所有子节点以 DOM 对象形式存放可以使用类似数组的下标访问// Access the first child of the body node console.log(document.body.childNodes[0]);运行结果出乎很多初学者的意料——打印出来的并不是h1原因在于HTML 代码中标签之间的空格和换行会被浏览器视为文本节点。因此h1其实是 body 的第二个子节点验证如下// Access the second child of the body node console.log(document.body.childNodes[1]);想要去掉这些文本节点可以把 HTML 写成更紧凑的形式例如bodyh1My web page/h1!-- ... --但原书作者的建议很明确为了可读性和代码缩进宁可接受标签之间的文本节点存在也不建议牺牲代码的整洁。⚠️ 重要提示元素节点的childNodes属性不是真正的 JavaScript 数组而是一个NodeList对象。标准数组方法并不能全部应用于它例如不是所有浏览器都支持直接在 NodeList 上调用forEach原生方法只有item()与length。需要数组操作时可以用Array.from()转换——这一点在下一章 chapter14.md 中会再次强调。三种方式遍历子节点要遍历某个节点的所有子节点书中给出了三种等价写法// Browse the body nodes children using a for loop for (let i 0; i document.body.childNodes.length; i) { console.log(document.body.childNodes[i]); } // Browse the body nodes children using the forEach() method document.body.childNodes.forEach(node { console.log(node); }); // Browse the body nodes children using a for-of loop for (const node of document.body.childNodes) { console.log(node); }三种写法输出完全一致可以看到body 的 7 个子节点中大量是标签间的换行/缩进形成的文本节点——这正是空白换行也算节点规则的直观体现。用parentNode访问父节点每个 DOM 对象都有属性parentNode返回其父节点也是 DOM 对象。但对于 DOM 根节点document来说它没有父节点因此parentNode的值为nullconst h1 document.body.childNodes[1]; console.log(h1.parentNode); // Show the body node console.log(document.parentNode); // Will show null, since body has no parent node注意原书注释中有一个小笔误实际是document而非 body没有父节点。除parentNode外DOM 还提供了firstChild、lastChild、nextSibling等导航属性本章不作展开后续章节会用到其中的思路。本章小结TL;DR网页是包含文本与 HTML 标签的结构化文档。DOM文档对象模型是定义网页结构的标准化方式。DOM 同时是一套API允许通过程序与网页交互。用 JavaScript 可以访问并修改浏览器中显示页面的结构。DOM 把网页表示为一棵对象层级树每个对象对应嵌套 HTML 元素树中的一个节点。变量document提供对 DOM 树根部的访问对应 HTML 中的html元素。DOM 对象具有可被 JavaScript 操作的属性与方法nodeType返回节点类型childNodes包含子节点集合parentNode返回父节点。实战练习编写showChild()函数本章的 Coding Time 练习要求你编写一个showChild()函数它接收一个父节点DOM 元素节点和一个子节点索引打印出对应的子节点并处理两类错误——父节点不是元素节点、索引越界。关联的 HTML 结构如下h1A title/h1 divSome text with a href#a link/a./div请在下面程序的TODO处补全代码使各条调用得到预期结果// Show a DOM objects child node // node is the DOM object // index is the index of the child node const showChild (node, index) { // TODO: add code here }; // Should show the h1 node showChild(document.body, 1); // Should show Incorrect index showChild(document.body, -1); // Should show Incorrect index showChild(document.body, 8); // Should show Wrong node type showChild(document.body.childNodes[0], 0);解题要点校验节点类型document.body.childNodes[0]是 body 与h1之间的文本节点空白换行所致此时应输出 Wrong node type。可用node.nodeType ! document.ELEMENT_NODE判断校验索引越界索引为负数-1或超过子节点数量8而 body 实际子节点数远小于此时应输出 Incorrect index。注意childNodes是 NodeList可用node.childNodes.length获取数量正常输出showChild(document.body, 1)应输出h1A title/h1这个元素节点。原书还给出了一个实用建议错误信息用console.error()而不是console.log()输出这样在控制台中错误会以醒目的样式显示便于调试时与正常输出区分。参考实现基于本章所讲 API 的一种写法供读者对照const showChild (node, index) { if (node.nodeType ! document.ELEMENT_NODE) { console.error(Wrong node type); return; } if (index 0 || index node.childNodes.length) { console.error(Incorrect index); return; } console.log(node.childNodes[index]); };下一步从看懂 DOM走向驾驭 DOM本章建立了 DOM 的完整心智模型树形结构、两类节点、根部document、三大核心属性nodeType/childNodes/parentNode。下一章 chapter14.md 将教你更高效地遍历 DOM——届时你会看到靠childNodes逐层下标导航如document.body.childNodes[5].childNodes[1]虽然可行却非常笨拙getElementsByTagName()、getElementsByClassName()、getElementById()以及基于 CSS 选择器的querySelectorAll()/querySelector()才是日常开发的主力再下一章 chapter15.md 则会讲解用 JavaScript修改页面结构让网页真正动起来。本书全部章节源码均位于仓库的 manuscript 目录可对照原文逐章练习。赞分享教程文档【免费下载链接】thejswayThe JavaScript Way book项目地址https://gitcode.com/gh_mirrors/th/thejsway点击查看免费下载相关推荐深入理解 JavaScript 面向对象编程class、原型链与委托实战The JavaScript Way 第 9 章精读深入理解 JavaScript 面向对象编程class、原型链与委托实战The JavaScript Way 第 9 章精读 本篇技术指南围绕开源书籍《T教程文档The JavaScript Way 第八章精讲JavaScript 字符串处理的完整实战指南The JavaScript Way 第八章精讲JavaScript 字符串处理的完整实战指南 本文基于开源书籍《The JavaScript Way》的 m教程文档SadTalker技术解析如何用单张图片和音频生成逼真3D面部动画SadTalker技术解析如何用单张图片和音频生成逼真3D面部动画 在数字内容创作领域音频驱动的人脸动画技术一直是计算机视觉和图形学的核心挑战。传统方法需要人工智能媒体生成计算机视觉深度学习数字人上一篇jemalloc配置最佳实践不同应用场景下的参数推荐下一篇突破边界GroundingDINO与SEEM结合实现全场景多粒度物体分割创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门