$("div").append("section") できないらしいので色々調べてみた

追記: jQ的には解決していませんが、素の JavaScript を使った回避方法がわかりました。IE8以下では、オンザフライで作成した要素に対して innerHTML すると謎要素が作成されてしまうといった現象がでるため、一度要素片を、DOMツリー( body とかね ) にぶらさげてから innerHTML すると回避できました。

つまり、オンザフライな↓ではだめで…
var div = document.createElement("div"); // 作る
div.innerHTML = "<section>ほげー</section>"; // 突っ込む → ι(´Д`υ)

↓のようにすると謎の挙動を回避できます。
var div = document.createElement("div"); // 作る
document.body.appendChild(div); // あてがう
div.innerHTML = "<section>いけたー</section>"; // 突っ込む → ヽ(・ω・)ゝ 

createDocumentFragment() を使っても、オンザフライなノードに突っ込むと、同様に謎の挙動が発生します。

node.cloneNode() は、nodeがオンザフライかどうかに関わらず、謎の <:section> ノードを生成するため、
CSSを適用したい場合は、
section { ... } と記述するだけだとだめで、
section, \:section { ... } と併記する必要があります。 \:section を併記すると IE8 でスタイルが適用されます(IE6, IE7 では適用されません)。

文章で書くとよくわからないと思いますがコードにすると↓こんな感じです。

<!DOCTYPE html><html lang="ja"><head><meta charset="utf-8" />
<title></title></head><body>
<style>
section    { color:blue;outline:2px solid blue }
\:section  { color:pink;outline:2px solid pink } /* IE8で<:section>に適用される, IE6, IE7には適用されない */
\\:section { color:red; outline:2px solid red  } /* IE6, IE7, IE8 には適用されない */
</style>

<script>
document.createElement("section"); // HTML5 siv

var div = document.createElement("div"); // 作る
div.innerHTML = "<section>ほげー</section>";
document.body.appendChild(div); // あてがう → ι(´Д`υ)

var div2 = document.createElement("div"); // 作る
document.body.appendChild(div2); // あてがう
div2.innerHTML = "<section>いけたー</section>";  // ヽ(・ω・)ゝ 

var div3 = div2.cloneNode(true);
document.body.appendChild(div3);
alert(div3.outerHTML); // ※

// ※
// IE9              では <div><section>いけたー</section></div>
// IE8              では <DIV><:section>いけたー</:section></DIV>
// IE7              では <DIV><:section>いけたー</:section></DIV>
// IE6              では <DIV><:section>いけたー</:section></DIV>
// IE9(IE7互換mode) では <DIV><section>いけたー</section></DIV>
// IE9(IE8互換mode) では <DIV><section>いけたー</section></DIV>
</script>
</body></html>

IE9IE7,IE8 互換モードは実際の IE7,IE8 と細かな挙動が異なるのです、いっぱいあって説明する時間も気力もないのですが、ひとつ言えることは、「HTML5 に対応しました。(IE9 の互換モードで)確認もしました(ドヤ)」する人は、もれなく罠にはまるといいよ!

ここまで追記

ここから本文

@hokaccha さんのツイートを見て気になったので、

