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

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

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

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

Q&A

解決済

1回答

1543閲覧

JSの初期化エラーについてご教授いただきたいです。

LEMON_

総合スコア17

JavaScript

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

0グッド

0クリップ

投稿2021/07/05 14:43

自分の状況

現在JSのサイトを作って練習しているのですが、独学の為少しつまずいてしまったのでご教授いただければ幸いです。

分からないこと

初期化エラーのエラーコードが出てきたのだが、自分のコードのどこが出来ていないのか理解できなかった。

errorcode

1script.js:28 Uncaught ReferenceError: Cannot access 'checkPlaying' before initialization at HTMLImageElement.<anonymous> (script.js:28)

試したこと

エラーコードを検索してみたところ初期化のエラーだと分かった。検索結果

しかし、該当箇所のコードを見たところletなどを使用しておらず、知識も浅いため初期化についての理解が出来なかった。

コード

HTML

1<div class="app"> 2 <div class="vid-container"> 3 <video loop> 4 <source src="video/rain.mp4"> 5 </source> 6 </video> 7 </div> 8 9 <div class="time-select"> 10 <button data-time="1500">25 Minutes</button> 11 <button data-time="300">5 Minutes</button> 12 <button data-time="600">10 Minutes</button> 13 </div> 14 <div class="player-container"> 15 <audio class="song"> 16 <source src="sounds/rain.mp3"> 17 </audio> 18 <img src="svg/play.svg" alt="play" class="play"> 19 <svg class="track-outline" width="453" height="453" viewBox="0 0 453 453" fill="none" 20 xmlns="http://www.w3.org/2000/svg"> 21 <circle cx="226.5" cy="226.5" r="216.5" stroke="white" stroke-width="20" /> 22 </svg> 23 <svg class="moving-outline" width="453" height="453" viewBox="0 0 453 453" fill="none" 24 xmlns="http://www.w3.org/2000/svg"> 25 <circle cx="226.5" cy="226.5" r="216.5" stroke="#018EBA" stroke-width="20" /> 26 </svg> 27 <h3 class="time-display">0:00</h3> 28 </div> 29 <div class="sound-picker"> 30 <button data-sound="sounds/rain.mp3" data-video="sounds/rain.mp4"><img src="svg/rain.svg" 31 alt="rain"></button> 32 <button data-sound="sounds/beach.mp3" data-video="sounds/beach.mp4"><img src="svg/beach.svg" 33 alt="beach"></button> 34 </div> 35 </div>

JS

1const app = () => { 2 const song = document.querySelector(".song"); 3 const play = document.querySelector(".play"); 4 const outline = document.querySelector(".moving-outline circle"); 5 const video = document.querySelector(".vid-container video"); 6 7 const sounds = document.querySelectorAll(".sound-picker button"); 8 9 const timeDisplay = document.querySelector(".time-display"); 10 const timeSelect = document.querySelector("time-select button"); 11 12 const outlineLength = outline.getTotalLength(); 13 14 let fakeDuration = 600; 15 16 outline.style.strokeDasharray = outlineLength; 17 outline.style.strokeDashoffset = outlineLength; 18 19 sounds.forEach(sound => { 20 sound.addEventListener("click" , function(){ 21 song.src = this.getAttribute("data-sound"); 22 video.src = this.getAttribute("data-video"); 23 checkPlaying(song); 24 }); 25 }) 26 27 play.addEventListener("click", () => { 28 checkPlaying(song); 29 }); 30 31 timeSelect.forEach(option => { 32 option.addEventListener("click", function () { 33 fakeDuration = this.getAttribute("data-time"); 34 timeDisplay.textContent = `${Math.floor(fakeDuration / 60)}:${Math.floor(fakeDuration % 60)}`; 35 }); 36 }); 37 38 const checkPlaying = song => { 39 if (song.paused) { 40 song.play(); 41 video.play(); 42 play.src = "svg/pause.svg"; 43 } else { 44 song.pause(); 45 video.pause(); 46 play.src = "svg/play.svg"; 47 } 48 }; 49 50 song.ontimeupdate = () => { 51 let currentTime = song.currentTime; 52 let elapsed = fakeDuration - currentTime; 53 let seconds = Math.floor(elapsed % 60); 54 let minutes = Math.floor(elapsed / 60); 55 56 let progress = outlineLength - (currentTime / fakeDuration) * outlineLength; 57 outline.style.strokeDashoffset = progress; 58 59 timeDisplay.textContent = `${minutes}:${seconds}`; 60 61 if(currentTime >= fakeDuration) { 62 song.pause(); 63 song.currentTime = 0; 64 play.src= "svg/play.svg"; 65 video.pause(); 66 } 67 } 68}; 69 70app();

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

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

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

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

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

so87

2021/07/05 19:46

掲載しているソースコードは実際に該当のエラーが発生しているソースコードと相違がありますか?わたしが試してみたところ別のエラー「Uncaught TypeError: Cannot read property 'forEach' of null」を確認しました。 const timeSelect = document.querySelector("time-select button"); ではなく const timeSelect = document.querySelectorAll(`.time-select button`); となるはずです。
guest

回答1

0

ベストアンサー

投稿されたコードでは別のエラー「Uncaught TypeError: Cannot read property 'forEach' of null」が発生しており、いったん

