AsaDesign

【備忘録メモ】JavaScript 30 #1

JavaScript 30 Build 30 things with vanilla JS in 30 days with 30 tutorials javascript30.com

英語で話しているので、Google翻訳に頼りながら理解していきます。

事前説明編

00:00~00:45
作るものの説明:ボタン押下時に、①キーに関連付けられた音をならす ②ボタンが少し大きくなる。(データダッシューキーとは??)

この演習では、とても素敵な JavaScript ドラム キットを作成します。正確には何なのかはよくわかりませんが、演奏するのはとても楽しいもので、キーボードの対応するキーを押すと、2 つのことが行われます。まず、そのキーに関連付けられているサウンドが再生されます。次に、ボタンがポップアップして、必要なサイズより少しだけ大きくなる短いアニメーションが実行されます。これは非常に微妙な動作ですが、ここでどのように動作するかを説明します。ここでは、このキック 1 つを調べます。ここにデータダッシュキーがあります。そして、黄色の枠線と小さな背景が適用されます。これは非常に微妙な機能ですが、ここでどのように機能するかをお見せします。このキック1を調べます。データダッシュキーがあります。すぐに確認しますが、押しても追加されるのがわかりません。

00:53~01:30 
playingクラスの有無でボタンサイズ/境界線の色/背景色を切り替える予定

非常に速く動いているからです。しかし、これはその要素にplayingクラスを追加し、今日の演習を開いてCSSのstalledを見れば、CSSが起動します。playingクラスがあり、CSSで1.1倍に拡大します。境界線の色を変えます。バックシャドウを変えます。ここで通常のキーを見ると、0.07秒のトランジションがあり、非常に高速です。拡大して、その背後の背景色を変えます。これがここにある2つのことです。自分で試してみたい場合は、ここでビデオを一時停止して、これが機能するようにしてください。そうでなければ、先に進んで、作業内容を見てみましょう。

01:40~02:14
各キーボードには紐づいたキーコードがある!
例:「A」キーは「65」、「escape」キーは「27」

ここにkeysクラスのdivがあり、その中にkeyクラスのdivが多数あります。ここでのそれぞれのキーには、当然ながらclapのような音や、キーボードで押すべきキーがあります。しかしここで重要なのは、キーボードのどのキーでも、上または下を押すと、キーアップまたはキーダウンイベントが発生し、そのキーに関連付けられたキーコードと呼ばれるものがあることです。 01:57 これは非常に微妙なことですが、ここでどのように機能するかをお見せします。ここでは、このkick oneを調べます。ご覧の通り、このデータダッシュキーがあります。数年前に作った小さなウェブサイトがあります。いつも検索していたので、keycode.infoというサイトです。キーボードのエスケープやスペース、Aなどのキーを押すと、そのキーに関連付けられた数字が表示されます。これが最も一貫性のあるものです。

02:15~03:05 「data-key」の経緯(データダッシュキーってこれのことかw)

これはブラウザや言語を問わず私が見つけた方法です。完璧ではありませんが、標準的なキーのほとんどをカバーします。クリックしたり、65 を押したり、たとえばキーアップしたときにそれが A キーかどうかを確認し、対応するオーディオ要素を再生します。これにはデータキーもあります。では、このデータダッシュキーとは何でしょうか? 02:46 これまでデータ属性を使用したことがない場合は、これは標準ではありません。Google で検索しても、私がブラウザや言語を問わず見つけた方法です。完璧ではありませんが、標準的なキーのほとんどをカバーします。基本的に、データ属性は、人々が独自の属性を作成していたときに HTML で導入されました。source や class などがあり、これらは標準です。そして人々は独自のHTMLを作り始め、HTMLを作った人たちは「ちょっと待って、ちょっと待って、落ち着いて、

03:13~03:50 data属性は開発者がキーを追加できるようにHTMLが作ってくれたもの。

