知りたいこと
JavaScript で querySelector()
等で要素を取得した後、その成否を確認するかどうか?
ご意見をお伺いしたいです。
コード
以下のようなコードです。
JavaScript
1// ➀成否を確認するバージョン 2const element = document.querySelector(".target"); 3if (element) { 4 element.setAttribute("data-flg", true); 5} 6 7// ➁成否を確認しないバージョン 8document.querySelector(".target").setAttribute("data-flg", true);
質問の経緯と意図
WEBサイト制作は未経験の初心者です。
何度かJavaScripは書いたことはあるのですが、いつも「➁成否を確認しないバージョン」でやっていました。
しかしChatGPTに聞いてみると「➀成否を確認するバージョン」の方が堅実であるとアドバイスを頂戴し、実際の現場ではどうなのかと疑問に思いました。
例えば「いいねボタン」の更新にあたってそのボタンがないことなんてあり得ないハズなので確認は不要だろうと思いますが、途中で insertAdjacentHTML()
などをする要素については確認した方がいいのかも。とは思ったのですが・・どうなのでしょうか?
必ず確認する、またはこういうときに確認する。など教えて頂けましたら幸いです。
よろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
#1
総合スコア146452
投稿2025/03/19 07:15
こんな手段もあります。
js
1// optional chaining 2document.querySelector(".target")?.setAttribute("data-flg", true);
とりわけ、TypeScriptでは、document.querySelector
の返り値がHTMLElement | null
のような型になっているので、「!
で無視させる」「条件分岐で絞り込む」「?.
でnull
やundefined
を無視させるようにメソッドをつなぐ」「as
でキャストをかける」など何かしらのアクションを取らないと、コンパイルに失敗します。
#2
総合スコア117400
投稿2025/03/19 07:27
趣旨が違うかもしれませんがdata-*を利用するなら私ならdatasetを使います
html
1<script> 2window.addEventListener("DOMContentLoaded", e=>{ 3 document.querySelector(".target")?.setAttribute("data-flg", true); 4 (document.querySelector(".target")?.dataset??{}).flg2=true; 5}); 6</script> 7<style> 8[data-flg]{color:red;} 9[data-flg2]{background-Color:yellow;} 10</style> 11<div class="target">hoge</div>
どうしても煩雑になりますので掴んでから処理したほうがわかりやすいし不具合がおきにくいと思います
html
1<script> 2window.addEventListener("DOMContentLoaded", e=>{ 3 const elem=document.querySelector(".target"); 4 if(elem){ 5 elem.setAttribute("data-flg", true); 6 elem.dataset.flg2=true; 7 } 8}); 9</script> 10<style> 11[data-flg]{color:red;} 12[data-flg2]{background-Color:yellow;} 13</style> 14<div class="target">hoge</div>
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#4
総合スコア700
投稿2025/03/19 07:44
編集2025/03/19 07:52めんどうくさくなると id だけ指定して、そのまま変数名として使いますね。
html
1<ul id="log"> 2 <template id="logTemplate"><li></li></template> 3</ul> 4<script type="module"> 5if (!logTemplate) throw new Error('required id=logTemplate element.'); 6addLog('hello world.'); 7function addLog(message) { 8 const row = logTemplate.content.firstElementChild.cloneNode(true); 9 row.innerText = `${message}`; 10 logTemplate.insertAdjacentElement('afterend', row); 11 logTemplate.parentElement.querySelectorAll(':scope > :nth-child(n + 100 of :not(template))') 12} 13</script>
throw expression が実装されたなら次の様に書くのではありますが……。(なのでちょっと書きづらいので要所要所ですね。
https://github.com/tc39/proposal-throw-expressions
js
1logTemplate ?? throw new Error('required id=logTemplate element.');
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#5
総合スコア87
投稿2025/03/19 11:41
javascriptだと確かに型チェックないんで、意識しないと難しいですね。
自分はその後の処理によるところはあるのですが、概ねチェックします。
簡単にやりたいなら、maisumakun(#1)さんが記載しているやり方を使いがちですね。
ただ可読性を意識するなら質問者さんが記載しているようにif文にします!
if文はその後の処理にもよりますが、ガード節使って機能追加時に{}のネストが深くならないように工夫します。
ts
1const element = document.querySelector(".target"); 2if (!element) return; 3element.setAttribute("data-flg", true);
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#6
総合スコア658
投稿2025/03/19 13:23
んー
色々な意見があるがどうなんだろうか。
JavaScriptでのコーディングは9割がVSCodeを使っているだろうからそれを前提として、jsではドキュメントコメントとかを書けば一応コードエディタの機能として型のミスマッチエラーの確認は実装中にできそうでそういう意味で言っても型システムの意味で言ってもNullableな変数をクリーンに扱いたければ、以下のようなコードになって、呼び出す関数のドキュメントコメントに引数にnullは許容できないと書くべき内容になるかと思うんですよね。
javascript
1// ➀成否を確認するバージョン 2const element = document.querySelector(".target"); 3if (element) { 4 // Todo: 以下のコードを関数呼び出しに置き換える 5 // element.setAttribute("data-flg", true); 6}
もちろん、jsにはオプショナルチェーンと言ってハテナマークでnullだとかundefinedとかは無視できるんですけど、糖衣構文というか式を簡略化するための機能なので構造的な問題からは少し外れるのかなと感じます。
それで、JavaScriptのいい所はscriptらしく簡単にコードを書ける上に基本機能が強力という所にあるかと思うので、厳密な意味でクリーンにするのってjsの良さをある種捨ててる感じがします。(関数化しなくてもコメント注釈とかをエディタで拾えるのかなjsは)
まあそこら辺は好みですけども。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#7
for (let i = 1; i <= 6; i++) {
console.log(#${i} さん、ありがとうございます!
);
}
メソッドチェーンに ?
・・オプショナルチェーン!便利ですね!
さっそくマニュアルを見てまいりましたが、使えるシーンがたくさんありそうですね。勉強になりました。
TypeScriptは触ったことがないのですが、備えるならば常にオプショナルチェーンの利用を必須とした方が良さそうですね。
なるほど、dataset
の方がピッタリなメソッドですね。短く済みますし、使わせて頂きます。
??{}
はその左がなければ空のオブジェクトをセットするみたいな処理でしょうか。
たしかに1行ずつ掴んでからの方が順序立てられていて見やすいですね。
なるほど、if
で囲んだらエラーはないが、目的の処理もされず、なんで処理されないのか困ったりしそう・・
そう考えるとチェックせずエラーが生じるようにして、すぐに当該箇所がわかるという利点はたしかにありそうですね。
junerさんid指定多用されますよね。以前教えて頂けたおかげで私もちょくちょく使えるようになりました。
要素チェックはするが、「質問の➀のように、要素があるときだけ目的の処理をする」ではなく、「要素がないときにthrow
する」ということですね。
たしかに要素チェックをするならその方が絶対いいですね。➀だと要素がないときに何で処理されないのか、分かりにくいですもんね。
「ガード節」というのですね。知りませんでした。
ネストの問題は悩むことが多々あるので、1行だとスマートで良いですね。
言語の思想的な発想を辿れるのはすごいですね。ご見識の深みと広がりを感じます。
そういうそもそものところから考えていくのは大好きです。
他の言語をほぼ知らずよくわからないのが正直なところですが笑、大変参考になりました。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。