web-dev-qa-db-ja.com

RangeまたはDocumentFragmentを文字列に変換する

W3C準拠のブラウザでJavaScript範囲オブジェクトのhtml文字列を取得する方法はありますか?

たとえば、ユーザーが次を選択したとします。_Hello <b>World</b>_
Range.toString()メソッドを使用して、「HelloWorld」を文字列として取得することができます。 (Firefoxでは、documentgetSelectionメソッドを使用することもできます。)

しかし、内部HTMLを取得する方法を見つけることができないようです。

いくつか検索したところ、範囲をDocumentFragmentオブジェクトに変換できることがわかりました。

ただし、DocumentFragmentsにはinnerHTMLプロパティがありません(少なくともFirefoxでは、WebkitまたはOperaを試していません)。
これは私には奇妙に思えます。選択したアイテムにアクセスする方法があるはずです。

documentFragmentを作成し、ドキュメントフラグメントを別の要素に追加してから、その要素のinnerHTMLを取得できることに気付きました。
しかし、そのメソッドは、選択した領域内の開いているタグを自動的に閉じます。
それに加えて、文字列として取得するためだけにdomにアタッチするよりも、明らかな「より良い方法」があることは確かです。

では、RangeまたはDocFragのhtmlの文字列を取得する方法は?

23
SamGoody

いいえ、それが唯一の方法です。約10年前のDOMレベル2の仕様には、HTMLテキストとの間のノードのシリアル化と逆シリアル化に関してほとんど何もなかったため、innerHTMLのような拡張機能に依存する必要があります。

あなたのコメントについて

しかし、その方法では、選択した領域内の開いているタグがすべて自動的に閉じます。

...他にどのように機能しますか? DOMは、ツリーに配置されたノードで構成されています。 DOMからコンテンツをコピーすると、ノードの別のツリーのみを作成できます。要素ノードは、HTMLで開始タグ、場合によっては終了タグで区切られます。終了タグを必要とする要素のHTML表現には、終了タグが必要です。そうでない場合、有効なHTMLではありません。

4
Tim Down

FWIW、jQueryの方法:

$('<div>').append(fragment).html()
15
Brian M. Hunt

ここ から例を綴るには:

//Example setup of a fragment 
var frag = document.createDocumentFragment(); //make your fragment 
var p = document.createElement('p'); //create <p>test</p> DOM node
p.textContent = 'test';
frag.appendChild( p  ); 

//Outputting the fragment content using a throwaway intermediary DOM element (div):
var div = document.createElement('div');
div.appendChild( frag.cloneNode(true) );
console.log(div.innerHTML); //output should be '<p>test</p>'
10
yuvilio

これを行う別の方法は、childNodesを反復処理することです。

Array.prototype.reduce.call(
    documentFragment.childNodes, 
    (result, node) => result + (node.outerHTML || node.nodeValue),
    ''
);

インラインSVGでは機能しませんが、機能させるために何かを行うことができます。また、ノードを使用して連鎖操作をドーム化し、結果としてhtml文字列を取得する必要がある場合にも役立ちます。

2
waterplea

DocumentFragment.textContentはあなたに必要なものを与えることができますか?

var frag = document.createRange().createContextualFragment("Hello <b>World</b>.");

console.log(frag.textContent)
0
y.c