DOM Core 及 DOM HTML 规范中明确说明了文档对象模型中各种接口的 IDL (Interface Definition Language) 定义,包括了接口之间的继承关系和接口所具有的属性及方法。
其中,DOM Core 规范定义了访问和操作文档对象的一套对象和接口,这其中包含了对 HTML 及 XML 的解析及操作;DOM HTML 规范为 DOM Core 的扩展,描述了 HTML 及 XHTML
的对象的细节。
如 HTMLDocument 接口将继承 Document 接口中的所有属性及方法,同时 HTMLDocument 接口也会实现一些自身的属性及方法。
下面的表格列举了 DOM Core 及 DOM HTML 规范中描述的接口的继承关系。其中 背景色 代表此接口属于 DOM Core 规范, 背景色 代表此接口属于 DOM HTML 规范。
1
is the root |
2
inherits from 1 |
3
inherits from 2 |
4
inherits from 3 |
---|---|---|---|
NodeList | |||
NamedNodeMap | |||
DOMImplementation | |||
Node | DocumentFragment | ||
CharacterData | Text | CDATASection | |
Comment | |||
Attr | |||
DocumentType | |||
Notation | |||
Entity | |||
EntityReference | |||
ProcessingInstruction | |||
Document | HTMLDocument | ||
Element | HTMLElement | HTMLHtmlElement | |
HTMLHeadElement | |||
HTMLLinkElement | |||
HTMLTitleElement | |||
HTMLMetaElement | |||
HTMLBaseElement | |||
HTMLIsIndexElement | |||
HTMLStyleElement | |||
HTMLBodyElement | |||
HTMLFormElement | |||
HTMLSelectElement | |||
HTMLOptGroupElement | |||
HTMLOptionElement | |||
HTMLInputElement | |||
HTMLTextAreaElement | |||
HTMLButtonElement | |||
HTMLLabelElement | |||
HTMLFieldSetElement | |||
HTMLLegendElement | |||
HTMLUListElement | |||
HTMLOListElement | |||
HTMLDListElement | |||
HTMLDirectoryElement | |||
HTMLMenuElement | |||
HTMLLIElement | |||
HTMLDivElement | |||
HTMLParagraphElement | |||
HTMLHeadingElement | |||
HTMLQuoteElement | |||
HTMLPreElement | |||
HTMLBRElement | |||
HTMLBaseFontElement | |||
HTMLFontElement | |||
HTMLHRElement | |||
HTMLModElement | |||
HTMLAnchorElement | |||
HTMLImageElement | |||
HTMLObjectElement | |||
HTMLParamElement | |||
HTMLAppletElement | |||
HTMLMapElement | |||
HTMLAreaElement | |||
HTMLScriptElement | |||
HTMLTableElement | |||
HTMLTableCaptionElement | |||
HTMLTableColElement | |||
HTMLTableSectionElement | |||
HTMLTableRowElement | |||
HTMLTableCellElement | |||
HTMLFrameSetElement | |||
HTMLFrameElement | |||
HTMLIFrameElement | |||
HTMLCollection | |||
HTMLOptionsCollection |
关于 DOM Core 及 DOM HTML 中接口的更多信息,请参考 DOM 规范 Document Object Model Core 及 Document Object Model HTML 中的内容。
在 IE6 IE7 IE8(Q) 中,无法通过脚本检测到 DOM 接口原型,故无法获得其接口继承关系。
在 IE8(S) 中,只能检测到部分 DOM 接口原型,但这些原型不可枚举,故无法获得其接口继承关系。
在 Firefox 中,部分 DOM 接口原型不可枚举,接口继承关系与 DOM 规范中的描述不符。
在 Chrome Safari Opera 中,DOM 接口继承关系遵照了 DOM 规范中的描述。
若修改了某些较高层的 DOM 接口,如 Document 接口中的 getElementById 方法,则由于继承关系的存在,将会导致 Chrome Safari Opera 中作为 HTMLDocument 接口的实例——document 对象的 getElementById 方法异常。
所有浏览器 |
---|
分析以下代码:
<!DOCTYPE html> <html> <head> </head> <body> <div id="d" style="display:none;">DIV element</div> <script> try { Document.prototype.getElementById = function () { return "method getElementById in interface Document modified"; } } catch (ex) { document.write(ex.message + '<br />'); } document.write('getElementById("d"): ' + document.getElementById("d") + '<br />'); try { document.write('HTMLDocument.prototype.getElementById: ' + HTMLDocument.prototype.getElementById); } catch (ex) { document.write(ex.message + '<br />'); } </script> </body> </html>
上面代码中尝试修改了 Document 接口下的 getElementById 方法,之后检测了 document.getElementById("d") 的返回值以及 HTMLDocument.prototype.getElementById 方法的内容。
这段代码在不同浏览器中运行结果如下:
IE6 IE7 IE8(Q) |
---|
'Document' 未定义
getElementById("d"): [object] 'HTMLDocument' 未定义 |
IE8(S) |
'Document' 未定义
getElementById("d"): [object HTMLDivElement] HTMLDocument.prototype.getElementById: function getElementById() { [native code] } |
Firefox |
getElementById("d"): [object HTMLDivElement]
HTMLDocument.prototype.getElementById: function getElementById() { [native code] } |
Chrome Safari Opera |
getElementById("d"): method getElementById in interface Document modified
HTMLDocument.prototype.getElementById: function () { return "method getElementById in interface Document modified"; } |
根据 DOM 规范,document 对象为 HTMLDocument 接口的实例,HTMLDocument 接口继承自 Document 接口,getElementById 方法定义在 Document 接口中。若通过 Document.prototype.getElementById 修改了 getElementById 方法,此时 HTMLDocument 接口中继承自 Document 接口的 getElementById 也会发生变化,则在通过 document.getElementById() 调用 getElementById 方法时将调用修改后的方法。
下面更加详细地测试各浏览器中 DOM 接口的继承关系,以 Node -> Document -> HTMLDocument -> 以及 Node -> Element -> HTMLElement -> HTMLFormElement 为例。
<!DOCTYPE html> <html> <head> </head> <body style="font:24px Consolas;"> <script> function $r(str) { document.write(str); } function testDOMObject(objStr, level) { var indent = '', g = 0, s = []; var T = '<strong style="background-color:lime">true</strong>'; var F = '<strong style="background-color:tomato">false</strong>'; var NA = '<strong style="background-color:fuchsia">N/A</strong>'; while (g++ < level) { indent += ' '; } try { var o = eval(objStr); s.push(indent + '<strong style="background-color:greenyellow">Interface ' + objStr +': ' + o + '</strong>'); s.push('<br />'); try { s.push(indent + objStr + '.prototype: ' + o.prototype); } catch (ex) { s.push(indent + '<strong style="background-color:coral">' + objStr + '.prototype: ' + ex.message + '</strong>'); } s.push('<br />'); s.push(indent + objStr + '.prototype.hasOwnProperty("XXX"): <br />'); var str = []; try { for (var i in o.prototype) { str.push(indent + '<em>' + i + '</em>: ' + ((o.prototype.hasOwnProperty(i)) ? T : F) + '<br />'); } } catch (ex) { } s.push(((str.length > 0) ? str.join('') : indent + NA)); } catch (ex) { s.push(indent + '<strong style="background-color:coral">Interface ' + objStr + ': ' + ex.message + '</strong>'); } s.push('<br /><br />'); return s.join(''); } var objHTMLDocument = ['Node', 'Document', 'HTMLDocument']; var objHTMLFormElement = ['Node', 'Element', 'HTMLElement', 'HTMLFormElement']; for (var i in objHTMLDocument) { $r(testDOMObject(objHTMLDocument[i], i)); } for (var i in objHTMLFormElement) { $r(testDOMObject(objHTMLFormElement[i], i)); } </script> </body> </html>
在各浏览器中运行上面代码之后可以得到:
IE6 IE7 IE8(Q) | IE8(S) | Firefox | Chrome Safari Opera | |
---|---|---|---|---|
Node 接口 | No | No | Yes | Yes |
Document 接口 | No | No | Yes | Yes |
Document 接口继承自 Node 接口 | No | No | No | Yes |
HTMLDocument 接口 | No | Yes | Yes | Yes |
HTMLDocument 接口继承自 Document 接口 | No | No | No | Yes |
Element 接口 | No | Yes | Yes | Yes |
Element 接口继承自 Node 接口 | No | No | No | Yes |
HTMLElement 接口 | No | No | Yes | Yes |
HTMLElement 接口继承自 Element 接口 | No | No | Yes | Yes |
HTMLFormElement 接口 | No | Yes | Yes | Yes |
HTMLFormElement 接口继承自 HTMLElement 接口 | No | No | No | Yes |
可见只有 Chrome Safari Opera 中,DOM 接口的继承关系遵照了 DOM 规范中的描述。
由于各浏览器中 DOM 接口实现的不一致性,这里建议应尽量避免修改浏览器脚本引擎内 DOM 接口的原生方法。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.9 Chrome 7.0.517.0 dev Safari 5.0.1 Opera 10.61 |
测试页面: |
get.html
inherit.html |
本文更新时间: | 2010-09-08 |
DOM Core HTML Document HTMLDocument Element interface inherit