为什么在“新文档”下创建的元素包含错误的原型?

问题描述 投票:11回答:2

创建div时,它是HTMLDivElement的一个实例:

var d = document.createElement('div');
d instanceof HTMLDivElement; // true
d instanceof Element; // true

获取外部文档和窗口时也是如此:

var frame = document.createElement('iframe');
document.body.appendChild(frame);
var doc2 = frame.contentWindow.document;
var d2 = doc2.createElement('div');
d2 instanceof frame.contentWindow.HTMLDivElement; // true
d2 instanceof Element; // false, different realm/dom

我尝试使用Document构造函数创建一个文档来处理外部HTML文档:

var doc = new Document();
var d = doc.createElement('div');
d instanceof Element; // true

因此,它创建了元素,元素与我们所处的元素处于同一领域。但令我惊讶的是它没有键入其元素:

d instanceof HTMLDivElement; // false
d.constructor.name; // "Element"

为什么这样,为什么当前文档创建类型元素而新文档只创建Element

javascript html dom
2个回答
13
投票

Document构造函数不是特定于HTML(因为有XML文档),你需要构造一个HTMLDocument,但它的构造函数是不可调用的。

正如评论所提到的,创建文档的正确方法是通过DOMImplementation#createHTMLDocument方法。

var doc = document.implementation.createHTMLDocument();
var d = doc.createElement('div');
d instanceof Element; // true;
d instanceof HTMLDivElement; // true
d.constructor.name; // "HTMLDivElement"

从我可以收集的内容来看,在某些时候,将通用文档(HTML和XML共享)分离为两个不同的构造函数。同样的机会,他们使新的构造函数不可调,并添加了.createDocument()(用于XML)和.createHTMLDocument()(用于HTML)方法。


5
投票

因为你有一个Document而不是HTMLDocument的实例,所以它会创建一个Element,而不是一个HTMLElement。文档和元素是所有文档类型共享的基本接口。 EG一个HTMLDocument将创建一个HTMLElement。

来自MDN,

Document接口描述了任何类型文档的公共属性和方法。根据文档的类型(例如HTML,XML,SVG,...),可以使用更大的API:HTML文档(使用“text / html”内容类型)也实现HTMLDocument接口,而XML和SVG文档实现XMLDocument接口。

Element是最常用的基类,Document中的所有对象都从该基类继承。它只有各种元素共有的方法和属性。更具体的类继承自Element。例如,HTMLElement接口是HTML元素的基本接口,而SVGElement接口是所有SVG元素的基础。大多数功能在类层次结构中进一步指定。

您可能希望使用DOMImplementation.createHTMLDocument()来创建HTML文档。

© www.soinside.com 2019 - 2024. All rights reserved.