<source src="video/rain.mp4">の閉じタグを削除と、下記修正を行った上で検証してみたところ ```js // const timeSelect = document.querySelector("time-select button"); const timeSelect = document.querySelectorAll(".time-select button"); ``` 該当の初期化エラーは確認できませんでした。

?と思ったのでソースを元に戻して、timeSelect.forEachでエラーが発生しているのは無視をして、playボタンを押してみたところ、該当のエラーコードが出てきました。初期化エラーということで初期化の段階でエラーが発生しているのだと勘違いしてしまいました。

ということで下記のセレクタの記述ミスが原因です。

js

1const timeSelect = document.querySelector("time-select button");

ここでNodeListではなくElementを返すquerySelectorを選択してしまっているのと、引数のセレクタもクラス指定ができておらず、結果はnullとなるはずです。nullで初期化された変数timeSelectに対してforEachメソッドがコールされたので、JSとしては処理がそこ(timeSelect.forEach部分)で落ちます。checkPlaying関数を定義する前にJSが終了しているため、playボタンに登録されているイベントリスナーから存在しないcheckPlaying関数をコールしようとして、今回のエラーが発生という流れです。「checkPlayingなんてないよ。初期化ちゃんとした?」ということですね。

script.js:28 Uncaught ReferenceError: Cannot access 'checkPlaying' before initialization at HTMLImageElement.<anonymous> (script.js:28)

投稿2021/07/05 20:23

編集2021/07/05 20:31
so87

総合スコア764

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

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

LEMON_

2021/07/06 08:03

ご回答ありがとうございます。so87様の回答を繰り返しながら確認していく形となってしまっているので、間違いがあればご指摘いただきたいです。 ここでNodeListではなくElementを返すquerySelectorを選択してしまっているのと、引数のセレクタもクラス指定ができておらず、結果はnullとなるはずです。 →クラス指定見落としていました....Nodelistを返すquerySelectorAllではなく、Elementを返すquerySelectorを指定してしまっていたので、forEach関数が使えずにエラーが出てしまっていたということですね.... nullで初期化された変数timeSelectに対してforEachメソッドがコールされたので、JSとしては処理がそこ(timeSelect.forEach部分)で落ちます。checkPlaying関数を定義する前にJSが終了しているため、playボタンに登録されているイベントリスナーから存在しないcheckPlaying関数をコールしようとして、今回のエラーが発生という流れです。「checkPlayingなんてないよ。初期化ちゃんとした?」ということですね。 →関数を定義した段階で、timeSelectが初期化=Nullしてしまっていた。そのあとは上記のような状況と認識しています。 「checkPlayingなんてないよ。初期化ちゃんとした?」ということですが、初期化の必要があるということなのでしょうか....?基礎的なところだと思うので、スルーしていただいてもかまわないです。
so87

2021/07/06 08:34

少し認識が違うようです。Javascriptはインタプリタ方式で実行される動的なスクリプト言語という類のもので、`const checkPlaying = song => {`というアロー関数式が処理される前に、エラーでブロックを抜けてプログラムが完了しています。checkPlayingがアロー関数式を使った関数定義ではなく、`function checkPlaying(song){}`というような往年のユーザー関数定義ならばエラーにはならなかったはずです。関数宣言はスコープ内ならばどこに書いていても実行されますが、関数式は実行しながら順番にメモリに読み込まれます。これはJSの仕様で、`関数宣言`と`関数式`の挙動の違いとなります。LEMON_さんはcheckPlayingを定義して初期化してるつもりでも、今回の場合はエラーで処理が飛ばされているので、jsのインタプリタ上ではまだ読み込まれていない状態となります。
so87

2021/07/06 08:42

今回のように`関数式`で関数定義するのであれば、使う箇所よりも上のほうに書いておきましょう。であれば、今回はforEachのエラーだけで済んだはずです。エラーが発生する箇所より、後ろに書いたため今回のエラーとなりました。でも理解が深まるはずなので、今回のquerySelectorミスは無駄ではなかったと思います^^
so87

2021/07/07 01:00

少し認識が違うようですと述べさせていただいたのは >>→関数を定義した段階で、timeSelectが初期化=Nullしてしまっていた。 という解釈のところです。関数定義まで来ていない状況なので、「関数を定義した段階」とは表現できないということです。「timeSelectが初期化=Nullされていたので、関数の定義(初期化)ができなかった」という認識なら大丈夫です。 >> 初期化の必要があるということなのでしょうか はい。`関数宣言`と`関数式`で初期化のタイミングが異なるので、それぞれにあった適切な箇所で初期化を行う必要があります。
LEMON_

2021/07/07 12:20

丁寧にご返信ありがとうございます。とても助かっています.... 07/06に送っていただいたものを四苦八苦しながら読ませて貰ってたのですが、7日に送っていただいたもので理解が簡単になりました、ありがとうございます。 まずは、関数式と関数宣言のところですが知識が薄かったため、自分なりに調べてみたところhttps://www.atmarkit.co.jp/ait/articles/1605/18/news018.html 関数宣言と関数式の違いとは?の欄と今回の問題が一致していると思ったので読み、理解出来ました。ありがとうございます。 次に、初期化について認識違いをしており、func1 = "" などの工程が初期化なのかなと勝手に勘違いしていたことが原因でした。関数式と関数宣言のそれぞれ違ったタイミングでの初期化を行っていきます、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問