$('div').append('

hoge
'); とかしたときIEでstyleが効かなくなる件jQuery1.5になったら対応してくれるかなと思ったけど、試してみたらダメだった。

http://twitter.com/hokaccha/statuses/34258257182724098

IE6〜IE8 で HTML5 で追加された新要素(この場合は section) を jQuery で追加するとスタイルが適用されない問題があるらしい。

jQuery で試してみた

jQuery の最新版(1.5)で http://jsdo.it/uupaa/createHTML5ElementByjQuery 試してみた。

<script>
var css = "div{border-top:1px solid blue}";

document.createElement("section"); // HTML5 shiv

$(function() {
    $("head").append("<style>" + css + "</style>");
    $("div").append("<section>section</section>");
});
</script>
<style>
section,
\:section {
    display:block;border-top:1px solid red
}
</style>
<div>div</div>
<div>div</div>

uupaa.js で試してみた

uupaa.js の最新版で http://jsdo.it/uupaa/createHTML5ElementByuu 試してみた。

<script>
var css = "div{border-top:1px solid blue}";

uu.ready(function() {
    uu.head(uu.style(css));
    uu("div").add(uu.section("section"));
});
</script>
<style>
section,
\:section {
    display:block;border-top:1px solid red
}
</style>
<div>div</div>
<div>div</div>

IEのinnerHTMLとcloneNodeの不具合を調査している時に、

IE6〜IE8で(

).cloneNode(true)で生成せした要素にスタイルが当たらなくなるのは、 クローンで作成したノードがチラ見だと
にみえて実は<:section>要素になっているため。

http://twitter.com/#!/uupaa/status/34544812854091776

      • -

jsからは

のようにみえて、実はouterHTMLすると<:section>なので、CSSが当らないし、IEは仲間を呼んだ。爆弾岩が現れた。IEはぱるぷんてを唱えた。みたいなDOMツリーになる

http://twitter.com/#!/uupaa/status/34545606823256064

      • -

cloneNode()せずにNodeの属性を正確に素早くコピーする方法はない。cloneNodeすると

が<:section>になる。outerHTMLに"hoge"突っ込むとDOMツリーの親子関係ぶっこわれ3つのノードができる。手詰まり

http://twitter.com/#!/uupaa/status/34555491514322944

      • -

IE

.cloneNode() した要素にCSSを当てるには \:section { display:block;border-top:1px solid red } のように \:section な感じで先頭にバクスラでエスケープいれればOK

http://twitter.com/#!/uupaa/status/34562498577309696

と色々と無駄知識が手に入ったので、
このデモでは、CSSに section と一緒に \:section を併記し、ライブラリ内部でcloneNodeされている要素にもスタイルが適用されるようにしてあります(結局逃げてますが)。

実行結果

IE8 + jQuery

画面表示
DOMツリー

IE8 + uupaa.js

画面表示
DOMツリー

jQueryの場合、画像のように DOM ツリー構造がそもそも壊れちゃってて、

<div>
  文字列
  <section>
  文字列
  </section>
</div>

のように、本来は2つあれば十分なはずの div 要素の子要素が4つもある。
この状態だとスタイルも適用されなかったんだけど…

どうせ、皆さんが使っているjQuery使えば対策済みですから大丈夫ですよ

HTML5の新要素をinnerHTMLで生成できないバグを回避する - latest log http://htn.to/9wkfZg

http://twitter.com/#!/ofk/status/34472957216555008

ってブクマが今朝のエントリに書かれてたのが気になる。
何か特別な方法があるのかもしれないんだけど、jQユーザではないのでよくわからず。

uupaa.js でも、コードを一部入れ替えると、jQueryのように壊れたDOMツリーが生成されてしまう。

 // uu("div").add(uu.section("section"));        // cloneNode でノードをノードとしてコピーする
    uu("div").add("<section>section</section>"); // innerHTML でノードを文字列としてコピーする

uu.section() でノードを作る場合は、内部で cloneNode が走るので被害を最小限にできるんだけど、
uu.node("

section
") や uu.add() でノードをつくると、内部で innerHTML が走ってしまい、innerHTML の副作用で親子関係が維持されず div の子要素が4つになってしまう。

今のところ、innerHTML で親子関係が崩れる問題をどうにかする良い方法は見つかってない。IE6〜IE8のバグ由来の仕様という認識。

お願い

uupaa.jsで、HTML5で追加された要素を作成する時は、uu.add("

...
") や uu().add("") のように文字列から生成せず、uu.section() や uu.aside() など、予め用意されたノード生成関数で生成し、IEのバグを回避してください。

その際に、CSS には \:section や \:aside など cloneNode で生成される特殊な要素に対するスタイルも併記してください。
よろしくお願いします。

CSSの\:sectionの話については、こちらをどうぞ http://jsdo.it/uupaa/IEcloneNodeBug (HTML5の新要素をcloneNodeするとCSSが適用されないバグを対策する)