Почему элементы, созданные в «новом документе», содержат неправильный прототип? - PullRequest
11 голосов
/ 23 апреля 2019

При создании 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?

Ответы [ 2 ]

13 голосов
/ 23 апреля 2019

Конструктор 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 голосов
/ 23 апреля 2019

Поскольку у вас есть экземпляр Document, а не HTMLDocument, он создаст элемент, а не HTMLElement. Document и Element являются базовыми интерфейсами для общего доступа для всех типов документов. Например, HTMLDocument создаст HTMLElement.

от MDN,

Интерфейс Document описывает общие свойства и методы для любого типа документа. В зависимости от типа документа (например, HTML, XML, SVG,…), доступен более широкий API: документы HTML, обслуживаемые с типом контента «text / html», также реализуют интерфейс HTMLDocument, тогда как документы XML и SVG реализуют XMLDocument интерфейс.

Элемент - это самый общий базовый класс, от которого наследуются все объекты в документе. Он имеет только методы и свойства, общие для всех видов элементов. Более конкретные классы наследуются от Element. Например, интерфейс HTMLElement является базовым интерфейсом для элементов HTML, в то время как интерфейс SVGElement является основой для всех элементов SVG. Большая часть функций указана ниже по иерархии классов.

Возможно, вы захотите использовать DOMImplementation.createHTMLDocument() для создания HTML-документа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...