javascript 使用document.createDocumentFragment()和innerHTML来操作DOM

eoxn13cs  于 2023-01-16  发布在  Java
关注(0)|答案(9)|浏览(219)

我正在创建一个文档片段,如下所示:

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

变量aWholeHTMLDocument包含一个长字符串,它是页面的整个html文档,我想将它插入到我的 fragment 中,以便动态地生成和操作DOM。
我的问题是,一旦我将该字符串添加到frag.innerHTML中,它是否应该加载该字符串并将其转换为DOM对象?
设置innerHTML之后,我不应该通过属性访问DOM吗?
我尝试了frag.childNodes,但它似乎不包含任何内容,我所需要的只是访问新创建的DOM。

qrjkbowd

qrjkbowd1#

虽然DocumentFragment不支持innerHTML,但<template> * 支持 *。
<template>元素的content属性是DocumentFragment,因此其行为相同。例如,您可以执行以下操作:

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

上面的例子很重要,因为你不能对innerHTML<div>这样做,因为<div>不允许<tr>元素作为子元素。

注意:DocumentFragment仍然会剥离<head><body>标记,因此它也不会执行您想要的操作。您确实需要创建一个全新的Document

n8ghc7c1

n8ghc7c12#

can't set the innerHTML of a document fragment就像你处理一个普通节点一样,这就是问题所在,添加一个标准的div并设置它的innerHTML是常见的解决方案。

gab6jxml

gab6jxml3#

DocumentFragment继承自Node,但不继承自包含.innerHTML属性的Element
在您的情况下,我将使用<template>标记。In继承自Element,它有一个漂亮的HTMLTemplateElement.content属性,可以为您提供DocumentFragment
下面是一个简单的helpermethod,你可以用途:

export default function StringToFragment(string) {
    var renderer = document.createElement('template');
    renderer.innerHTML = string;
    return renderer.content;
}
ecfdbz9o

ecfdbz9o4#

我知道这个问题很老了,但是我在处理文档片段时遇到了同样的问题,因为我没有意识到我必须向它附加一个div,并使用div的innerHTML来加载HTML字符串并从中获取DOM元素。我有其他答案来解决这类问题,更适合于整个文档。
在firefox(23.0.1)中,设置文档片段的innerHTML属性并不会自动生成元素,只有在将片段附加到文档中之后,元素才会被创建。
要创建一个完整的文档,请使用document.implementation方法(如果支持的话)。我在Firefox上已经成功地做到了这一点。不过我还没有在其他浏览器上测试过,你可以在AtropaToolbox中的HTMLParser.js中找到一个使用document.implementation方法的例子,我已经用这个脚本来处理XMLHttpRequest页面,并从中提取数据。但是不执行页面中的脚本,这是我想要的,虽然可能不是你想要的我之所以使用这个相当冗长的方法,而不是尝试直接使用XMLHttpRequest对象提供的解析,是因为当时我遇到了很多解析错误,我想指定文档应该解析为HTML 4 Transitional因为它似乎接受了所有类型的溢出并生成了一个DOM。
还有一个DOMParser可能更容易使用。在MDN的页面上有一个Eli Grey的实现,用于没有DOMParser但支持document.implementation.createHTMLDocument的浏览器。DOMParser的规范指定页面中的脚本不执行,noscript标记的内容被呈现。
如果你真的需要在页面中启用脚本,你可以创建一个0高,0宽,没有边框等的iFrame。它仍然会在页面中,但你可以很好地隐藏它。
也可以选择将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的无头脚本网页浏览器,你可以访问本地文件系统,并且可以做你想做的任何事情,我真的不知道你想用你的整个页面脚本和操作来完成什么。

jei2mxaa

jei2mxaa5#

对于Firefox附加组件,使用document.implementation.createHTMLDocument方法可能更有意义,然后从提供的DOM开始。

txu3uszq

txu3uszq6#

对于一个文档片段,你可以添加你用document.createElement('yourElement')创建的元素。aWholeHTMLDocument仅仅是文本。另外,除非你使用框架,否则我不确定你为什么需要创建整个HTML文档,只要使用<body>标签中的内容。

chhkpiq4

chhkpiq47#

使用 * 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);
qoefvg9y

qoefvg9y8#

下面是将HTML字符串转换为DOM对象的解决方案:

let markup = '<!doctype html><html><head></head><body><h1>hello world</h1></body></html>';
let range = document.createRange();
let fragment = range.createContextualFragment(markup); //Creates a DOM object

字符串不需要是完整的HTML文档。

iugsix8n

iugsix8n9#

使用querySelector()获取文档片段的一个子元素(您可能需要正文,或者正文的某个子元素),然后获取innerHTML。

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

aWholeHTMLDocument.querySelector("body").childNodes;

参见https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment.querySelector

相关问题