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) 用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点。