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

时间:2019-04-23 13:35:16

标签: javascript html dom

创建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

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

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

为什么?为什么当前文档会创建类型化元素,而新文档仅创建Element

2 个答案:

答案 0 :(得分: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)方法。

答案 1 :(得分:5)

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

从MDN,

  

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

     

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

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