DOM之节点层次

时间:2022-08-06 20:07:02

1.1 Node类型

  DOM1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现。这个Node接口在JS中是作为Node类型实现的;除了IE之外,其他浏览器可访问这个类型。JS中的所有节点类型都继承自Node类型。注意:不是所有节点类型都受到了Web浏览器的支持。

  每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,并不是Array的实例。它实际是基于DOM结构动态执行查询的结果。除了在IE8-中,可以使用Array.prototype.slice()方法来转换成数组。而兼容IE8-的版本如下:

function convertToArray(nodes) {
    var array = null;
    try {
        array = Array.prototype.slice.call(nodes, 0);
    } catch (ex) {
        array = new Array();
        for (var i = 0, len = nodes.length; i < len; i++) {
            array.push(nodes[i]);
        }
    }
    return array;
}

如果传入appendChild()中的节点已经是文档的一部分,那么结果就是把该节点从原来的位置转移到新位置。replaceChild()和removeChild()节点还是为文档所有,是不过文档中没有了位置。

  cloneNode()方法用于创建一个副本。但传入参数为true时,执行深复制,复制节点以及整个子节点树;在参数为false时,执行浅复制,只复制节点本身。副本节点属于文档,但没有位置。在使用childNodes时,注意在IE8-中,不会为空白符创建节点。cloneNode()方法不会复制添加到DOM节点中的JS属性,比如事件处理程序。IE在此存在一个bug,会复制事件处理程序。所以,建议在使用方法前移除事件处理程序。

  normalize()方法的作用是处理文档树中的文本节点,包括空文本节点和相邻文本节点问题。

1.2 Document类型

  JS通过Document类型表示文档。document对象是HTMLDocument(继承自Document类型)的一个实例,表示整个HTML页面。而且,document对象是window对象的一个属性,因此可作为全局对象来访问。

1.2.1 文档的子节点

  DOM规定Document节点的子节点可以是DocumentType、Element、ProcessingInstruction或Comment,但有两个内置的访问其子节点的快捷方式。第一个就是documentElement属性,该属性始终指向HTML页面中的<html>元素。另一个是通过childNodes列表访问文档元素。document对象还有一个body属性,直接指向<body>元素。

  注意各浏览器在处理文档类型说明和<html>元素之外的注释之间的差别。会导致<html>不是document的第一个子节点。

1.2.2 文档信息

  作为HTMLDocument的一个实例,document对象有一些标准Document对象没有的属性。比如:title,包含<title>元素中的文本。其中的URL、domain和referrer都是从请求的HTTP头部中取出来的。其中只有domain可以设置,但也只可以设置URL中存在的域。而且只能变紧。

  当页面中包含来自其他子域的框架或内嵌框架时,能过设置document.domain就非常方便了。由于跨域安全限制,不同子域页面无法通过JS通信,可以将每个页面的document.domain设置为一样的值,就可以互相访问。

1.2.3 查找元素

  主要的方法有getElementById()、getElementsByTagName()和getElementsByName()。

1.3 Element类型

  Element元素用于表现XML或HTML元素。

1.3.1 HTML元素

  所有的HTML元素都由HTMLElement类型表示,或者由更具体的子类型。

1.3.2 取得特性

  操作特性的DOM方法主要有三个,分别是getAttribute()、setAttribute()和removeAttribute()。此处要注意:HTML元素的特性和对应的DOM元素的属性之间有些差别。比如特性中的class对应到了属性中的className。

  两类特殊的特性,它们虽然有对应的属性名,但属性的值与通过getAttribute()返回的值并不相同。第一类是特性是style,通过getAttribute()访问时,返回的style特性值中包含的是CSS文本,而通过属性来访问会返回一个对象。这说明,style属性并没有直接映射到style特性。第二类特性是onclick这样的事件处理程序。通过getAttribute()访问,则会返回相应代码的字符串,而访问onclick属性时,则返回一个JS函数(没有指定时,返回null)。

1.3.3 设置特性

  setAttribute()方法可以操作HTML特性,特性名统一转换为小写形式。因为所有特性都是属性,直接给属性赋值可以设置特性的值,不过为DOM元素添加自定义的属性,该属性不会自动成为元素的特性。

  removeAttribute(),这个方法用于彻底删除元素的特性。

1.3.4 atttibutes属性

  Element类型是使用attributes属性的唯一一个DOM节点类型。该属性中包含一个NamedNodeMap,与NodeList类似,也是一个动态的集合。

1.3.5 创建元素

  使用document.createElement()方法可以创建新元素。在IE中,为这个方法传入完整的元素标签,可以用来避开IE7-中动态创建元素的某些问题。注意此种方式需要浏览器检测。

1.3.6 元素的子节点

  注意各浏览器对待childNodes属性时的差异性。可利用nodeType来辅助获得目标节点。

1.4 Text类型

  文本节点由Text类型表示,包含的是可以照字面解释的纯文本内容。里面的内容不能包含HTML代码,会被转义。

1.4.1 创建文本节点

  使用document.createTextNode()创建文本节点。如果两个文本节点是相邻的同胞节点,那么这两个节点中的文本就会连起来显示,中间不会有空格。

1.4.2 规范化文本节点

  使用normalizez()方法可以合并多个相邻的文本节点。

1.4.3 分割文本节点

  Text类型提供了一个splitText()函数,将一个文本节点分成两个文本节点。分割文本节点是从文本节点中提取数据的一种常见DOM解析技术。

1.5 Comment类型

  注释在DOM中是通过Comment类型来表示的。Comment类型与Text类型继承自相同的基类,因此它拥有除了splitText()之外的其他方法。

1.6 DocumentType类型

  DocumentType类型仅有Firefox、Safari和Opera支持它。

1.7 DocumentFragment类型

  所有节点类型中,只有DocumentFragment在文档中没有对应的标记。虽然不能把文档片段直接添加到文档中,但可以将它作为一个“创库"来使用,提高效率。文档片段中的节点不属于文档树。通过appendChild()或insertBefore()将文档片段中内容添加到文档中,即使文档片段作为参数,也只会将子节点添加过去,文档片段本身永远不会成为文档树的一部分。

1.8 Attr类型

  元素的特性在DOM中以Attr类型来表示。从技术角度讲,特性就是存在于元素的attributes属性中的节点。尽管它们也是节点,但特性却不被认为是DOM文档树的一部分。