jQuery の .html(htmlString) を呼ぶ際、コメント部にタグの文字列が入っていると、余計なタグが付与されてしまう場合がある
以下のコードで再現する。
result1
と result2
は、いずれも tr タグの配下に td タグを追加するものだが、
result2
のほうは tr が余計に付いている。
var result1 = $('<tr></tr>').html('<td>hoge</td>'); console.log(result1.html()); // => <td>hoge</td> var result2 = $('<tr></tr>').html('<!--<tr>--><td>hoge</td>'); console.log(result2.html()); // => <!--<tr>--><tr><td>hoge</td></tr>
html()
は innerHTML 相当なので、 result2
は tr が二重になってしまう。
例えば、上記の結果を table タグに append
したりすると、以下のようになる。
console.log($('<table></table>').append(result1).html()); // => <tbody><tr><td>hoge</td></tr></tbody> console.log($('<table></table>').append(result2).html()); // => <tbody><tr><!--<tr>--><tr><td>hoge</td></tr></tr></tbody> // ^^^^ ^^^^ // tr タグが二重になっている
結論は「コメントに変なものを書かないようにしましょう」でいいのかな…*1
ところで、以下の例ではこの問題は発生しない。 親要素と同じタグが、コメントに含まれている場合だけ発生するのだろうか…
var result3 = $('<tr></tr>').html('<!--<table>--><td>hoge</td>'); console.log(result3.html()); // => <!--<table>--><td>hoge</td>
参考: .html() | jQuery API Documentation
追記: バージョン書くの忘れてた
- jQuery 2.1.4
- Google Chrome 42.0.2311.135 (64-bit) (Mac OS X 10.10.3)
以下蛇足
この問題は、 JavaScript エンジニア養成読本という書籍の Backbone.js 入門を写経しているときに遭遇したもの。
JavaScriptエンジニア養成読本 [Webアプリ開発の定番構成Backbone.js+CoffeeScript+Gruntを1冊で習得! ] (Software Design plus)
- 作者: 吾郷協,山田順久,竹馬光太郎,和智大二郎
- 出版社/メーカー: 技術評論社
- 発売日: 2014/10/18
- メディア: 大型本
- この商品を含むブログ (3件) を見る
第 6 章で、ノートアプリの一覧表示を動作確認するのだが、図 4 に比べて、テーブルがおかしい。 tbody の行が左寄りになっている。
(確認用に、罫線が見えるよう table-bordered クラスを指定している)
- インスペクタで見ると、 tr タグが二重になっているようだ…
- デバッガで、 note_list_item.js の render メソッドにブレークポイントを設定し、 return 直前のときの各変数を調べてみる。
- ローカル変数
html
の中身は、まだ tr タグが付いていないようだ。 - しかし、
this
のプロパティを調べていくと、el.outerHTML
というプロパティがあり、これは tr タグが二重になってしまっている (下記画像の下部、 Console の内容からわかる) 。 this.$el.html(html)
の呼び出し時に、 tr タグが 1 個だけ付くべきなのに、 2 個になってしまっているのか?
- ローカル変数
this.$el.html(html)
ではテンプレート HTML を渡している。
最初に使用していたテンプレート HTML
<script type="text/template" id="noteListItemView-template"> <!-- 個々のメモ情報を表示する<tr>要素のためのテンプレート <tr>要素自体はBackbone.Viewが生成する --> <td> <a href="#"> ... (以下略)
*1:仕様なのかバグなのかもわかってない