использование документа.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