W3C準拠のブラウザでJavaScript範囲オブジェクトのhtml文字列を取得する方法はありますか?
たとえば、ユーザーが次を選択したとします。_Hello <b>World</b>
_Range.toString()
メソッドを使用して、「HelloWorld」を文字列として取得することができます。 (Firefoxでは、documentのgetSelection
メソッドを使用することもできます。)
しかし、内部HTMLを取得する方法を見つけることができないようです。
いくつか検索したところ、範囲をDocumentFragment
オブジェクトに変換できることがわかりました。
ただし、DocumentFragments
にはinnerHTML
プロパティがありません(少なくともFirefoxでは、WebkitまたはOperaを試していません)。
これは私には奇妙に思えます。選択したアイテムにアクセスする方法があるはずです。
documentFragment
を作成し、ドキュメントフラグメントを別の要素に追加してから、その要素のinnerHTML
を取得できることに気付きました。
しかし、そのメソッドは、選択した領域内の開いているタグを自動的に閉じます。
それに加えて、文字列として取得するためだけにdomにアタッチするよりも、明らかな「より良い方法」があることは確かです。
では、RangeまたはDocFragのhtmlの文字列を取得する方法は?
いいえ、それが唯一の方法です。約10年前のDOMレベル2の仕様には、HTMLテキストとの間のノードのシリアル化と逆シリアル化に関してほとんど何もなかったため、innerHTML
のような拡張機能に依存する必要があります。
あなたのコメントについて
しかし、その方法では、選択した領域内の開いているタグがすべて自動的に閉じます。
...他にどのように機能しますか? DOMは、ツリーに配置されたノードで構成されています。 DOMからコンテンツをコピーすると、ノードの別のツリーのみを作成できます。要素ノードは、HTMLで開始タグ、場合によっては終了タグで区切られます。終了タグを必要とする要素のHTML表現には、終了タグが必要です。そうでない場合、有効なHTMLではありません。
FWIW、jQueryの方法:
$('<div>').append(fragment).html()
ここ から例を綴るには:
//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>'
これを行う別の方法は、childNodesを反復処理することです。
Array.prototype.reduce.call(
documentFragment.childNodes,
(result, node) => result + (node.outerHTML || node.nodeValue),
''
);
インラインSVGでは機能しませんが、機能させるために何かを行うことができます。また、ノードを使用して連鎖操作をドーム化し、結果としてhtml文字列を取得する必要がある場合にも役立ちます。
DocumentFragment.textContentはあなたに必要なものを与えることができますか?
var frag = document.createRange().createContextualFragment("Hello <b>World</b>.");
console.log(frag.textContent)