「何でも好きなように追加し始めることはできない」と。そこで、データ属性というアイデアを思いつきました。キーのようなものを作りたい場合、それをデータのようなものの後ろに置かなければなりません。ここで私がやっていることは、データ属性を使用して、データキー65とデータキーオーディオを接続しています。 03:21 誰かがキーボードのキーを押すと、オーディオ要素を見つけて再生し、キーdivを見つけて再生クラスを追加して、アニメーション化します。では、始めましょう。ここのスクリプトタグに移動して、最初に必要なのは、キーアップイベントをリッスンすることです。これを行うには、まずリッスンする要素を取得します。私たちの場合、

ここで学んだこと

  • 「keydown(キーダウン)」= キーボード押下イベント があるということ
  • 「data-key(データダッシュキー)」開発者がキーを拡張できるデータ属性

音声編

04:00~04:38
イベントリスナー登場。キーダウン(=キーボード押下)イベントを検知させる

ウィンドウをリッスンします。入力やdiv、テキストエリアなどをリッスンしたい場合もあるでしょう。イベントリスナーを追加します。ここでリッスンするイベントはキーダウンです。次に、イベントを取得する関数がありますが、その中には何も入っていません。そして、ここにある残りのものを取り除きます。キーダウンイベントをリッスンし、それが発生したら、イベントを取得する関数を実行します。コンソールにイベントをログします。コンソールを開いてください。キーボードのキーの1つを押すたびに、このキーボードイベントが取得されます。これがEです。イベントは、何が起こったかを説明するデータでいっぱいのオブジェクトで、何が起こったかを教えてくれます。

04:38~05:16
イベント(e)の中を見てみよう
e.keyCodeをログ出力すると、キーボードに対応した番号があるはず。

キーボードのキーを押すと、キーボード イベント (E がそれです) が取得されます。イベントは、何が起こったかを説明するデータでいっぱいのオブジェクトで、実際にどのキーが押されたかなど、さまざまな情報を提供します。ただし、ここで関心があるのはキー コードです。これは、そのキーに関連付けられた番号で、基本的にこの Web サイトはすべてこのコードです。誰かがキーを押すと、対応する番号が表示されます。ここで、e.keyCode をログに記録して、取得結果を確認します。これで、さまざまな情報を取得できました。スペース バーを押すと、32 が取得されます。エスケープ キーを押すと、27 が取得されます。次に、必要なのは、「データ ダッシュ キーが 65 であるオーディオ要素がページにあるかどうか」を調べることです。

05:29~06:04
特定のキーを取得する方法:document.querySelectorを使う。
識別するためには、「class=key-65」ではなく独自のデータ属性を使うのがおすすめ。「data-key=”65″」のように書く。

document.querySelector を使用します。これは、1 つだけを検索するためです。複数を検索する場合は、query selector allを使用しますが、この場合はクエリ セレクターのみです。オーディオをリッスンし、オーディオ要素を選択しようとしますが、データ キーがある要素を選択します。ここにはクラスはありません。時々、「class=key-65」のように分割して、キー 65 のクラスを選択する人がいます。これは少し面倒です。ここでは独自のデータ属性を使用することをお勧めします。属性セレクターを使用できます。CSS でこれを使用したことがある場合、JavaScript でも同じように機能します。属性セレクターは、「data-key=」のように記述します。通常は 65 になりますよね。ただし、これは変数になります。

データ取得方法

06:16~07:00
「document.querySelector(`audio[data-key={$e.keyCode}]`)」❌取れない
「document.querySelector(`audio[data-key={$e.keyCode}]`)」⭕️取れる

