web-dev-qa-db-ja.com

document.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を動的に生成および操作するために、それをfragment内に挿入します。

私の質問は、その文字列をfrag.innerHTMLに追加したら、この文字列をロードしてDOMオブジェクトに変換しないのですか?

InnerHTMLを設定した後、プロパティを介してDOMにアクセスできませんか?

私はfrag.childNodesを試しましたが、何も含まれていないようで、新しく作成したDOMにアクセスするだけです。

35
Loic Duros

あなたは ドキュメントフラグメントのinnerHTMLを設定することはできません 通常のノードと同じように、それが問題です。標準的なdivを追加してそのinnerHTMLを設定するのが一般的なソリューションです。

28
Johan

DocumentFragmentinnerHTMLをサポートしていませんが、<template>does

<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を作成する必要があります。

26
chowey

私はこの質問が古いことを知っていますが、divを追加し、divのinnerHTMLを使用してHTMLの文字列をロードする必要があることに気付かなかったため、ドキュメントフラグメントを操作しているときに同じ問題に遭遇しましたそこからDOM要素を取得します。 wholeドキュメントに適している、この種のことを行う方法について他の答えがあります。

Firefox(23.0.1)では、ドキュメントフラグメントのinnerHTMLプロパティを設定しても要素が自動的に生成されないようです。要素が作成されるのは、ドキュメントにフラグメントを追加した後のみです。

wholeドキュメントを作成するには、サポートされている場合は _document.implementation_ メソッドを使用します。私はFirefoxでこれを成功させることができましたが、他のブラウザーで実際にテストしたことはありません。 _document.implementation_メソッドの使用例については、AtropaToolboxの HTMLParser.js を参照してください。このスクリプトを使用してXMLHttpRequestページを操作し、ページを操作したり、ページからデータを抽出したりしました。ただし、ページ内のスクリプトは実行されません。これは、私が望んでいたことではないかもしれませんが、私が望んでいたことです。 XMLHttpRequestオブジェクトから直接利用できる解析を使用する代わりに、このかなり冗長なメソッドを使用した理由は、そのときに解析エラーでかなりのトラブルに遭遇し、 docはHTML 4 Transitionalとして解析する必要があります。これは、あらゆる種類のスローを取り、DOMを生成するように見えるためです。

DOMParser もあり、これを使用すると簡単です。 DOMParserがなくても_document.implementation.createHTMLDocument_をサポートしているブラウザー用のMDNのページにEli Grayによる実装があります。 DOMParserの仕様は、ページ内のスクリプトが実行されず、noscriptタグのコンテンツがレンダリングされることを指定しています。

ページでスクリプトを有効にする必要がある場合は、高さ0、幅0、境界線なしなどのiFrameを作成できます。これはページ内にありますが、かなりうまく隠すことができます。

_document.write_、DOMメソッドなど、window.open()を使用するオプションもあります。一部のブラウザーでは、データ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);
_

したがって、wholeドキュメントをオフスクリーン/非表示にして操作するためのいくつかのオプションがあります。これらのオプションはすべて、文字列からのドキュメントのロードをサポートします。

phantomjs もあり、webkitに基づいたヘッドレススクリプト対応Webブラウザーを作成する素晴らしいプロジェクトです。ローカルのファイルシステムにアクセスでき、好きなことがほとんどできるようになります。フルページのスクリプトと操作で何を達成しようとしているのか本当にわかりません。

5
Kastor

DocumentFragmentNode から継承します、ただし_.innerHTML_プロパティを含む Element からではありません。

あなたの場合、私は _<template>_ タグを使用します。はElementから継承し、DocumentFragmentを提供する気の利いた_HTMLTemplateElement.content_プロパティがあります。

使用できる簡単なヘルパーメソッドは次のとおりです。

_export default function StringToFragment(string) {
    var renderer = document.createElement('template');
    renderer.innerHTML = string;
    return renderer.content;
}
_
5
pekaaw

Firefoxアドオンの場合、おそらく document.implementation.createHTMLDocument メソッドを使用して、指定したDOMからアクセスします。

2
Gijs

ドキュメントフラグメントを使用して、document.createElement('yourElement')で作成した要素を追加します。 aWholeHTMLDocumentは単なるテキストです。また、フレームを使用しない限り、HTMLドキュメント全体を作成する必要がある理由がわからないので、<body>タグ内にあるものを使用するだけです。

1
qw3n

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);
0
Tony Jin