DOM

Posted jonas-von

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DOM相关的知识,希望对你有一定的参考价值。

DOM

  DOM 是 Document Object Model 的缩写,意为文档对象模型,在前面也说到它是 JS 的一个组成部分,是一个编程接口。它的核心就是把整个网页结构映射成一颗节点树(多层次的节点结构),节点可以分为几种不同类型,每种类型分别表示文档中的不同信息,每个节点都拥有自己的特点、数据和方法,也与其他节点存在着某些关系,比如说,父子节点,兄弟节点等等。这颗 DOM tree 最外层的是文档节点,与之对应的是 document 对象,通过这个对象可以操作这颗 DOM tree 的所有节点。在一个网页中只能有一个文档节点,文档节点下也只能有一个子节点,这个子节点就是根节点(html)。

  DOM 还有等级之分,DOM 1级(也称DOM 1)由两个模块组成,一个是 DOM core (DOM 核心),另一个是 DOM HTML,其中,DOM 核心规定如何映射文档结构,DOM HTML 在 DOM 核心的基础上进行扩展,添加了针对 HTML 的对象和方法。DOM 2 在 DOM 1 的基础上扩展了鼠标和用户界面事件等模块,而且通过对象添加了针对 CSS 的接口。DOM 2 具体的模块如下:

① DOM 视图 (DOM Views),定义了跟踪不同文档视图的接口。

② DOM 事件(DOM Events),定义了事件和事件处理的接口。

③ DOM 样式(DOM Style),定义了基于 CSS 为元素应用样式的接口。

④ DOM 遍历和范围(DOM Traversal and Range),定义了遍历和操作文档的接口。

DOM 3 也是对 DOM 的扩展,引入了统一方式加载和保存文档的方法和验证文档的方法。或许你会发现这里缺少了一个 DOM 0,实际上是没有 DOM 0 的标准的,DOM 0 只是 DOM 历史节点上的一个参考点而已,他指的是  Internet Explorer 4.0 和 Netscape Navigator 4.0 最初支持的 DHTML。

  DOM 1 定义了一个 Node 接口,该接口由 DOM 中所有节点类型实现,也就是说,JS 中的所有节点类型都继承与 Node 类型,也因此所有节点都有着共同的方法和属性。例如,每个节点都有一个 nodeType 属性(该属性只读,返回一个 1-12 的数字分别代表不同的节点类型),用于表明节点的类型。节点类型由在 Node 类型中定义的下列 12 个数值常量来表示:

技术分享图片

其实常用的也就前3个,属性节点也弃用,但是它依然能返回正常的值,vue框架里面也还有用它~.~。除了上面说到的 nodeType 属性以外,下面列举还会用的一些属性:

① Node.baseURI 是一个只读属性,返回一个节点的绝对基址URL,如果无法获取则返回 null 。document 的默认基址是浏览器显示的地址(window.location)。

② Node.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合。需要注意的是,该属性会包含文本节点,那个代码格式化的换行也是一个文本节点,所有在使用的时候最后先过滤掉这些节点。返回值总是一个类数组对象(伪数组),如果没有子节点,则返回一个空的伪数组。

 Node.parentNode 与 Node.parentElement 前者返回父节点,后者返回父元素,一般情况下区别不大,返回的都是直接的一个 DOM ,而不再是伪数组了!!

③ Node.firstNode 只读属性,返回指定节点中的第一个子节点,如果没有子节点,就返回null。当然,这里也要小心文本节点哦~~ 另外,这也是一个实时更新的集合,何为实时更新,看下面例子:

技术分享图片

也许你会说,这不是一个死循环吗?额... 答案还真不是,vue 效率高除了使用列表标记以外,还用到一个优化更新次数的技术 Fragment ,将页面中多次被改变的 DOM 放入 Fragment 容器中,再去进行修改更新,这里面的步骤 —— 将 DOM 添加到 Fragment 中也正是用了这种表达,while 循环,添加首个子节点。这也说明了属性 firstChild 是实时更新的。

④ Node.lastChild 只读属性,返回指定节点里面的最后一个子节点,没有则返回 null ,用于跟 firstChild 类似。

⑤ Node.nextSibling 只读属性,返回指定节点的下一个相邻的兄弟节点,没有则返回 null。当然也包括文本节点~~

  Node.previousSibling 只读属性,返回指定节点的上一个相邻的兄弟节点,没有则返回 null。当然也包括文本节点~~

⑥ Node.nodeName 只读属性,返回当前节点的名称

⑦ Node.nodeValue 返回或设置当前节点的值,对于文档节点来说, nodeValue返回null. 对于text, comment, 和 CDATA 节点来说, nodeValue返回该节点的文本内容. 对于 attribute 节点来说, 返回该属性的属性值

⑧ Node.textContent 与 Node.innerHTML 前者返回的是指定节点以及其所有后代的文本内容;后者返回的是 HTML 文本,前者性能更好。这两个属性也可以设置节点的文本内容,如果只是单纯的文本,两者都可以使用;如果是一段 HTML 代码而且期望被解释,就必须通过后者设置。

  常用到的属性估计就上面这些了,接下再罗列出 Node 的方法:

① Node.appendchild( ) 将一个节点添加到指定父节点的子节点列表末尾,在前面已经有介绍了,这里不废话了。

② Node.cloneNode( deep=false ) 克隆节点,参数deep可选,true表示深度克隆,返回一个副本节点。

③ Node.contains( otherNode ) 如果 otherNode 是 node 的后代节点或是 node 节点本身.则返回true , 否则返回 false

④ Node.hasChildNodes( ) 返回一个布尔值,如果指定节点有子节点则返回 true,否则返回 false。

⑤ Node.insertBefore( newValue, referenceNode ) 在指定位置插入一个 DOM ,注意,该方法是由父节点调用的,在父节点内部的某个位置插入一个 DOM,参数 newValue 表示新的 DOM ,referenceNode 表示在哪个 DOM 前面插入。例如:

技术分享图片

在 ul 的第一个子节点前插入了一个 span (当然这只是举例~~)

⑥ Node.isEqualNode( otherNode )  用于判断两个节点是否相等。当两个节点的类型相同,定义特征(defining characteristics)相同(对元素来说,即 id,孩子节点的数量等等),属性一致等,这两个节点就是相等的。一些具体的数据指出:多数时候的比较是根据节点的类型来的。

⑦ Node.normalize( )  额,官方上面好似是这么定义的:将当前节点和它的后代节点”规范化“,在一个"规范化"后,不存在一个空的文本节点,或者两个相邻的文本节点。但是,不太高兴了,这里所说的“不存在一个空的文本节点”并不是我们“讨厌”的格式化换行,而是特指两个相连的文本节点会合并成一起,仅此而已~~

⑧ Node.removeChild( child ) 从DOM中删除一个子节点。返回删除的节点。

⑨ Node.replaceChild( newChild ,oldChild) 用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点。

以上是关于DOM的主要内容,如果未能解决你的问题,请参考以下文章

React虚拟dom中的key值

DOM事件: DOM事件级别DOM事件流DOM事件模型DOM事件捕获过程自定义事件

虚拟DOM(Virtual Dom) VS 影子DOM(Shadow Dom)

虚拟DOM(Virtual DOM)

关于DOM级别的一些问题,DOM0,DOM1,DOM2

DOM事件类