要素の追加(appendChild)と削除(removeChild)で上手くいかない原因はTextNode(テキストノード)だった。。。
- 2013/10/03
さてさて、今週作成した学生のポートフォリオサイトを紹介するページで、要素の追加と削除が上手くいかずに悩まされたので書いておきます。( ..)φメモメモ
原因はタイトルにも書いてるとおり、TextNode(テキストノード)でした。
やりたかったのはコレ
学生のポートフォリオサイトを紹介するページなので順番を固定せずにダイナミックに順番を変えたかった。
1.画像を並べる
2.最初の画像を削除する
3.消えた要素を埋めるように画像がズレる
4.削除した画像を最後の画像の後に追加する
これで、画像がグルグルローテーションする。はずだった・・・ が、1回目の要素の削除が上手くいかない。2回目からは、削除して追加されるけど、最初が消えてないので最初の画像と最後の画像に同じものが表示されてしまう。
どうみても1回目の削除だけが処理されておらず、それ以降は正常に処理されている。
実際の処理
<div id=”wrap”></div>
HTMLとしては、idでwrapとつけたdivを用意して、その中にimg要素を削除して追加するというもの。
//要素の削除 var removeObj = document.getElementById("wrap"); removeObj.removeChild(removeObj.childNodes.item(0)); //要素の追加 var element = document.createElement('img'); element.setAttribute('src', 'thumb' + n + '.jpg'); document.getElementById("wrap").appendChild(element);
変数のn は、違う画像を表示するためにカウントしながら使用しています。
バグの原因はTextNode(テキストノード)でした。
バグの原因はプログラムのミスではなく、HTMLの書き方にありました。実際のHTMLは、下のコードの様に改行して記述していました。
<div id="wrap"> </div>
ちなみに、TextNode(テキストノード)とは・・・
HTML文書のタグ以外の文字データで、ブラウザ画面上に配置して表示できるDOM オブジェクトの1つです。空白や改行、TABなどもテキストノードに当たります。
・テキストノードについてはこちら
そうなんです!
親要素内に文字や空白、改行やTABなどが存在すると、それらが1つ目の要素という扱いになります。1回目のremoveChildで目に見えない空白や改行を削除していたことになります。画像が削除されなかったのは仕様なのです。
<div id="wrap"></div>
HTMLを修正したら、思惑通りに動作しました。
ちなみに、バグの原因になった、このHTMLでも
<div id="wrap"> </div>
childNodes.item(0) → childNodes.item(1)
この様に書き換えれば、上手くいきます。
//要素の削除 var removeObj = document.getElementById("wrap"); removeObj.removeChild(removeObj.childNodes.item(1)); //要素の追加 var element = document.createElement('img'); element.setAttribute('src', 'thumb' + n + '.jpg'); document.getElementById("wrap").appendChild(element);
今回は煮詰まったので、Spicadotsの静海くんに見てもらったら・・・
Nodoの第一要素が
というものになっているのがそもそもの原因になってますね なので、最初には何も消えていないように見える。 仮にitem(1)で動かした場合どうなりますか? そもそもなぜ第一要素がこれなのかもちょっとわからないですね・・・
と、メッセージを送ってくれたので、TextNodeで検索したら、ピンときたわけです。静海くん、ありがとうございました!
ちなみに、今回作ったポートフォリオサイトの紹介ページはこちら!