Подтвердить что ты не робот

Используя document.createDocumentFragment() и innerHTML для управления DOM

Я создаю фрагмент документа следующим образом:

var aWholeHTMLDocument = '<!doctype html> <html><head></head><body><h1>hello world</h1></body></html>';
var frag = document.createDocumentFragment();
frag.innerHTML = aWholeHTMLDocument;

Переменная aWholeHTMLDocument содержит длинную строку, которая является всего html-документа страницы, и я хочу вставить ее внутри моего фрагмента, чтобы динамически генерировать и манипулировать dom.

Мой вопрос: как только я добавил эту строку в frag.innerHTML, не должен ли она загружать эту строку и преобразовывать ее в объект DOM? После установки innerHTML, не должен ли я иметь доступ к DOM через свойство? Я попробовал frag.childNodes, но он, кажется, ничего не содержит, и все, что я хочу, - это просто получить доступ к вновь созданной DOM.

4b9b3361

Ответ 1

Вы не можете установить innerHTML фрагмента документа, как если бы вы сделали с обычным node, что проблема. Добавление стандартного div и установка innerHTML этого общего решения.

Ответ 2

Я знаю, что этот вопрос старый, но я столкнулся с той же проблемой во время игры с фрагментом документа, потому что я не понимал, что мне нужно добавить div к нему и использовать div innerHTML для загрузки строк HTML и получить от него элементы DOM. У меня есть другие ответы о том, как это сделать, лучше подходит для целого документа.

В firefox (23.0.1) кажется, что установка свойства innerHTML фрагмента документа не генерирует автоматически элементы. Только после добавления фрагмента в документ создаются элементы.

Чтобы создать документ целое, используйте методы document.implementation, если они поддерживаются. У меня был успех в Firefox, но я не проверял его на других браузерах. Вы можете посмотреть HTMLParser.js в AtropaToolbox для примера использования методов document.implementation. Я использовал этот бит script для XMLHttpRequest страниц и манипулировал ими или извлекал из них данные. Скрипты на странице не выполняются, хотя это то, что я хотел, хотя это может быть не то, что вы хотите. Причина, по которой я пошел с этим довольно подробным методом вместо того, чтобы пытаться использовать синтаксический анализ, доступный непосредственно из объекта XMLHttpRequest, заключалась в том, что я столкнулся с довольно сложной ситуацией при анализе ошибок в то время, и я хотел указать, что документ должен быть анализируется как HTML 4 Transitional, потому что он, кажется, принимает все виды slop и создает DOM.

Существует также DOMParser, который может быть проще для вас использовать. Существует реализация Эли Грей на странице в MDN для браузеров, у которых нет DOMParser, но поддержка document.implementation.createHTMLDocument. Спецификации для DOMParser указывают, что сценарии на странице не выполняются, и содержимое тегов noscript будет отображаться.

Если вам действительно нужны сценарии, включенные на странице, вы можете создать iFrame с 0 высотой, шириной 0, без границ и т.д. Это все равно будет на странице, но вы можете скрыть это довольно хорошо.

Также существует возможность использования window.open() с document.write, методами DOM или любым другим, что вам нравится. Некоторые браузеры даже позволяют вам выполнять URI данных.

var x = window.open( 'data:text/html;base64,' + btoa('<h1>hi</h1>') );
// wait for the document to load. It only takes a few milliseconds
// but we'll wait for 5 seconds so you can watch the child window
// change.
setTimeout(function () {
    console.log(x.document.documentElement.outerHTML);
    x.console.log('this is the console in the child window');
    x.document.body.innerHTML = 'oh wow';
}, 5000);

Итак, у вас есть несколько вариантов для создания целого документов за кадром/скрытыми и манипулирования ими, все из которых поддерживают загрузку документа из строк.

Там также phantomjs, удивительный проект, создающий безгласный скриптовый веб-браузер на основе webkit. У вас будет доступ к локальной файловой системе и вы сможете делать все, что захотите. Я действительно не знаю, что вы пытаетесь выполнить с помощью полного скриптинга страниц и манипуляций.

Ответ 3

Для дополнения Firefox, вероятно, имеет смысл использовать метод document.implementation.createHTMLDocument, а затем перейти от DOM, который дает вы.

Ответ 4

С фрагментом документа вы добавите элементы, созданные с помощью document.createElement('yourElement'). aWholeHTMLDocument - это просто текст. Кроме того, если вы не используете фреймы, я не уверен, зачем вам нужно создавать весь HTML-документ, просто используйте то, что находится внутри тегов <body>.

Ответ 6

Пока DocumentFragment не поддерживает innerHTML, <template> делает.

Свойством content элемента <template> является DocumentFragment, поэтому он ведет себя одинаково. Например, вы можете:

var tpl = document.createElement('template');
tpl.innerHTML = '<tr><td>Hello</td><td>world</td></tr>';
document.querySelector('table').appendChild(tpl.content);

Приведенный выше пример важен, потому что вы не могли сделать это с помощью innerHTML и, например, a <div>, так как a <div> не позволяет элементам <tr> как детям.


ПРИМЕЧАНИЕ. A DocumentFragment по-прежнему будет стирать теги <head> и <body>, поэтому он не будет делать то, что вы хотите. Вам действительно нужно создать совершенно новый Document.

Ответ 7

Используйте querySelector(), чтобы получить дочерний элемент фрагмента документа (вы, вероятно, хотите, чтобы тело или какой-либо дочерний элемент тела). Затем получите innerHTML.

document.body.innerHTML = aWholeHTMLDocument.querySelector("body").innerHTML

или

aWholeHTMLDocument.querySelector("body").childNodes;

См. https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment.querySelector