これはこのイベント内にあります。それで、これをバックテキストに切り替えて、ES6 テンプレート文字列 (ドル記号の中括弧で囲まれた “e.keyCode” など) を使用します。これで、console.log(audio) を実行して、実際のオーディオ要素が選択されているかどうかを確認できます。更新して、A ボタンを押します。エラーが発生し、audio(data-key=65) は有効なセレクタではありません。ここで何をしたのでしょうか。この実際のキーを引用符で囲む必要があると思います。うまくいくかどうか確認してみましょう。A を押します。これで完了です。実際の数字を引用符で囲む必要があるようです。キーを押して S を押したら、D を押します。特定のキーに対応するオーディオ要素を取得していることがわかります。

07:10~08:09
ここまでの挙動:

  • <audio>設定しているAやSキーを押すと音が鳴る。
  • <audio>設定していないQキーを押すと何も鳴らない。nullを返す。
  • Fキーを連打しても、たまにしか鳴らない。理由は、「今再生中だから💢」ということらしい。

押します。Qを押します。null が返されます。なぜ null が返されるのでしょうか? それは、81 に関連付けられたオーディオ要素がないためです。すぐに、オーディオがない場合、つまりオーディオがない場合は、戻ると指定できます。これで関数の実行が完全に停止します。よし、停止します。このオーディオ要素があるので、再生できます。試してみましょう。S、D、F。これである程度は機能しますが、ここで F を何度も押します。F、F、F、F。複数回押していますが、実際には時々 1 回しか再生されません。これは、オープン ハット F が再生され、実際に終了するまでに 2、3 秒かかるためです。すでに再生中のオーディオ要素に対して再生を呼び出した場合、再度再生されることはありません。「ああ、なぜそんなことをする必要があるんだ?明らかにすでに再生中だから」という感じだからです。

08:17~08:56
連打するたびに音を出す対応:
「audio.currentTime = 0」で秒数をリセットしてから「audio.play()」で音出す。(ほえ〜〜これだけ)(currentTimeってなんだ?↓)

currentTimeに新しい値を設定すると、メディアが利用可能であれば、指定された時刻にシークします。

HTMLMediaElement: currentTime プロパティ

その前に、要素の先頭に巻き戻す必要があります。そうすれば、連続して何度も何度も押すと、先頭に巻き戻されます。「audio.currenTime=0」としましょう。これで先頭に巻き戻されます。そして、F を押すと、AAAA、SSS、DDD、FFF が何度も繰り返されます。繰り返し再生されます。キーボードの他のキーも試してみますが、何も起こりません。これはオーディオ要素がないかどうかをチェックしているからです。次に、対応するキーを選択する必要があります。ここにある小さなアニメーションを追加したいからです。「const key=」としましょう。この全体を切り替えます。

描画編

09:04~09:51
クリックされた要素だけを取得する方法:
「document.querySelector(`.key[data-key={“$e.keyCode”}]`)」
<div data-key=”65” class=”key“>…省略…</div> が取得できる。

ドットキーでオーディオ要素を選択する代わりに、div またはこの場合はキーのクラスとデータ ダッシュ キーを持つものを選択できます。では、ここの一番下に移動して、実際のキー要素をコンソール ログに記録してみましょう。これらが対応するキー要素です。これらの要素にこのクールなアニメーションをさせるにはどうすればよいでしょうか。もう一度、style.CSS に戻ってみると、CSS のスタイルはすでに設定されています。このほとんどが重要ではありませんが、ここにある 0.07 秒の transition という 1 行だけは重要です。これに playing というクラスを追加すると、拡大して境界線の色を変更し、ボックスの影の色を変更します。つまり、次のようにします。

10:02~10:45
クリックされた要素に「playing」クラスを付与しよう:
key.classList.add(“playing”);
これで、クリックされた要素だけにplayingクラスに設定した描画がされるようになる。ただし、removeしてないので状態はそのまま。

