[メモ] 断片的なHTMLからjQueryセレクタで要素を取り出すときの注意

何気なくハマったのでメモ

そもそも書き方が乱暴という節はありますが、実際ハマってしまって「?」ってなったので、メモエントリー。

断片的な、そもそも単体でHTMLとして成立していないような文字列から、要素を取り扱う場合の注意書きです。横着しない限り、そうそうあるような話ではありませんが。

断片的なHTMLからセレクタで要素を取り出そうとすると...

断片的なHTML ( fragment.html ) を、仮に下記のようなファイルとします。

<div id="hoge">hoge</div>
<div id="fuga">fuga</div>
<div id="hige">hige</div>

<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="bar">bar</div>

これを、以下のように、jQueryでファイルをgetした後に、文字列中からセレクタで要素を選択しようとします。

空のオブジェクトが返ってしまう

$.get('/fragment.html', function(html)
{
    // 空のjQueryオブジェクトが返る
    console.log($('.foo', html));
});

すると空のオブジェクトが返ってきてしまいます。これはクラス以外の、#hogeなどのセレクタでも同様の結果が得られます。

適当な要素で、断片をラップするとOK

$.get('/fragment.html', function(html)
{
    // 適当にラップすると中身の入ったjQueryオブジェクトが返る
    console.log($('.foo', '<div>'+html+'</div>'));
});

これを何かしらの要素(意味はないのでdiv要素やhtml要素が妥当でしょう)でラップすると、中身の入ったjQueryオブジェクトが返り、期待通りの結果が得られます。

ラップしないと、各要素がルート要素扱い?

おそらく、文字列全体のルートに各要素が並んでいた状態なので、それぞれがルート要素のような扱いを受けているんじゃないかと。

通常のHTMLドキュメントであれば、html要素に相当する部分は、document.documentElementなどで取得できますが、今回のような場合は素直にラップしてjQueryセレクタで取得できるようにしたほうが良さそうです。