質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.34%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

意見交換

5回答

216閲覧

記載するjsコードでの読みやすい書き方などを教えていただきたいです。

krnkn6

総合スコア8

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

2クリップ

投稿2025/01/16 13:14

編集2025/01/16 13:17

質問したいこと

3つの異なる要素を取得し、イベントリスナーを使用して同じタイミングでクラスを切り替えする際、どういった方法で記述するのが、読みやすさ・効率・パフォーマンスなどにおいてよいのかお聞きしたいです。

上記について、実装したjsコードをもとにご教示いただきたいです。

実装したコード

まずは、簡単にHTMLを記載します。
(id名やクラス名は今回適当につけております。)

「#el1」「#el2」「#el3」に、スクロールイベント・クリックイベント時にクラスを切り替えます。

今回、肝になると思われるのが、【クラスを切り替えるタイミングは全く同じでも、付与されるcssプロパティはそれぞれ異なる】という点です。

HTML

1<div id="el1"></div> 2 3<div> 4 <p id="el2"></p> 5</div> 6 7<div> 8 <div> 9 <p> id="el3"></p> 10 </div> 11</div> 12 13<button id="btn"></button>

上記のHTMLをもとに実装したjs(ほかのコード省略)を記載します。
(末尾に、クラスが追加された際のcssも一緒に記載しておきます。)

JavaScript

1const el1 = document.getElementById('el1'); 2const el2 = document.getElementById('el2'); 3const el3 = document.getElementById('el3'); 4const btn = document.getElementById('btn'); 5const eventClass = 'js-el'; //切り替えを行うクラス名 6 7let elFunc = ()=> { 8 el1.classList.toggle(eventClass); 9 el2.classList.toggle(eventClass); 10 el3.classList.toggle(eventClass); 11} 12 13window.addEventLisntener('scroll', ()=> { 14 elFunc(); 15} 16 17btn.addEventLisntener('click', ()=> { 18 elFunc(); 19} 20 21/* 22//js-elが追加された際のcss 23#el1.js-el {color: red;} 24#el2.js-el {color: blue;} 25#el3.js-el {color: orange;} 26*/

私が実装する際に考えたのは、「jsの読みやすさを重視して切り替えるクラス名を同じにし、cssでそれぞれプロパティを変える」という方法です。

また、コードの効率を重視する下記の考え方もありました。

HTMLで3つの要素をidではなく同じクラス名を付与し、getElementsByClassで取得。
上記を配列に変換し、forEachでそれぞれ「js-el」を切り替える。
(どの要素にjs-elを追加したのか、jsをパッと見ただけで想像つかないという観点から辞めました。)

上記の考え方以外にもまだまだ考え方はたくさんあるかと思います。

そもそも、切り替えるタイミングは同じでも付与するcssプロパティが異なるなら、クラス名は別々にした方がいいなど。

読みやすさ・効率・パフォーマンス面でどういう考え方がよいのかなど意見お聞きしたいです。

よろしくお願いいたします。

juner👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

回答5

#1

yambejp

総合スコア116921

投稿2025/01/16 13:51

scrollするたびにelFunc()を実行するのは合理的ではありません。
スクロール時の処理をもうすこし精査されたほうがよいでしょう

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#2

otn

総合スコア85989

投稿2025/01/16 17:53

yambejpさんのご指摘以外にも、「識別子のネーミングが変だよね」がぱっと見で思うことですが、「今回適当につけております」と言うことなので、そこには言及するなということですよね。

本題について言うと、こういうのは人により色々な考え方があるかと思います。

私は「毎回きちんと考える」方針です。別の言い方をすると「意味重視」とでもいうのか。
「ほんとに毎回真剣にゼロから検討しているのか?」と聞かれると、もちろんケースバイケースで手を抜いてそれほど頭を使わず決めることもありますが。

「下記のようなことを全部無視して一般論で考えるとどういうのがいい?」というのが質問意図かも知れませんが、一般論での検討をして案が出たとしても、個々のケースでその一般論的回答を使うかどうかは「毎回きちんと考えます」。手抜きの時はそれを使うかもですが、手を抜くのはどうでも良いケースなので、ほんとにどうでも良いです。

