もどる TOP

[JavaScript] 文字列をDOM要素に変換する

 素のJavaScriptでHTMLの文字列をDOM要素に変換する方法を考え中。引数にテンプレートリテラルを突っ込んでいっぺんに作れるのが理想。

 今のところこんな感じ。要素がいくつだろうと戻りは必ず配列になる。

2017/11/19更新
function stringToDOMElements(str) {
	str = str.replace(/[\r\n\t]/g, '');
	var tmpTag = 'div';
	var m = str.match(/^<([a-zA-Z]+)[ >]/);
	if (m !== null && m[1] !== undefined) {
		if (m[1] == 'tr') {
			tmpTag = 'tbody';
		}
	}
	var tmpElem = document.createElement(tmpTag);
	tmpElem.innerHTML = str;
	return Array.prototype.slice.call(tmpElem.childNodes);
}

// テンプレートリテラルを引数にした使用例
var elems = stringToDOMElements(`<ul>
	<li>ほにゃ</li>
	<li>ふにゃ</li>
</ul>
<div>へにゃ</div>`);

console.log(elems[0].firstElementChild.innerHTML); // ほにゃ
console.log(elems[1].innerHTML); // へにゃ

 やや奇怪な感じになってしまったので以下経緯。

 最初に改行コードとタブ文字を除去してるのは、文字列状態での要素間の改行コードやタブが、最後にchildNodesで取得した時にテキストノード扱いされてしまったから。

 次に、innerHTMLで突っ込むために一時的に生成している親要素を、divtbodyで使い分けてるところ。。。これはtr要素を作らせようとしたら、divの下にいきなりinnerHTMLで突っ込んだところ、おそらく文法エラーでtrが作れなかったから (Chromeではundefinedになってしまった。ほかブラウザでは未確認)。なので先頭の要素がtrのときだけ親をtbodyにしてる。なお、先頭以外でやはりいきなり変なところにtrを作成しようとしたら、Chromeではテキストノードにされた。そもそも変な文法がNGだから、これはフォローしてない。

 最後に、childNodesで取得したものをArray.prototype.slice.callで配列に変換してるところ。これは、childNodesの戻りがNodeListのままだと、forでほかの要素にひとつずつappendChildしたときに消えていってしまって困ったから。

サイドバーを表示する
ブログ
ShortCircuit
ShortCircuit
花火大会
天使
去る512時間前、キリウ君は折れてない千歳飴を渡してきて、ぼくが折るよう仕向けた。1024時間前、彼はこの世のものではないハッシュアルゴリズムでひとりブロックチェーンを始めていた。