Ответ 1
Вы не можете установить innerHTML фрагмента документа, как если бы вы сделали с обычным node, что проблема. Добавление стандартного div и установка innerHTML этого общего решения.
Я создаю фрагмент документа следующим образом:
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.
Вы не можете установить innerHTML фрагмента документа, как если бы вы сделали с обычным node, что проблема. Добавление стандартного div и установка innerHTML этого общего решения.
Я знаю, что этот вопрос старый, но я столкнулся с той же проблемой во время игры с фрагментом документа, потому что я не понимал, что мне нужно добавить 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. У вас будет доступ к локальной файловой системе и вы сможете делать все, что захотите. Я действительно не знаю, что вы пытаетесь выполнить с помощью полного скриптинга страниц и манипуляций.
Для дополнения 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);
Пока 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
.
Используйте querySelector(), чтобы получить дочерний элемент фрагмента документа (вы, вероятно, хотите, чтобы тело или какой-либо дочерний элемент тела). Затем получите innerHTML.
document.body.innerHTML = aWholeHTMLDocument.querySelector("body").innerHTML
или
aWholeHTMLDocument.querySelector("body").childNodes;
См. https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment.querySelector