像在座阅读此文的读者一样,由于自身的兴趣,我对 AJAX 编程方面的研究是持续不断的。随着该领域的深入,我越来越发觉所谓的浏览器 DOM,即 HTML DOM,是一个非常值得关注的点。在与资深的技术人员们交换意见的时候,也曾谈到过这样的观点,就是关于 DOM Level1,我们仍然缺乏具有深度的、规范的辅助读物,而且网络上搜索也比较少见。我们真正的想法在于,工作的时候我们不仅仅是去翻阅工具库/API 那些高级的抽象内容。
为此我打算在本文中拨开其中的云雾,如果您正好想用用“ DOM-脚本”做很多的事情,那么接下来课题内容便适合您了,也可以当作抛砖引玉的 DOM 介绍。本文内容的主题便是,为什么开发者要认为“DOM Level 1规范的架构”是至关重要的,其突出的重要性在哪里等等,以及还有 HTML DOM 和 XML DOM之间微妙的区别及内在的联系。
W3C 所制订的 DOM Level 分为两大模块:Core 和 HTML。第一个大模块是 Core 核心,W3C 规范是这样描述 Core 的:
“满足软件开发者和 Web 脚本编写者,访问和操控产品项目中包含的可解析的 HTML 和 XML 内容。”
"sufficicent to allow software developers and web script authora toaccess and mainipulate parsed HTML and XML content inside conformingproducts."
第二个为 HTML 模块,其规范描述是:
“HTML之中特定元素的功能,和恰到好处的、易用的、针对常见性任务的HTML文档操作机制。”
"functionality that depends on specific elements defined in HTML"
以上可见两者的重要性。同时 HTML 模块的意义也在于,解决了向后兼容的问题,这在当今符合 DOM Level 1 的浏览器中已经可以提供适应的解决方案。
按照这样的说法,如果您仍然不能理解上述的要义,我们则可以这样认为,HTML文档可以使用 Core API 和 HTML API 两者;而 XML 文档只能使用 Core API。换句话说,HTML 与 XML 重叠的部分有 Core API,而 HTM LAPI 则是不能共享的部分,顾名思义限于 HTML 文档所使用。这是我们认识 Core/HTML 的初步认识。
理解DOM Level 1 Core
理解DOM Level 1Core之要义实质在于将Core看待成为许多节点(Nodes)而组成的文档(Document),也就是说,此文档结构中可允许存在着大量的条目项,其每一项都可理解为“节点”。讨论该结构可以以两个方面入手:一、一切皆是节点对象(NodeObject,扁平化的角度去理解,flattened view,乃适合于多态下的接口);二、每个对象继承于基类节点,实现了节点的接口(interface,OO继承的角度去理解);
请观察一下这段HTML:
<divid="myDiv">Hello World</div>
这是一个闭合的 div 标签。从 DOM Level 1 的层面来分析可以有以下几点内容:
标签 div 可作为“节点对象 Node Object(扁平化角度,前面已述)”,或者元素对象 Element OBject (继承的角度 - 元素继承于 Node)。
节点属性id也可作为“节点对象 Node Object(扁平化角度)”,或者属性对象 Attr. OBject(继承的角度 - Attr继承于 Node)。
文本“Hello world”也可作为“节点对象 Node Object(扁平化角度)”,字符串对象 CharacterData对象(继承的角度 - CharacterData 继承于 Node),Text 文本对象(继承的角度 - Tex t继承于 CharacterData)。
稍微归纳一下,就是 DOM 1Core 部分中一切皆是节点,节点以及其接口都可实现在每个对象身上(从继承的角度理解出发),实现了节点接口才可以有节点的属性、方法。——这是我们理解的前提。然后,根据特定的节点类型的不同,其接口的属性和方法都是不同的,视乎 DOM 对该节点的设计而定。
理解 DOM Level 1 HTML
我们日常工作的时候,都跟 HTML 文档打交道,其实就是属于 W3C 所规定的 DOM Level 1HTML 模块内的那些处理工作。HTML DOM 的特性和方法不是标准的 DOM 实现,是专门针对 HTML 同时也让一些 DOM 操作变的更加简便。HTML 模块集中表现在 HTMLElement 接口上,即为全体元素类型的对象所实现的接口。就该文讨论的范围而言,HTMLElement 接口的参与形式与上述的 Node 节点接口非常地相似。一旦引入了 OO 设计观,只要实现了 HTMLElement 接口的对象,就可以定义它为元素了。一份 HTML 文档有相当多的都是元素,当然还有,表示文档本身的 HTMLDocument 和集合容器 HTMLCollection 等等。
因此,要准确理解 DOM 1HTML的模块,必须认识其接口是基于元素的(Element-based),而不是基于节点的(Node-based)。那样的话,元素方式与节点方式到底又有什么区别呢(Element v.s Node),应该如何界定两者呢?例如节点属性(properties ofelements),当在“基于元素”的语境中,就是“属性(attributes)”,并非独立的节点对象。——尽管按照某个角度讲,元素是节点的一种特例,我们仍可保留“节点”这一说法,一个标签(tag)便是一个 “节点”。假如我们要得到 id 属性的字符串的值是什么,采用DOM 1Core 的方式就是,
myElement.attributes["id"].value; // 从Node接口提供的属性
等于下面的方法:
myElement.getAttributes("id"); // 从Element实现的方法返回
但使用 DOM 1 HTML 方式的话,我们仅仅如此:
myElement.id;
这般就可以获取 id 了。此时此刻,你可能会认为,XML 文档本身就不一定缺省有 id 的属性,而因为有你所说的 HTMLElement.id 属性预先定义在 API 中,当然 HTML 中的每个元素就有 id 的属性啦!?——这里的意思没有错,也不妨碍我们的理解。的确全体的 HTML 元素均有 id一项的属性,不管 HTMLDivElement/HTMLImageElement/……
Core or HTML Module?
既然这样,那我应该使用Core的API,还是 HTML 模块的 API?对于 HTML 的文档来说,用 Core 或 HTML Moduel 实际差别不大。本来我们一直都不太强调这种界定,以致忽略了它们细微的差异。如果我们觉得还是模棱两可的话,我们可进一步查探它们的明细。个人认为处理XHTML并使用 Core API 这样更能够说明 XHTML 的 “X”,即表明这份 HTML 就是一份标准的 XML 文档,以便与原有 HTML 4.1 从语义上区别开来。但请记住,当处理一份 XM L结构的文档的时候,自然而然就是采用 Core 去处理。通过XHMLHttpRequest 请求执行后所返回的r esponseXML 结果,那只能使用 Core 的API去处理分析,就不能够采用 HTML 的了。
小结
通过文本开发者应该明白到,HTML DOM 与 XML DOM 之间,既有区别,又有联系。一般而言,除了上述比较外,须值得一提的就是,HTML 是可以允许不 Well-Form 的,XML则不然。