検討のための材料としては、
・クリック(やスクロール)で色を付けたり消したりしたいようだが、それはどういう意図・意味なのか?
・色が違うがそれぞれ意味が違うのか?あるいは色は対象によって違うだけで、「色有り」「色無し」の意味は全部共通なのか?

別の観点では、
・今回たまたま3要素が対象のようだが、画面表示条件によってこの数は変動するのか?あるいはシステムの仕様が変わらない限り常に3つなのか?仕様で3つと決まっている場合、今後の仕様変更で数が変動することを想定するのか、数の変動は今後もあり得ないのか?

などを踏まえて考えると思います。

読みやすさ・効率・パフォーマンスなどにおいてよいのかお聞きしたいです。

ですが、「読みやすさ」はいいとして、「パフォーマンス」はおそらく「リアル実行時間(レスポンスタイムというか)」「CPU使用量」「メモリー使用量」「その他リソース使用量」等だと思いますが、「効率」とは何の効率を言ってますか?「パフォーマンス」と同意?あるいは別の意味ですか?
上記の「別の観点では」は、「保守容易性」を考えてのことですが、そういうのは気にしますか?

また「読みやすさ」と「パフォーマンス」は、トレードオフの関係になることがしばしばあります。必ずではないし、ならない方が多い気もしますが。

という風に、評価軸の何を重視するかが変わると検討結果も変わってくるかと思います。

なお、上記の質問の形をした記述は、「などを踏まえて考えると思います」という自分だったらの場合の例として挙げただけで、回答してくれという意図ではないし、検討に必要な事項を網羅的に列挙し尽くしたつもりもないので、もし回答してもらったとしても、「その回答を前提として考えるとこういう書き方がいいのでは?」と回答出来ない気がします。

今回は他にもコードがあるようですが、もし質問に書かれているコードが全部で、補足の情報も無しというケースなら、上述のように「手を抜いてあまり真剣に考えない」と思います。
が、もし、真剣に考えるなら、意図・意味から、理解しやすさ・保守しやすさを意識して考えるというのは書いたとおりです。処理時間を気にするかどうかは、「この部分の処理時間が全体の時間のボトルネックになるのか?」次第ですね。現時点でだけじゃなくて将来的にデータ量が増えた場合とかも想定した上で。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#3

Lhankor_Mhy

総合スコア37040

投稿2025/01/17 00:40

まだ挙がっていない観点ですと、変数のスコープが大きいことが気になりました。
el1elFuncの中でしか使われないため、その中にスコープを収めた方が可読性は高いかと思います。
もちろん、その分elFunc呼び出し時のコストは高くなりますが、一方で(GCの動きによりますが)メモリは優位になるかと思います。
elFuncの中に書かないとしても、もしかしたら、ブロックを作ってその他のコードのクロージャから追い出した方がいいのかもしれません。

ただ、すでにご指摘がある通り、この程度のコードであるならあまり考えても思考コストに見合わないと思いますので、適当にやっつけて別のコードを書いた方が生産的ではないかな、と思うところです(もちろん、コードは例示であって実際のコードはもっと重たいものなのでしょうけれども)。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#4

yambejp

総合スコア116921

投稿2025/01/17 01:02

おそらくattr()の汎用性があがればdata-*を使用すると楽になるのですが

いまの実装状況から考えると各要素のstyleタグを書き換えるくらいが限界かなと

javascript

1<script> 2window.addEventListener('DOMContentLoaded', ()=>{ 3 const elFunc = ()=>document.querySelectorAll('[data-color]').forEach(x=>x.style.color=x.style.color==x.dataset.color?"":x.dataset.color); 4 btn.addEventListener('click',elFunc); 5}); 6</script> 7<div data-color="red">el1</div> 8<div> 9 <p data-color="blue">el2</p> 10</div> 11<div> 12 <div> 13 <p data-color="orange">el3</p> 14 </div> 15</div> 16<button id="btn">btn</button>

