JS勉強記⑧ノードの置き換え
HTML既に存在するノード(要素/タグ、テキスト)をJSを使って新しいノードに置き換える処理。
例題
HTMLで「古い要素です」という項目のリスト・「置換」ボタンを配置。ボタンをクリックするとリストの項目の内容が新しいものに置き換えられる。
①HTMLで上記のリスト・ボタンを配置。bodyは以下の通り。
<body>
<ul>
<li id="oldList">古い要素です</li>
</ul>
<input type="button" value="置換" onclick="replace()">
<script src="js/replace_child.js"></script>
</body>
続いてJSは以下の通り。
function replace() { -②
const newList = document.createElement('li'); ―③
newList.setAttribute('id', 'newList'); ―④
const newText = document.createTextNode('新しい要素です') ―⑤
newList.appendChild(newText); ―⑥
const oldList = document.getElementById('oldList'); ―⑦
const parentNode = oldList.parentNode; ―⑧
parentNode.replaceChild(newList, oldList); ―⑨
}
②function命令で関数replaceを宣言。
③変数newListを宣言し、createElementメソッドを使って新しいリスト用の空のli要素を生成。
④②で生成したノードにsetAttributeメソッドを使ってid属性(今回であれば'newList')を付与。基本構文は以下の通り。
要素名.setAttribute(属性名,値);
※もしすでに属性が設定されている場合はその属性の値を上書きする。
⑤変数newTextを宣言し、createTextNodeメソッドを使って新しいテキストノード(置き換えたい文字列『新しい要素です』)を生成。
⑥newTextをappendChildメソッドを使ってnewListの子ノードとして組み込む。この段階で「<li id="newList">新しい要素です</li>」が作成された状態。前回の復習です。
⑦変数oldListを宣言し、getElementByIdメソッドを使ってid='oldlist'のノードの内容を取得して代入。
⑧変数parentNodeを宣言し、parentNodeプロパティで変数oldListの親ノード(=liタグの親ノードなのでulタグ)を代入する。
⑨replaceChildメソッドを使って既存のoldListノードを②で生成したnewListノードに置き換える。基本構文は以下の通り。
置換されたノード = 置換対象の親ノード.replaceChild(置換後のノード, 置換対象のノード);
※今回置換対象となるのはliタグなので、変数parentNodeを⑨で使うために⑧でliタグの親要素であるulタグを取得し、プロパティで親ノードと設定した。
⑩ブラウザ上で「置換」ボタンを押すと『古い要素です』が『新しい要素です』に置換される。
長いし、いよいよ参照という概念が出てきて難しくなってきた。今回宣言したの変数の内容をまず整理してみる。
・変数oldList
id属性が"oldList"という値になっている、li要素/タグ。
・変数newList
createElementメソッドによって生成されたid属性が"newList"という値になっているli要素/タグ。
・変数newText
createNodeTextメソッドによって生成された、『新しい要素です』というテキストノード。
・変数parentNode
変数oldListにparentNodeプロパティを追加することで、「変数oldListの親」という役割が与えられたノード。変数oldListはli要素/タグなので、HTML的に言えばul要素/タグを指す。
各変数の関係を表すと以下の通り。
変数parentNode
(<ul>)
↓子 ↑親
変数oldList ⇔ 変数newList
(<li id="oldList">) ⇔ (<li id="newList">)
(⇔:replaceChildメソッドで置換)
↓子 ↑親
変数newText
(『新しい要素です』)
もし『古い要素です』を変数として宣言するならこの法則でいえば変数oldTextとなる。ややこしく感じるのはHTMLのid属性の値とJSの変数名が同じだからかもね。どうせならid属性だけ'old','new'で分かりやすくしてくれればよかった。(Q&Aを見ると同じような質問も多かった)次回以降id属性を振る場合は変数と名前が被らないように設定しよう!