はじめに
SQLの実行結果によって、HTML要素を削除したり、追加しているときに気づいた話を自分用メモとして残します。
もしかしたら勘違いしていることがあるかもしれないので、その際にはご指摘いただけると幸いです。
早速ですが以下の例、なんで子要素、つまり「太郎元気です!」が削除されず、どう消すのかわかりませんでした。
【HTML構成】
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>元気ですか~!</h2>
<div id="parentObj">
<p id = "childObj">太郎元気です!</p>
<p id = "nextChildObj">二郎元気です!</p>
</div>
</body>
</html>
【Javascript構成】
const getParentObj = document.getElementById("parentObj");
const getChildObj = document.getElementById("childObj");
if(getParentObj.removeChild(getParentObj.firstChild)){
alert("削除成功"); // 条件文は通るが、実際に太郎元気です!は消されてない。
}
else{
alert("削除失敗");
}
直接子要素にアクセスしてやれば話は早いですが、子要素にidが振られていなかったときに大変です。
適当にwhile文を回して全部消して、削除したくない子要素だけ復活させるなんてやったら手間ですし、無駄な処理です。
結論
はじめに、でお話したHTML構成だと、直接子要素指定する or whileで全削除からの必要子要素のみ復活以外の方法では、以下のようにするしかないと思います。
const getParentObj = document.getElementById("parentObj");
const getChildObj = document.getElementById("childObj");
const childCount = getParentObj.childElementCount;
for(var i = 0; i < childCount; i++){
getParentObj.removeChild(getParentObj.firstChild);
}
具体的説明
しかし、以下の例で条件文が通ってしまうことに違和感があり、原因を探ったところわかりました。
const getParentObj = document.getElementById("parentObj");
const getChildObj = document.getElementById("childObj");
if(getParentObj.removeChild(getParentObj.firstChild)){
alert("削除成功"); // 条件文は通るが、実際に太郎元気です!は消されてない。
}
else{
alert("削除失敗");
}
消えてないのではなく、消える対象を勘違いしているだけ
以下の例、本当は消す対象がないだけで、実行的にはうまくいっているんです。
const getParentObj = document.getElementById("parentObj");
const getChildObj = document.getElementById("childObj");
if(getParentObj.removeChild(getParentObj.firstChild)){
alert("削除成功"); // 条件文は通るが、実際に太郎元気です!は消されてない。
}
else{
alert("削除失敗");
}
というのも、HTML構成を少し変化させてみてみます。
【変化後のHTML構成】
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>元気ですか~!</h2>
<div id="parentObj">
三郎だって元気だよ。
<p id = "childObj">太郎元気です!</p>
<p id = "nextChildObj">二郎元気です!</p>
</div>
</body>
</html>
【Javascript構成】
const getParentObj = document.getElementById("parentObj");
const getChildObj = document.getElementById("childObj");
if(getParentObj.removeChild(getParentObj.firstChild)){
alert("削除成功"); // 条件文は通り、三郎だって元気だよ。が削除されました!
}
else{
alert("削除失敗");
}
ここで、親要素の内部に書かれた情報だけ削除されているのが、ブラウザのコンソールなどで調べればお分かりいただけると思います。
つまり、removeChild(getParentObj.firstChild)は、いきなり子要素に着目するのではなく、親要素を参照した後に、子要素のアクセスをしていることがわかりました。
おまけに
以下のようにやると、idが付けられていない要素の削除もできます。
【おまけのHTML構成】
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>元気ですか~!</h2>
<div id="parentObj">
<p>太郎元気です!</p>
<p>二郎元気です!</p>
</div>
</body>
</html>
【おまけのJavascript構成】
if(getParentObj.removeChild(getParentObj.firstElementChild.nextElementSibling)){
alert("削除成功"); // 条件文は通り、二郎元気です!が削除されました!
}
else{
alert("削除失敗");
}
最後に
すごく単純作業ですが、これに小一時間近くとられたので、メモしました。
removeChildの動きをしっかり理解することが大切ですね。
参考
- Node.removeChild
https://developer.mozilla.org/ja/docs/Web/API/Node/removeChild - ライブラリを使わない素のJavaScriptでDOM操作
https://qiita.com/kouh/items/dfc14d25ccb4e50afe89