「key.classList.add」と書いて、「playing」と書きます。これを使ったことがなく、jQuery に慣れているだけなら、「key.addClass(playing)」と同じことになります。ただし、ここでは jQuery は使用しておらず、Vanilla JavaScript を使用しているだけなので、Vanilla JavaScript ではこのように行います。.classList を呼び出し、add します。同様に、.remove と .toggle もあり、これを使用して、必要なさまざまなクラスを追加したり削除したりできます。それでは、S、D、F がどのように機能するかを見てみましょう。これらが追加されているのがわかりますか? もう少し遅く動作を確認したい場合は、CSS を開いてこれを変更します。スケールを 2 にして、遷移を 1.07 秒にします。ここで D を押すと、1 秒後に F、G が表示されます。

11:01~11:53
クラスを消すための話:
ボタンを元に戻すために、タイムアウトを設定するのはおすすめしない。

これが実際に起こっていることですが、0.07秒という非常に短い時間で実行したため、非常に高速に実行され、また、それほどスケールアップしたくありませんでした。さて、これはうまくいきましたが、なぜそれが消えないのでしょうか。これは、クラスを追加しているが、まだクラスを削除していないためです。「ああ、問題ない、ここでタイムアウトを設定して、ここで関数を実行し、0.07秒後に実行する」と思うかもしれません。まあ、それは問題ありませんが、ここでタイムアウトを設定し、CSS JavaScriptにもタイムアウトを設定した場合、デザイナーが「ちょっとおかしい。0.9に変更しよう。少しましだと思う」と言って、同期が取れなくなる傾向があります。

12:02~12:47
クラスを消すための話:
transition終了イベント、クリックイベントを使おう

そして、JavaScript で、これも整列させる必要があります。タイマーを設定するのではなく、アニメーションが停止したときに発生するトランジション終了イベントを使用できます。では、トランジション終了イベントとは何でしょうか。少し戻って、クリック イベントとは何でしょうか。クリック イベントは、何かをクリックすると、イベントが発生し、「誰かがクリックしました」と表示されます。また、JavaScript には、「クリックされなかったが、トランジションが発生しました。スケール 1 の黒のボーダーからスケール 1.1 の黄色のボーダーにトランジションしました」というイベントもあります。これが、黒のボーダーであるここから、黄色のボーダーであるここへ移動するものです。つまり、トランジション終了イベントが発生するタイミングを各キーでリッスンすることができます。では、それを実行してみましょう。

クラスを消す 実践1:audio要素を取得

12:59~13:39
9つのaudio要素全て取得する

const keys = document.querySelectorAll(.key)

まず、ここへ行って「const key=」とします。ページ上のすべてのキーを選択する必要があります。各キーをリッスンしたいからです。「document.querySelector」とします。クエリセレクターを「すべて」にし、「ドットキー」とします。ここでコンソールで実行して、結果を見てみましょう。一致したすべての要素の配列が得られます。よし、それでは、各キーで transition end というイベントをリッスンします。これは「keys.forEach」のようなもので、各キーを取得します。なぜこれをしなければならないのか、なぜ「keys.addEventListener」を実行して transition end をリッスンできないのか疑問に思うかもしれません。これは、jQuery などを使用している場合、

クラスを消す 実践2:audio要素にイベントリスナーをアタッチ

13:50~14:32
キーを使って、9つのaudio要素にイベントリスナーをアタッチする。これで、キーをクリックした時にremoveTransition関数が動く。
※removeTransitionはこれから作る関数

