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

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

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

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

Q&A

解決済

2回答

1079閲覧

querySelectorの戻り値を変数に代入する場合としない場合の挙動の違い

YESYUKI17

総合スコア28

JavaScript

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

0グッド

0クリップ

投稿2019/09/01 03:19

前提・実現したいこと

お世話になります。自らコードを書いていて挙動の違いの原因が理解できずにおります。
アドバイスいただけると助かります。
タブの切り替えをJSで実装しようとしております。結果的に意図した挙動になるようにコードがかけたのですが、
なぜ意図したものと意図しないものの違いが生まれるのかいまいち理解できずにいます。
意図した挙動にならない場合はタブの切り替えの際にis-shownクラスが外れず二重にPanelが表示されます。
document.getElementsByClassName('disp')を変数に代入するか、むき出し?のままで使うかによってこの違いが生まれていると思うのですが、なぜそうなるのかがいまいち理解できません。確かに、意図しないコードの方だとPanel2のis-shownクラスを外すためのコードが書かれていないので、当然is-shownが重複で表示されると言うことは理解できます。逆に意図したコードの方のis-shownの付け外しが、変数を使うか、むき出しのまま使うかどうかに影響されているのかなと思っているのですが、いまいちピンと来ません。よろしくお願いします。

意図した挙動になるJSコード

function tabswitch() { document.getElementsByClassName('is-shown')[0].classList.remove('is-shown'); tab = Array.prototype.slice.call(tab); const index = tab.indexOf(this); document.getElementsByClassName('disp')[index].classList.add('is-shown'); }

意図した挙動にならなかったJSコード

function tabswitch() { const disp = document.getElementsByClassName('disp'); disp[0].classList.remove('is-shown'); tab = Array.prototype.slice.call(tab); let index = tab.indexOf(this); disp[index].classList.add('is-shown'); }

HTML

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Practice</title> <link rel="stylesheet" href="css/styles.css"> </head> <body> <div class="select"> <div class="tab">button1</div> <div class="tab">button2</div> </div> <div class="panel"> <div class="disp hidden is-shown">panel1</div> <div class="disp hidden">panel2</div> </div> <script src="js/main.js"></script> </body> </html>

CSS

.panel { position: relative; } .disp { position: absolute; height: 200px; /* background: white; */ } .hidden { visibility: hidden; } .hidden.is-shown { visibility: visible; }

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

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

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

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

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

kei344

2019/09/01 03:29

書かれている状況が再現するコードを質問文に追記されたほうが回答を得やすいと思います。
guest

回答2

0

「意図した挙動」と「意図しない挙動」で、.classList.removeするリストが明らかに異なっています。

  • 前者…document.getElementsByClassName('is-shown')
  • 後者…document.getElementsByClassName('disp')

投稿2019/09/01 03:58

maisumakun

総合スコア145183

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

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

0

ベストアンサー

意図した挙動になるコード、 そうでないコードの差は、

is-shown を取得しているか disp を取得しているかです。

意図した挙動になるコードは is-shown を取得しています。

javascript

1document.getElementsByClassName('is-shown')[0].classList.remove('is-shown');

is-shown を取得した場合は、
is-shownを取得 -> is-shownを削除 -> tabに合わせてdispにis-shown を付与

という感じになるので、 片方にis-shownがついて、 そのis-shownを取得して消して、 もう片方に付与するという流れになります。

一方で、 意図しないコードは

javascript

1 const disp = document.getElementsByClassName('disp'); 2 disp[0].classList.remove('is-shown');

必ずdisp[0]のis-shownを消しています。そのため、 もう片方のis-shownが消えることはありません。

それと、 お節介ですが、
ES6の記法で書いて良いなら、

javascript

1const tab = [...document.getElementsByClassName('tab')] 2const disp = [...document.getElementsByClassName('disp')] 3const tabSwitch = (e) => { 4 const shown = document.getElementsByClassName('is-shown')[0] 5 shown.classList.remove('is-shown') 6 const k = tab.indexOf(e.currentTarget) 7 disp[k].classList.add('is-shown') 8}

個人的に無駄はありますが、 forが見やすくて好きです(数が少ない場合は私はこちらを使ってます)。

javascript

1const tab = [...document.getElementsByClassName('tab')] 2const disp = [...document.getElementsByClassName('disp')] 3const tabSwitch = (e) => { 4 for (const v of disp) v.classList.remove('is-shown') 5 const k = tab.indexOf(e.currentTarget) 6 disp[k].classList.add('is-shown') 7}

ES6でアロー関数、 スプレッド演算子、 for..of などが出ました。

ちなみに Array.prototype.slice.call(elms) は [].slice.call(elms) とも書けますし、
ES6からはスプレッド演算子で [...elms] という風にも書けるようになりました。

投稿2019/09/01 04:35

編集2019/09/01 04:37
Newbi

総合スコア163

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

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

YESYUKI17

2019/09/01 10:19

ES6での記法までありがとうございます。勉強させていただきます。 そして回答もありがとうございます。初歩的な勘違いをしていたことに気づけました。 is-shownクラスは常に一つしか存在しないので、どのタグについていても必ず[0]で削除できますね。 助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問