我正在创建一个文档片段如下:
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。
你和can't set the innerHTML of a document fragment一样,你会做一个正常的节点,这就是问题所在。添加标准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
做到这一点,例如:一个<div>
,因为<div>
不允许<tr>
元素作为孩子。
注意:DocumentFragment
仍将剥离<head>
和<body>
标签,因此它也不会做你想要的。你真的需要创建一个全新的Document
。
我知道这个问题很老,但我在玩文档片段时遇到了同样的问题,因为我没有意识到我必须在它上面添加一个div并使用div的innerHTML
来加载HTML字符串并获取DOM元素从中。关于如何做这类事,我有其他答案,更适合整个文档。
在firefox(23.0.1)中,似乎设置文档片段的innerHTML属性不会自动生成元素。只有在将片段附加到文档后才能创建元素。
要创建整个文档,请使用document.implementation
方法(如果它们受支持)。我在Firefox上取得了成功,但我还没有真正在其他浏览器上测试过。您可以在AtropaToolbox中查看HTMLParser.js,以获取使用document.implementation
方法的示例。我已经将这段脚本用于XMLHttpRequest
页面并操纵它们或从中提取数据。页面中的脚本不会执行,这是我想要的,虽然它可能不是你想要的。我使用这个相当冗长的方法而不是尝试直接使用XMLHttpRequest
对象提供的解析的原因是我在解析错误时遇到了相当多的麻烦,我想指定doc应该被解析为HTML 4 Transitional因为它似乎采取各种slop并产生DOM。
还有一个DOMParser
,可能更容易使用。 Eli Gray在MDN的页面上实现了没有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的无头可编写脚本的Web浏览器。您可以访问本地文件系统,并且可以随心所欲地执行任何操作。我真的不知道你要用整页脚本和操作来完成什么。
对于Firefox附加组件,使用document.implementation.createHTMLDocument
方法可能更有意义,然后从提供给您的DOM开始。
DocumentFragment
继承自Node
,但不是来自包含Element
财产的.innerHTML
。
在你的情况下,我会使用<template>
标签。继承自Element
,它有一个漂亮的HTMLTemplateElement.content
属性,给你一个DocumentFragment
。
这是一个你可以使用的简单助手方法:
export default function StringToFragment(string) {
var renderer = document.createElement('template');
renderer.innerHTML = string;
return renderer.content;
}
使用文档片段,您将附加使用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