浏览器中的JavaScript:文档对象模型与 DOM 操作

更新日期: 2019-05-01阅读: 1411标签: dom

JavaScript 并没有那么糟糕。作为运行在浏览器中的脚本语言,它对于网页操作非常有用。在本文中,我们将看到可以用哪些手段来修改 html 文档和交互。


什么是文档对象模型?

文档对象模型是在浏览器中一切的基础。但它究竟是什么呢?

当我们访问网页时,浏览器会计算出如何解释每个 HTML 元素。这样它就可以创建 HTML 文档的虚拟表示,并保存在内存中。 HTML 页面被转换为树状结构并且每个 HTML 元素都变成一个叶子结点,连接到父分支。看一下这个简单的 HTML 页面:

<!DOCTYPE html>
<html lang="en">
  <head>
        <title>A super simple title!</title>
  </head>
  <body>
      <h1>A super simple web page!</h1>
  </body>
</html>

在这个结构的顶部有一个文档,也称为根元素,它包含另一个元素:html。 html 元素包含一个 head ,而 head 内又有一个 title。然后 body 中包含一个 h1。每个 HTML 元素都由特定类型(也称为接口)表示,并且可以包含文本或其他嵌套元素:

document (HTMLDocument)
  |
  | --> html (HTMLHtmlElement)
          |  
          | --> head (HtmlHeadElement)
          |       |
          |       | --> title (HtmlTitleElement)
          |                | --> text: "A super simple title!"
          |
          | --> body (HtmlBodyElement)
          |       |
          |       | --> h1 (HTMLHeadingElement)
          |              | --> text: "A super simple web page!"

每个HTML元素都来自 Element,但其中很大一部分都是专用的。你可以通过检查原型以查找元素所属的“种类”。例如,h1元素是 HTMLHeadingElement:

document.querySelector('h1').__proto__
// Output: HTMLHeadingElement

而 HTMLHeadingElement 又是 HTMLElement 的“后代”:

document.querySelector('h1').__proto__.__proto__
// Output: HTMLElement

这时(特别是初学者)可能会对 document 和 window 之间的区别产生一些混淆。让我们看看它们有什么不同!


window和document之间的区别

window 是指浏览器,而 document 是你当前正在操作的 HTML 页面,即当前文档。文档界面有许多实用功能,比如querySelector(),一种用于选择给定页面内任何 HTML 元素的方法:

document.querySelector('h1');

window 表示当前窗口的浏览器,以下代码效果与上述相同:

window.document.querySelector('h1');

无论如何,以下语法更常见,你还会看到更多:

document.methodName();


dom 操作

DOM中的每个 HTML 元素也都是“节点”,实际上我们可以像这样去检查节点类型:

document.querySelector('h1').nodeType;

上面的代码会返回 1,它是 Element 类型的节点的标识符。你还可以检查节点名称:

document.querySelector('h1').nodeName;
"H1"

上面的例子用大写的形式返回节点名称。需要理解的也是最重要的概念是,我们主要使用 DOM 中的两种类型的节点:

  • Element 类型的节点(HTML 元素)
  • Text 类型的节点(文本节点)

为了创建 Element 类型的新节点,本机 DOM api 为我们提供了 createelement 方法,你通常会这样调用:

var heading = document.createElement('h1');

为了创建文本,我们可以用 createTextNode:

var text = document.createTextNode('Hello world');

通过在新的 HTML 元素中附加文本,可以将两个节点组合在一起。最后需要注意的是,我们还可以将标题元素附加到根文档:

var heading = document.createElement('h1');
var text = document.createTextNode('Hello world');
heading.appendChild(text);
document.body.appendChild(heading);

在浏览器中使用 JavaScript 时,你需要了解这三种方法。在技术圈中,我们将这些指令称为 DOM 操作

当以这种方式创建和操作元素时,我们谈论的是“命令式” DOM操作。现代前端库正在通过支持“声明”方法来解决这个问题。我们不是一步一步地去命令浏览器,而是声明我们需要什么 HTML 元素,而库可以处理剩下的部分。


DOM 操作和 jquery

此时你可能会想:“我可以只使用jQuery吗?为什么要用 createElement?“ 我经常会被问到这些问题。

好吧,请注意 jQuery 正逐渐消失。 Bootstrap 5 将从依赖项中删除它,还有更多的库或框架正在删除它。这背后有一个十分正当的理由:原生 DOM API 已经非常完整且成熟到足以使 jQuery 过时

如果你想坚持用原生 JavaScript 实现简单的交互和操作。甚至可以创建自己的迷你框架来抽象出最常见的操作:创建元素、追加、创建文本等。


