IE で innerHTML = "" すると中の要素の innerHTML も消される
- カテゴリ:
- JavaScript
- IE
- コメント数:
- Comments: 0
◆ IE の innerHTML への空文字代入はその要素の全子要素削除だけじゃない
◆ 子孫要素すべての innerHTML を空にしてる
◆ innerHTML を消して子要素まとめて削除するときは使いまわす要素が innerHTML 以下にいないか注意
◆ 子孫要素すべての innerHTML を空にしてる
◆ innerHTML を消して子要素まとめて削除するときは使いまわす要素が innerHTML 以下にいないか注意
document.body.innerHTML = '<div class="a"><p>a</p><span>bcd</span><div id="id">efg</div></div>'
var elem = document.body.firstElementChild
console.log(1, elem.innerHTML)
document.body.innerHTML = ""
document.body.appendChild(elem)
console.log(2, elem.innerHTML)
var elem = document.body.firstElementChild
console.log(1, elem.innerHTML)
document.body.innerHTML = ""
document.body.appendChild(elem)
console.log(2, elem.innerHTML)
body に HTML を入れた後に 要素への参照を変数に入れておきます
そして body の innerHTML を空にします
body のすべての childNode に対して removeElement をしたような状態になるはずです
div や p タグの要素は除去されるだけに思えます
ですが結果は
[IE11]
1 <p>a</p><span>bcd</span><div id="id">efg</div>
2
2
elem の innerHTML まで空になっています
Chrome では
[Chrome]
1 <p>a</p><span>bcd</span><div id="id">efg</div>
2 <p>a</p><span>bcd</span><div id="id">efg</div>
2 <p>a</p><span>bcd</span><div id="id">efg</div>
ちゃんと残っています
つまり IE11 では innerHTML に空文字入れると その要素の子要素をすべて削除するのではなく 子孫要素全部の innerHTML を空にした上で子要素を削除しているわけです
こんなことしてるから遅いのか!
でもただ遅い原因だけじゃなくて やめてほしい動きでもあります
ここでいう elem を後から再利用するつもりのときに子要素を全部消すのが面倒だし 速度面でも早いことが多いので removeElement や remove メソッドを使わずに innerHTML を空文字にするという方法を取った場合 elem をどこかに append したら空になっています
バグのもとです
注意が必要ですね
手を抜かずに remove したら問題なく elem の中身は維持されます
document.body.innerHTML = '<div class="a"><p>a</p><span>bcd</span><div id="id">efg</div></div>'
var elem = document.body.firstElementChild
console.log(1, elem.innerHTML)
Array.prototype.forEach.call(document.body.childNodes, function(e){e.parentElement.removeChild(e)})
document.body.appendChild(elem)
console.log(2, elem.innerHTML)
var elem = document.body.firstElementChild
console.log(1, elem.innerHTML)
Array.prototype.forEach.call(document.body.childNodes, function(e){e.parentElement.removeChild(e)})
document.body.appendChild(elem)
console.log(2, elem.innerHTML)
[IE11]
1 <p>a</p><span>bcd</span><div id="id">efg</div>
2 <p>a</p><span>bcd</span><div id="id">efg</div>
2 <p>a</p><span>bcd</span><div id="id">efg</div>
ES6 使えないし remove メソッドも使えないので長くなりました
Chrome なら
;[...document.body.childNodes].forEach(e =>e.remove())
だけで済むのにやっぱり IE は早くほろべばいいんだ