использование документа.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 через собственность? Я попробовал фраг.childNodes, но он, похоже, ничего не содержит, и все, что я хочу, это просто получить доступ к недавно созданному DOM.

7 ответов


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


пока 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>, потому что <div> не дает <tr> элементы, как дети.


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


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

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

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

также DOMParser доступно, что может быть проще для вас использовать. На странице MDN есть реализация Eli Grey для браузеров, у которых нет 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. У вас будет доступ к локальной файловой системе и вы сможете делать практически все, что захотите. Я действительно не знаю, чего вы пытаетесь достичь с помощью сценариев и манипуляций с полной страницей.


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


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


использовать appendChild

см https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment

var fragment = document.createDocumentFragment();
... fragment.appendChild(some element);
document.querySelector('blah').appendChild(fragment);

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

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

или

aWholeHTMLDocument.querySelector("body").childNodes;

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