结论

文档对象模型是浏览器创建并保留在内存中的网页的虚拟副本。在创建、修改、删除 HTML 元素时,我们会碰到 “DOM 操作”。在过去即使对于更简单的任务,我们也要依赖于 jQuery,但今天本机 API 已经互相兼容并且足够成熟以使 jQuery 过时。

虽然 jQuery 不会很快的消失,但每个 JavaScript 程序员都必须知道该如何使用本机 API 去操作 DOM。这样做有很多理由,其他库会增加 JavaScript 程序的加载时间和大小,更不用说 DOM 操作在技术面试中出现的越来越多。

DOM 中可用的每 个HTML 元素都有一个暴露一定数量属性和方法的接口。如果对使用什么方法有疑问,可以参考 MDN上的优秀文档。

操作 DOM 最常用的方法是 document.createElement() 用于创建新的 HTML 元素,document.createTextNode() 用于在 DOM 内创建文本节点。需要注意的是 .appendChild() 用于将新的 HTML 元素或文本节点附加到现有元素。

虽然很好的了解本机 API 是很好的,但是现代前端库也提供了无可置疑的好处。尽管用“原生” JavaScript 去构建大型JavaScript 程序确实是可行的,但有时 angularreactvue可以提供很多帮助。仅使用 JavaScript 来处理更简单的原型和中小型应用也是明智之举。


资源

如果你想了解更多关于文档对象模型的内容,那么 Aderinokun 还有另一篇好文章。非常详细,值得一读:文档对象模型究竟是什么

如果你想回到基础知识,请查看如何使用原生 JavaScript 生成表格 一文!在没有任何前端框架的帮助的情况下,你会发现实现它都需要什么。


本文首发微信公众号:前端先锋 
翻译:疯狂的技术宅
原文:https://www.valentinog.com/

 

链接: https://www.fly63.com/article/detial/3161

全面理解虚拟DOM,实现虚拟DOM

DOM是很慢的,其元素非常庞大,页面的性能问题鲜有由JS引起的,大部分都是由DOM操作引起的。虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。

HTML文档解析和DOM树的构建

浏览器解析HTML文档生成DOM树的过程,以下是一段HTML代码,以此为例来分析解析HTML文档的原理.解析HTML文档构建DOM树的理解过程可分为两个主要模块构成,即标签解析、DOM树构建

原生js获取DOM对象的几种方法

javascript获取DOM对象的多种方法:通过id获取 、通过class获取、通过标签名获取、通过name属性获取、通过querySelector获取、通过querySelectorAll获取等

JavaScript中易混淆的DOM属性及方法对比

ParentNode.children:该属性继承自ParentNode,返回值是一个HTMLCollection实例,成员是当前节点的所有元素子节点,该属性只读,且该属性是动态集合。Node.prototype.childNodes:该属性继承自Node,返回值是一个NodeList实例,成员是当前节点的所有子节点(包括但不限于元素子节点),该属性也是个动态集合。

js实现DOM遍历_遍历dom树节点方法

遍历DOM节点常用一般用节点的 childNodes, firstChild, lastChild, nodeType, nodeName, nodeValue属性。在获取节点nodeValue时要注意,元素节点的子文本节点的nodeValue才是元素节点中文本的内容。

如何编写自己的虚拟DOM

要构建自己的虚拟DOM,需要知道两件事。你甚至不需要深入 React 的源代码或者深入任何其他虚拟DOM实现的源代码,因为它们是如此庞大和复杂——但实际上,虚拟DOM的主要部分只需不到50行代码。

归纳DOM事件中各种阻止方法

事件冒泡: 即事件开始时由最具体的元素(文档中嵌套层数最深的那个点)接收,事件捕获:不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件.与此同时,我们还需要了解dom事件绑定处理的几种方式:

关于DOM操作是异步的还是同步的相关理解

先列出我的理解,然后再从具体的例子中说明:DOM操作本身应该是同步的(当然,我说的是单纯的DOM操作,不考虑ajax请求后渲染等);DOM操作之后导致的渲染等是异步的(在DOM操作简单的情况下,是难以察觉的)

JavaScript DOM事件模型

早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的JavaScript的实现都不进相同,本节内容介绍JavaScript的DOM事件模型及事件处理程序的分类。

vuejs2.0如何获取dom元素自定义属性值

设置定义属性值 :data-value=.., 2.直接获取 3.通过this.$refs.***获取 1.目标DOM定义ref值: 2.通过 【this.$refs.***.属性名】 获取相关属性的值: this.$refs.*** 获取到对应的元素 ...

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!