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

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

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

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

3回答

726閲覧

varを再定義する理由が何か分からないです。

Akaho

総合スコア39

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2019/06/03 12:23

編集2019/06/04 10:19

progateのjquery学習コース上級編を学習しています。
課題内容としては
画像にある 数字1〜4をおすボタンと、次へ・前へをおすボタンをおすと、それに対応する画像が出てきます。
それで、最初の画像(数字1)と最後の画像(数字4)になると、おすボタンである『前へ』と『次へ』が消えるようにするという課題です。
(最初の画像になると手本のように『前へ』が消え、最後の画像になると『次へ』が消えるようにする)
課題クリアしたのですが、今回教えてもらいたいことはvar slideIndex=$('.slide').index($('.active'));$('.index-btn').click(function() {
内で定義していれば、別に$('.change-btn').click(function() {で改めてかく必要性はないんじゃないかという疑問を解決して欲しいです。変数varのスコープはブロックの外まであるというのを理由にそう思うのですが、、、
イメージ説明

html

1コード 2<!DOCTYPE html> 3<html lang="ja"> 4 <head> 5 <meta charset="utf-8"> 6 <title>Progate</title> 7 <link rel="stylesheet" href="stylesheet.css"> 8 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> 9 </head> 10 <body> 11 <div class="slide-wrapper"> 12 <h2 class="slide-title">にんじゃわんこの一年</h2> 13 <div class="change-btn-wrapper"> 14 <div class="change-btn prev-btn">← 前へ</div> 15 <div class="change-btn next-btn">次へ →</div> 16 </div> 17 <ul class="slides"> 18 <li class="slide active"><img src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/jquery/advanced/spring.jpg"></li> 19 <li class="slide"><img src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/jquery/advanced/rainy.jpg"></li> 20 <li class="slide"><img src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/jquery/advanced/autumn.jpg"></li> 21 <li class="slide"><img src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/jquery/advanced/winter.jpg"></li> 22 </ul> 23 <div class="index-btn-wrapper"> 24 <div class="index-btn">1</div> 25 <div class="index-btn">2</div> 26 <div class="index-btn">3</div> 27 <div class="index-btn">4</div> 28 </div> 29 </div> 30 <script type="text/javascript" src="script.js"></script> 31 </body> 32</html> 33

css

1コード 2body { 3 font-family: "Hiragino Maru Gothic ProN", sans-serif; 4} 5 6ul { 7 list-style: none; 8} 9 10.slide-wrapper { 11 text-align: center; 12 width: 1000px; 13 margin: 0 auto; 14 color: #5e6f84; 15 padding: 60px 0; 16} 17 18.slide-title { 19 font-size: 40px; 20 margin-bottom: 30px; 21} 22 23.change-btn-wrapper { 24 width: 500px; 25 margin: 20px auto; 26 font-size: 18px; 27} 28 29.change-btn-wrapper:after { 30 content: ""; 31 clear: both; 32 display: block; 33} 34 35.prev-btn { 36 cursor: pointer; 37 float: left; 38 /* 初期状態では非表示にしてください */ 39 display:none; 40 41} 42 43.next-btn { 44 cursor: pointer; 45 float: right; 46} 47 48.slides { 49 padding: 0; 50} 51 52.slide { 53 display: none; 54} 55 56.active { 57 display: block; 58} 59 60.slide img { 61 width: 500px; 62 height: auto; 63 border-radius: 5px; 64} 65 66.index-btn-wrapper { 67 font-size: 16px; 68 margin-top: 20px; 69} 70 71.index-btn { 72 display: inline-block; 73 color: #4e90af; 74 background-color: #e0f5ff; 75 width: 40px; 76 padding: 6px 0; 77 margin: 0 5px; 78 border-radius: 3px; 79 cursor: pointer; 80} 81 82.index-btn:hover { 83 color: #fff; 84 background-color: #5cabd0; 85}

javascript

1コード 2$(function() { 3 $('.index-btn').click(function() { 4 $('.active').removeClass('active'); 5 var clickedIndex = $('.index-btn').index(this); 6 $('.slide').eq(clickedIndex).addClass('active'); 7 8 // 1. 変数slideIndexに「.active」要素のインデックス番号を代入してください 9 var slideIndex=$('.slide').index($('.active')); 10 11 // 3. change-btn要素を表示してください 12 $('.change-btn').show(); 13 14 // 2. ifとelse ifを用いて、「.change-btn」の表示/非表示をおこなってください 15 if(slideIndex==0){ 16 $('.prev-btn').hide(); 17 }else if(slideIndex==3){ 18 $('.next-btn').hide(); 19 20 } 21 22 }); 23 24 $('.change-btn').click(function() { 25 var $displaySlide = $('.active'); 26 $displaySlide.removeClass('active'); 27 if ($(this).hasClass('next-btn')) { 28 $displaySlide.next().addClass('active'); 29 } else { 30 $displaySlide.prev().addClass('active'); 31 } 32 33 // index-btnのクリックイベントと同様の処理を記述してください 34 var slideIndex=$('.slide').index($('.active')); 35 $('.change-btn').show(); 36 if(slideIndex==0){ 37 $('.prev-btn').hide(); 38 }else if(slideIndex==3){ 39 $('.next-btn').hide(); 40 } 41 42 }); 43}); 44

追記
質問する経緯
$('.change-btn').click(function() {内にある
var slideIndex=$('.slide').index($('.active'));を削除してやってみるとクリアできなかったので、
理由が分からず質問しました。varのことを調べて『変数varのスコープはブロックの外まである』と知り、progateの仕様で無理だったのか、まだ知らない知識があるのかの判断ができなかったからです。なぜ無理だったのかという理由に重点をおいた質問でした。情報欠けた質問になってしまって申し訳なかったです。

リンク内容

追記 総括
『まず、変数slideIndexに入っているのはslideクラスに付いているactiveクラスのインデックス番号であること、つまり数値であることを認識。
そしてactiveクラスは.change-btnクリックイベントの中にある変数$displaySlideに入っている。
その$displaySlideを使って、if文の中でactiveクラスを動かす処理を(一番下のコード)しているから、そのまま
var slideIndex=$('.slide').index($('.active'));をいれずに
if(slideIndex==0){
$('.prev-btn').hide();
}else if(slideIndex==3){
$('.next-btn').hide();
}の処理をするとだめ。なぜなら、activeクラスが移動したために変数slideIndexの数値が初期状態からずれてしまっているため。その防止策としてvar slideIndex=$('.slide').index($('.active'));でリセッしてやらないといけない。』

コード
$displaySlide.next().addClass('active');
} else {
$displaySlide.prev().addClass('active');
}

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

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

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

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

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

think49

2019/06/03 12:25

挑発的なタイトルを付ける必要がありますか
1T2R3M4

2019/06/03 12:39

progateの見解は何だったの。
m.ts10806

2019/06/03 12:48

>そう思うのですが、、、 実際にやってみた結果を記載してください。これを実際に解決するのは周囲ではなくご自身のような気がします。 試せばわかることなので。試したうえで思ったように動かなければデバッグして動作を確認すると良いです。
Lhankor_Mhy

2019/06/03 12:48

『改めてかく必要性はないんじゃないか』とのことですが、その改変をして動作するコードをご提示ください。
guest

回答3

0

ベストアンサー

var を伴って宣言した変数のスコープは実行コンテキスト (execution context)であり、これは変数を含んでいる関数、または関数の外で宣言された変数はグローバルになります。

var - JavaScript | MDN

ブロックスコープの外には出ますが、イベントリスナは関数なのでその中にスコープができます。

js

1$(function() { 2 $('.index-btn').click(function() { 3//... 4 slideIndex=$('.slide').index($('.active')); 5//... 6 }); 7 8 $('.change-btn').click(function() { 9//... 10 slideIndex=$('.slide').index($('.active')); 11//... 12});

↑のようにすれば、必要ないといえばないのですが、グローバル変数になります。あまりよいことではないと思います。

js

1$(function() { 2 $('.index-btn').click(function() { 3//... 4 var slideIndex=$('.slide').index($('.active')); 5//... 6 }); 7 8 $('.change-btn').click(function() { 9//... 10 slideIndex=$('.slide').index($('.active')); 11//... 12});

↑この場合も動きますが、$('.change-btn').clickの方はやはりグローバル変数です。

js

1$(function() { 2 var slideIndex; 3 $('.index-btn').click(function() { 4//... 5 slideIndex=$('.slide').index($('.active')); 6//... 7 }); 8 9 $('.change-btn').click(function() { 10//... 11 slideIndex=$('.slide').index($('.active')); 12//... 13});

↑この場合は両方ともローカル変数ですが、スコープの範囲が広くなっていますね。不必要に変数のスコープを広げるのはいいことではないと思います。状況によってはありかと思いますが、この場合は不要でしょう。

投稿2019/06/03 14:00

Lhankor_Mhy

総合スコア36074

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

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

Akaho

2019/06/04 05:21

場合分けして解説して下さってありがとうございました。
Lhankor_Mhy

2019/06/04 06:05 編集

追記拝読 var slideIndex=$('.slide').index($('.active')); の直前で、 removeClass('active'); addClass('active'); してますから、slideIndexは取得し直さないと、ずれます。 (slideIndex に入っているのはプロパティへの参照ではなく、ただの数値です。) なので、まるまる一行を削除すると、再取得ができないため動作しません。これはスコープとは関係ない話です。
Akaho

2019/06/04 06:15

なぜずれるのかよく理解できないです。 if ($(this).hasClass('next-btn')) { $displaySlide.next().addClass('active'); } else { $displaySlide.prev().addClass('active'); }が if(slideIndex==0){ $('.prev-btn').hide(); }else if(slideIndex==3){ $('.next-btn').hide(); }に影響与えているということですか?
Lhankor_Mhy

2019/06/04 06:21

$('.slide').index($('.active')); は、.slide 要素たちのなかで、.active が何番目にあるか を、数値で返します。 なので、.active の場所が変わると、違う値になります。 ですから、 removeClass('active'); addClass('active'); で、.active の場所を変えた場合、 $('.slide').index($('.active')); を再度取得しないと、間違った値になります。
Lhankor_Mhy

2019/06/04 06:23

繰り返しになりますが、slideIndex に入っているのはプロパティへの参照ではなく、ただの数値です。 .active の場所が変わった時に、勝手に値が変わってくれればラクなのですが、そういうものではないです。
Akaho

2019/06/04 10:25

しっかり理屈を解説してくださりありがどうございました。
guest

0

このようにslideIndexを外側に一箇所だけ記述すると
slideIndexが0となり、現在地が取得できないため
前へ次へが使用できなくなります。

そのため、スコープの関係上、click(function() {内の
2箇所に記述する必要があります。

js

1$(function() { 2 var slideIndex = $(".slide").index($(".active")); 3 $(".index-btn").click(function() { 4 $(".active").removeClass("active"); 5 var clickedIndex = $(".index-btn").index(this); 6 $(".slide") 7 .eq(clickedIndex) 8 .addClass("active"); 9 10 // 1. 変数slideIndexに「.active」要素のインデックス番号を代入してください 11 // var slideIndex = $(".slide").index($(".active")); 12 13 // 3. change-btn要素を表示してください 14 $(".change-btn").show(); 15 16 // 2. ifとelse ifを用いて、「.change-btn」の表示/非表示をおこなってください 17 if (slideIndex == 0) { 18 $(".prev-btn").hide(); 19 } else if (slideIndex == 3) { 20 $(".next-btn").hide(); 21 } 22 }); 23 24 $(".change-btn").click(function() { 25 var $displaySlide = $(".active"); 26 $displaySlide.removeClass("active"); 27 if ($(this).hasClass("next-btn")) { 28 $displaySlide.next().addClass("active"); 29 } else { 30 $displaySlide.prev().addClass("active"); 31 } 32 33 // index-btnのクリックイベントと同様の処理を記述してください 34 // var slideIndex = $(".slide").index($(".active")); 35 $(".change-btn").show(); 36 if (slideIndex == 0) { 37 $(".prev-btn").hide(); 38 } else if (slideIndex == 3) { 39 $(".next-btn").hide(); 40 } 41 }); 42});

投稿2019/06/03 13:47

編集2019/06/03 14:05
yasutomi

総合スコア2937

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

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

Akaho

2019/06/04 05:59 編集

『slideIndexを外側に一箇所だけ記述すると』と 『slideIndexが0となり、現在地が取得できないため』の間にある理屈がわからないです。 教えて下さい。実際に```var slideIndex = $(".slide").index($(".active"))```をprogateの方でご指摘通りやってみると、前へボタンだけが使えなくなっています。次へはなぜか使えます。
guest

0

変数varのスコープはブロックの外まである

たぶんグローバル変数とローカル変数を勘違いしてます。

投稿2019/06/03 12:58

gentaro

総合スコア8949

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

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

Akaho

2019/06/04 05:09

理解していない点を指摘して下さってありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問