keys.forEach(key => key.addEventListener('transitionend', removeTransition)

問題は、要素の配列がある場合、すべての要素をリッスンできないことです。すべての要素を明示的にループして、イベント リスナーをアタッチする必要があります。そのため、私にとって最も簡単な方法は、キーを使用する方法です。ここでは、矢印関数を使用します。ES6 シリーズを読んだことがある方はご存知かと思いますが、「key.addEventListener」です。次に、リッスンするリスナーは transition end です。これが終了すると、「remove transition」という関数を実行します。これを作成する必要があります。ここで簡単に見てみましょう。各キーに、transition end というイベント リスナーが追加されます。トランジションが終了すると、それを削除します。ここで実際にその関数を作成する必要があります。「function remove Transition」とします。

クラスを消す 実践3

14:45~15:29
removeTransition関数を用意

function removeTransition(e) {
 console.log(e);
}

現状、一つキーをクリックしたら6回ログが出るw なぜかというと、変化したcssが6つあるから。(transform, box-shadow, border-right-color, border-left-color, border-bottom-color, border-top-color)

私たちにイベントを与えてください。その中で、ここで何を行っているかを確認するために、イベントをコンソールに記録します。それで、A を押します。おっと、ここで何が起こったのでしょうか?さて、少し大きくなった 1 つの小さなフェードインに対して、1、2、3、4、5、6 つのトランジション終了イベントがあります。それは、ここで多くのことが移行したからです。境界線の右の色の遷移、すべての境界線が遷移しました。小さな黄色の輝きであるボックスの影が変化しました。そして、変身も終わった。さて、これらすべてについてはあまり気にしません。私たちは、1 つのビデオの修正、説明、コピーペーストが完了したら、それを実行したいと考えています。それでは、変換を選択しましょう。それでは、「if e」としましょう。ここで私たちが探していたイベントは何でしたか

クラスを消す 実践4:transform以外はreturn

15:40~16:28
transformだけに用があるので、それ以外はreturnする。(transformに用事あるの?)これで、キー押下時のログは「transition」と1回だけ出力される。

function removeTransition(e) {
 if(e.propertyName !== "transform") return // 追記
 console.log(e.propertyName);
}

「event.propertyName」です。transition と等しくない場合は戻ります。次に、「transform でない場合はスキップ」とします。transform です。transition ではありません。私はいつも間違えてしまいます。コンピューターの画面越しに私に怒鳴ってくれてありがとう。では、次は何でしょうか。コンソール ログ e.propertyName を実行しましょう。ここで何を操作しているか見てみましょう。transition が終了したときに実行される関数があります。何が起こっているかわかりますか。終了するプロパティが transform であるため、コンソール ログに単語が記録されています。これは非常に高速に実行されますが、この transform を 2.07 秒に変更して A、1、2 を押すと、数秒かかり、その時点で終了しました。偶然にも、なぜ偶然なのでしょうか。それがこれを実行したい理由です。

クラスを消す 実践5:thisで要素を指定して削除

16:39~17:27
thisの中身をconsole.logで見ると、<div data-key=”65″ class=”key”>…省略…</div> だよ。という話。
そのthisを使って、ついにplayingクラスを削除できる。

function removeTransition(e) {
 if(e.propertyName !== "transform") return
 this.classList.remove("playing"); // 追記
}

普通に「これ」って訳されるから怪文になる泣

それが起こったら、それが動き終わったら、それについて知っていることすべてを元に戻します。ここでトランジションの削除関数に進み、まず「これ」を保存します。では、「これ」は何に等しいのでしょうか? 「これ」が何に等しいのか理解するのが難しい場合は、「これ」が何に等しいのか理解するための非常に安っぽい方法ですが、まずコンソールログに記録してそれが何であるかを確認します。これはそれを見つけるのに良い方法です。それで、Aを押して、2秒後、まだ2秒です。これはキーに等しいです。なぜでしょうか? 「これ」は常に、それに対して呼び出されたものに等しいからです。それで、イベントリスナーが呼び出されました、それに対して何が呼び出されたか、キー。つまり、これは実際のキーに等しいです。それで、.classlist.removeで、プレイのクラスを削除します。保存します。今、2秒なので、それを押します。2秒後、

17:37~18:23
クラスを消す:動作確認
現時点でキーをクリックすると①音が鳴る ②Dのaudio要素だけゆっくり拡大③ゆっくり縮小する。ゆっくりなのは、cssでtransitionを2秒に設定しているから。
開発者ツールを見ると、Dのaudio要素だけplayingクラスが自動で付与+除去されているのが分かる。

トランジション終了が発動し、再生中のトランジションが削除され、フェードアウトします。それで、Dを押します。これで完了です。クラスが削除されます。これを調べて、ここを見てください。再生中のクラスがあり、2秒後に削除されます。 CSSに戻って、これを0.07秒に戻すと、すべてがすばやく実行されます。すぐに実行されます。divツールで再生中のクラスを追加した場合も同じことが起こります。JavaScriptがその要素をリッスンして削除を待機しているため、それでも削除されます。最後に、HTMLに進みます。私はこれらの関数をHTMLの要素に直接追加するのはあまり好きではありません。

18:34~19:29
リファクタリング:
リッスン後の処理を「playSound」という関数にまとめる

キーをここに押し下げます。これを独自の関数に入れて、サウンド再生を呼び出します。「function playSound」としましょう。ここにすべてのロジックを入れます。イベントを受け取り、イベント リスナーを一番下に下げます。誰かがキーを押したらサウンドを再生します。これで、キーが押されたときにサウンドが再生されます。これで、キーが保持されます。これで問題なく動作します。キーとサウンドを分離しておけるので、他の何かに基づいてサウンドを再生したい場合も、問題なく実行できます。これが基本的な JavaScript ドラム キットです。繰り返しになりますが、キー イベントとオーディオの再生、トランジション終了イベントのリッスンについて学びました。同様に、アニメーションも扱っている場合は、アニメーション終了イベントをリッスンできます。これはまったく同じ方法で動作します。ありがとうございました。次回もご覧ください。

復習

「ボタン押下時に、①キーに関連付けられた音をならす ②ボタンが少し大きくなる。」という機能の実装

コード

HTML

/* data-keyは開発者が拡張できるキー */
<audio data-key="65" class="key" srcz="sounds/dram.wav"></audio>

JacaScript

/**
* playSound
* キーに対応する音を鳴らす
* 描画を変えるため、playingクラスを付与する
*/
function playSound(e) {
// イベント発火の原因を取得
const audio = document.querySelector(`audio[data-key="{$e.keyCode}"]`);
const key = document.querySelector(`.key[data-key="{$e.keyCode}"]`);

// audio要素以外がクリックされている場合はreturnする
if (!audio) return;

// 再生秒数を0にリセットしてから再生
audio.currentTime = 0;
audio.play();

key.classList.add('playing');
}

/**
* removeTransform
* 描画を元に戻すため、
* playingクラスを外す
*/
function removeTransform(e) {
// eの中にはe.propertyNameがある
// transform以外のcssに用はないのでreturnする
if (e.propertyName !== 'transform') return;

// thisの中には<div>...</div>がある
// transformが来たら、playingクラスを解除する
this.classList.remove('playing');
}

// 要素を取得する
const keys = document.querySelecterAll('.key')
// 【keyクラスがついている9つのaudio要素】transform終了イベントリスナーを付けておく
keys.forEach(key => key.addEventListener('transformend', removeTransform));


// 【画面全体】キーボード押下イベントリスナーを付けておく
window.addEventListener('keydown', playSound);

CSSは省略。

アロー関数まだ慣れないな…。こう書いてしまう。

keys.forEach(key){
key.addEventListener('transformend', removeTransform)
}

実装手順

① イベントリスナーを付けたい要素を取得(windowの場合は不要)

  • document…document.querySelecterAll(‘クラス名’)

② イベントリスナーを付ける

  • window.addEventListener(‘keydown’, playSound);
  • key.addEventListener(‘transformend’, removeTransform);

③ イベント発火時に行う処理を関数にまとめる

  • playSound
  • removeTransform

要素識別方法の技

  • HTMLで「data-key=”65″」と書いて、JavaScriptで「e.keyCode」と書くと「65」が取得できる。

その他知ったこと

  • audio.currentTime = 0; を最初に書いて秒数をリセットしないと、連打しても反応しない
  • audio.play(); で音声再生できる