IE+jQueryでHTML5新要素のDOM操作

jQueryのprepend(), append(), appendTo(), before(), after(), html(), wrap(), wrapInner(), wrapAll()など、指定のセレクタに対してオブジェクトを操作できるメソッドを用いてHTML5の新要素を操作する際は、現行MicrosoftからリリースされているIE8までのバージョンでは、HTML5の新要素が認識できないので注意が必要です。

この罠に嵌ることが想定される事態

HTML5でリニューアルされているサイトが散見されるようになってきた今日この頃ですが、表題の問題で混乱が起こることが想定される事態としては、事前にHTML5の新要素群をdocument.createElement()で作成済みなので、「よし、これでjQueryでもHTML5の新要素群が操作できる!」と思い込んでしまうところに罠が潜んでいます。つまり、jQueryでの操作の際には、IE6~8にはHTML5の新要素群が認識できていないのです。では、どうすれば?ということで、解決のアプローチを!

ネイティブのDOM操作と組み合わせる

ネイティブっていうのは、JavaScriptのことを指します。HTML5の新要素群が認識できないIE6~8のようなブラウザに対しては、jQueryのメソッドを使うのではなく、ネイティブのJavaScriptでのDOM操作を上手く組み合わせてあげる必要があります。では作例を。

var testSection = document.createElement('section');
testSection.id = "test";
document.getElementById('追加したい部分のID名').appendChild(testSection);
$('#test').html('これで安心してjQueryでも操作できるよ!');

まず最初に追加したいHTML5の新要素は、document.createElement('ここに追加したいHTML5の要素名')で作成しておいてあげる必要があります。これを変数に格納し、加えてDOM操作がしやすいようにID名も付与(先の変数名.id="ID名")しておいてあげます。あとは追加したいところに対して、appendChild等で追加します。最後の$('#test')の行にはjQueryの書式を用いているように、この流れで追加してあげたHTML5の新要素については、IE6~8+jQueryでも操作することができます。

ですが、これだけでは万事がOKとは中々いかないですよね。ネイティブのJavaScriptのDOM操作であるappendChild()だと追加したい要素の子ノードリストの末尾にしか追加できないため、他にも要素を追加されていると、順番がうまく制御できません。では、もう少しネイティブのJavaScriptで追加したい場所の選択肢を広げられる方法を模索してみましょう。

追加できる場所の選択肢を広げる

jQueryだと、prepend(), append(), appendTo(), before(), after()などDOM操作は自由自在で、こういう時にこそ、jQueryの偉大さを痛感します。普段、jQueryでDOMを操作している人が、ネイティブのJavaScriptでDOMを操作するとなると不便を感じますが、近しいことができるように以下にいくつかのアプローチ例を示します。

対象ノードの前に挿入する場合

var testSection = document.createElement('section');
testSection.id = "test";
var target = document.getElementById('追加したい部分のID名');
target.parentNode.insertBefore(testSection, target);
$('#test').html('これで安心してjQueryでも操作できるよ!');

これでjQueryのbefore()と同様のことが実現できます。

子ノードの先頭に挿入する場合

var testSection = document.createElement('section');
testSection.id = "test";
var target = document.getElementById('追加したい部分のID名');
target.insertBefore(testSection, target.firstChild);
$('#test').html('これで安心してjQueryでも操作できるよ!');

末尾に追加するappendChild()とは反対で、これでjQueryのprepend()と同じ先頭に追加させることが実現できます。

対象ノードの後に挿入する場合

var testSection = document.createElement('section');
testSection.id = "test";
var target = document.getElementById('追加したい部分のID名');
target.parentNode.insertBefore(testSection, target.nextSibling);
$('#test').html('これで安心してjQueryでも操作できるよ!');

jQueryのafter()と同様のことが実現できます。

子ノード内の何番目に挿入するか指定する場合

var testSection = document.createElement('section');
testSection.id = "test";
var target = document.getElementById('追加したい部分のID名');
target.insertBefore(testSection, target.childNodes.item(数字));
$('#test').html('これで安心してjQueryでも操作できるよ!');

これでjQueryでHTML5の新要素を追加しようとしていたのと同様のことが、IE6〜8のようにHTML5の新要素を認識していないブラウザにおいてもカバーさせることができたかと思います。

Updated / Published