なお命題のフローについてはjs-elという同じクラスのつけ外しが課題なら、それらを包含する親要素1つだけでつけ外してあとは継承で対応すればよいような気がします。

javascript

1<script> 2window.addEventListener('DOMContentLoaded', ()=>{ 3 const elFunc = ()=>container.classList.toggle('js-el'); 4 btn.addEventListener('click',elFunc); 5}); 6</script> 7<style> 8.js-el #el1{color:red;} 9.js-el #el2{color:blue;} 10.js-el #el3{color:orange;} 11</style> 12<div id="container"> 13 <div id="el1">el1</div> 14 <div> 15 <p id="el2">el2</p> 16 </div> 17 18 <div> 19 <div> 20 <p id="el3">el3</p> 21 </div> 22 </div> 23 <button id="btn">btn</button> 24</div>

いずれにしてもスクロールで対応したいという命題が謎なのでそこは見直してください

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#5

utm.

総合スコア378

投稿2025/01/17 14:13

編集2025/01/17 14:16

書き方で効率やパフォーマンスは気にしなくていいと思います。
アルゴリズム的にアウトなら気にしますが。(ちなみに効率は「予測するな実測しろ」です)
cssの属性が違うのであれば、同じクラス名で別の挙動をとるようにするとおそらく、今後デバッグが発生したときにべつの人がみるとイラっとすると思うので、htmlに属性を持たせればいいと思います。

それとtoggleは不具合の原因になるので私は滅多に使いません。
質問のような簡易な状態ですと正直好みだと思いますけど、toggleを使うコードを書く人を信用はできません。

コメントアウトは別の書き方ですので参考までに。

だいぶ過激な考え方かもしれませんが、
私としてはidを使うと脳が縮むと思っているので使いません。
私としてはhtmlを見ているときにそのタグの意味を明確にしたいときに使いたいです。

ちなみにこういった質問というか疑問は考えるだけ無駄だと思ってます。
私も最初のころは考えましたが。

css

1.bg-blue{ 2 background-color: blue; 3} 4 5.bg-red { 6 background-color: red; 7} 8 9.bg-yellow { 10 background-color: yellow; 11}

html

1 <div id="el1" class="js-toggle-target" data-toggle-class="bg-blue"> 2 dummy1 3</div> 4 5<div> 6 <p id="el2" class="js-toggle-target" data-toggle-class="bg-red"> 7 dummy2 8 </p> 9</div> 10 11<div> 12 <div> 13 <p id="el3" class="js-toggle-target" data-toggle-class="bg-yellow"> 14 dummy3 15 </p> 16 </div> 17</div> 18 19<button id="btn"> 20 button 21</button>

javascript

1function elFunc() { 2 const $toggleTargets = document.getElementsByClassName('js-toggle-target') 3 Array.from($toggleTargets).forEach((value) => { 4 toggleClass(value) 5 }) 6} 7 8function toggleClass(element) { 9 const className = element.dataset.toggleClass 10 // const className = element.getAttribute('data-toggle-class'); 11 12 element.classList.toggle(className); 13 14} 15 16// function toggleClass(element) { 17// const className = element.dataset.toggleClass 18// // const className = element.getAttribute('data-toggle-class'); 19 20// const hasClass = element.dataset.hasToggledClass == 'true' 21// const changeFlag = (flag) => element.dataset.hasToggledClass = flag 22 23// if (hasClass) { 24// element.classList.remove(className); 25// } else { 26// element.classList.add(className); 27// } 28 29// changeFlag(!hasClass) 30 31// } 32 33const btn = document.getElementById('btn'); 34 35window.addEventListener('scroll', () => { 36 elFunc(); 37}) 38 39btn.addEventListener('click', () => { 40 elFunc(); 41}) 42

追記:
ちなみにstyleタグをjsから制御する方法は「最悪」なので使いません。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

この意見交換はまだ受付中です。

会員登録して回答してみよう

アカウントをお持ちの方は

関連した質問