見出し画像

たった14行のJavaScript(jQuery)で超簡単なタインピングアプリを作ってみる

JavaScript(jQuery)の初学者用の記事です。
ごく短いコードでタイピング練習アプリを作ってみます。

今回は一つのファイルでやってみましょう。
ファイル名は何でも構わないのですが、とりあえずtyping.htmlとしておきます。

まずは基本部分を記載します。

<!DOCTYPE html>
<html lang='ja'>
    <head>
        <meta charset='UTF-8'>
        <title>タイピングアプリ</title>
        <style>
            /*cssはここに書く*/
        </style>
        <script
            src="https://code.jquery.com/jquery-3.6.0.js"
            integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
            crossorigin="anonymous"></script>
        <script type='text/javascript'>
            //JavaScriptはここに書く
        </script>
    </head>
    <body>
        <!--HTMLはここに書く-->
    </body>
</html>

ランダムに文字を出力する

まずはHTML部分を書きましょう。
といっても1行だけです。

<div id='display_area'></div>

このファイルをブラウザで開いても、当然何も表示されません。
ではここに何かJavaScriptで表示してみましょう。

JavaScript部分には、まずjQueryを使う時のおまじないです。

            $(function(){
                //以降ここにJavaScriptを追記していく
            })

こんな感じに書きます。

さて、とりあえずはアルファベットの「a」とでも表記してみましょう。
それには、

$('#display_area').html('a');

と書くだけです。
そうすると、画面には

文字がちゃんと表示された

ちゃんと「a」が表示されます。

さて、この段階でせっかくですのでCSSもそれなりに整えておきましょう。

#display_area{
    font-size: 30px;
    font-weight:bold;
    width: 40px;
    padding: 5px;
    background-color:gray;
    color:white;
    text-align:center;
}

とまあこんな感じです。
この状態で画面を表示してみると、こんな感じにそれなりに綺麗に表示されます。

それなりに綺麗に表示

さて、いよいよランダムに表示されるようにします。
今は「a」だけが出るようになっておりますが、aからzの26文字がランダムに出るようにしたいわけです。

それにはまずは配列を作ります。
配列を定義するには

let charactors = ['a','b','c'];

こんな書き方ができます。
ちなみにcharactorとは「性格」「人物」みたいに捉えられがちですが、プログラミング界隈では「文字」という意味で認識しておきましょう。

この書き方でzまで書いてもいいんですが、それだと大変ですね。
ですのでこういう書き方も覚えておくと良いです。

let charactors = 'abcdefghijklmnopqrstuvwxyz'.split('');

これだけでaからzまで、1文字ずつが1つの要素になった配列になります。
まず、
'abcdefghijklmnopqrstuvwxyz'
この部分は、そのまま普通に文字列です。
その後についている.splitというメソッドが肝となります。splitとは「分割」という意味になります。
例えば、

let charactors = 'abc'.split('b')

というふうに書くと、「abcという文字列をbで分割して配列にする」という意味になります。
ですので、これだと0番目の要素がa、1番目の要素がcになります。
splitの引数として与えた文字で分割するわけですね。

さて、先程のコードではsplitの引数を空文字にしておりました。
そうすると、全ての文字間で分割して配列にしてくれます。
結果として、要素の数が26個の配列になったわけです。

ですので、配列を作った状態で

$('#display_area').html(’a');

と書いていた部分を

$('#display_area').html(charactors[2]);

こう書き換えると、26個のうち、0番目から数えて2番目の文字であるcが出力されます。

c が出力された

さて、これだと2番目(0から数えて)文字のcが出るだけですので、ここをランダムに出せるようにしましょう。
[](カギ括弧)の中身を0から25までのランダムな数字にするときは、

$('#display_area').html(charactors[2]);

↓このように書き換える

$('#display_area').html(charactors[Math.floor(Math.random()*26)]);

こんな感じに書いてみましょう。
実行してみると、読み込むたびにランダムに出るのがわかります。

読み込むたびにランダムな文字になる

ここで理解しておくべきはMath.random()とMath.floorです。

まずは試しにこう書いてみてください。

alert(Math.random());

そうすると、実行するたびにランダムな数字がポップアップウィンドウに出るはずです。
ランダムのな数字とはいっても、一定の範囲内ですね。
そう、0より大きく1より小さいランダムな数字を取得するのがMath.random()です。

すなわち数式にすると

0 < Math.random() < 1

という意味合いになりますね。
次にこれを26倍するとどうなるでしょう。
当然最大値も最小値も26倍されるわけですから、

0 < Math.random() * 26 < 26

となります。
つまり、最も小さい数で
0.0000000000001くらい
最も大きい数で
25.999999999999くらい
ということになります。あくまで26にはなりません。
あとはこれを小数点以下を切り捨てれば「0から25までのランダムな整数」になります。
その役割を果たすのがMath.floorなわけですね。
floorはその名の通り「床」です。
数字の一番低いところ→転じて「小数点以下切り捨て」ということになります。

そのため

$('#display_area').html(charactors[Math.floor(Math.random()*26)]);

こういう書き方をすることで、aからzまでの26個のうちからランダムな文字を取り出すことができるわけです。

このままでも機能的には問題ないですが、後々の拡張性を考えて、26という数字ではなく、charactorsという配列の要素の個数を表すcharactors.lengthを使うとより可読性が上がります。
こういうふうに書き換えてみましょう。

$('#display_area').html(charactors[Math.floor(Math.random()*charactors.length)]);

これでランダムな文字が出るようになりましたが、できればこれが1秒おきに変わって欲しいですね。
そういう時に使うのはsetIntervalです。
先程の1行をsetIntervalで囲んで、

setInterval(()=>{
    $('#display_area').html(charactors[Math.floor(Math.random()*charactors.length)]);
},1000);

こう書き換えてみましょう。
そうすると1秒ごとにランダムに文字が切り替わるはずです。

setIntervalは第一引数に実行する内容、第二引数に、それを何ミリ秒おきに実行するか、を指定します。ここでは1000としておりますので、1000m秒(1秒)おきに()=>{…}この中身を実行するわけですね。

現時点でのコードはこのようになります。

<!DOCTYPE html>
<html lang='ja'>
    <head>
        <meta charset='UTF-8'>
        <title>タイピングアプリ</title>
        <style>
            /*cssはここに書く*/
            #display_area{
                font-size: 30px;
                font-weight:bold;
                width: 40px;
                padding: 5px;
                background-color:gray;
                color:white;
                text-align:center;
            }
        </style>
        <script
            src="https://code.jquery.com/jquery-3.6.0.js"
            integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
            crossorigin="anonymous"></script>
        <script type='text/javascript'>
            //JavaScriptはここに書く
            $(function(){
                //以降ここにJavaScriptを追記していく
                let charactors = 'abcdefghijklmnopqrstuvwxyz'.split('');
                setInterval(()=>{
                    $('#display_area').html(charactors[Math.floor(Math.random()*charactors.length)]);
                },1000);
            })
        </script>
    </head>
    <body>
        <!--HTMLはここに書く-->
        <div id='display_area'></div>
    </body>
</html>

押したキーが表示されるようにする。

さて、jQueryをちょっとかじると、clickした時に何かが起きる、という時にはclickイベントを使うことがわかると思います。
ですが、イベントはclickだけではありません。
ここではkeydownイベントを使います。

その名の通り、キーを押したときに起こるイベントです。
試しにJavaScript部分の最後に

$(window).on('keydown',()=>{
    alert('キーが押されました');
})

こう追記してみましょう。

この状態で何らかのキーを押すと

キーを押したのを認識してくれる

このようにalertが出ます。

クリックであればどこをクリックしたか、ということを指定すべきですが、キーを押したときはそのウィンドウさえ開いていればいいわけですから、セレクタの部分は$(window)でいいわけです。

押したキーが何かを認識する

さて、今度はその、押されたキーが何かを認識しなくてはタイピングゲームになりません。
今度は先程追記した部分を

$(window).on('keydown',(event)=>{
    alert(event.originalEvent.key);
})

このように書き換えてください。
この状態でキーをクリックすると、クリックしたキーがalertされます。

pをクリックした時

さて、このeventがわかりずらいですね。
これまではイベントを起こすときに実行する関数では、引数を使ったことがない人が多いと思います。ここで突然、eventという引数が出てきました。

こういうふうに書くと、eventという変数にはそのイベントに関するあらゆる情報が入っております。
どのキーを押されたか、という情報が欲しいときはそのeventに対して

event.originalEvent.key

と書けばそれが押されたキーの情報になります。

eventには実に様々な情報が記載されています。
詳しく知りたいときは、

console.log(event);

をしてみて、コンソールに出力してみると良いでしょう。

さて、alertでは毎回OKを押すのが大変ですので、クリックしたキーがそのまま画面上に表示されるようにします。

まずはHTML部分に

<div id='typing_text'></div>

このように、タイピングした文字を表示する領域を作りましょう。

次にCSSで見やすい感じにします。

#typing_text{
    font-size: 30px;
    font-weight:bold;
    width: 40px;
    padding: 5px;
    background-color:royalblue;
    color:white;
    text-align:center;
}

こんな感じですね。

最後に、JavaScriptの先程のkeydownイベントの中身を書き換えます。

$(window).on('keydown',(event)=>{
    alert(event.originalEvent.key);
})

こう書いていた部分を

$(window).on('keydown',(event)=>{
    $('#typing_text').html(event.originalEvent.key);
})

このように書き換えましょう。
その上で、ブラウザで表示し、いろんなキーを押してみましょう。
そうするとブルーの部分に押したキーが表示されます。


押したキーがリアルタイムに表示される


得点を表示する

さて、最後に得点を表示する部分を作りましょう。
HTML部分に

<p>現在の得点<span id='point'>0</span>点</p>

この1行を追加しましょう。あとはこのspan要素を書き換えるロジックを書けばいいだけです。
まずはキーダウンイベントの前(setIntervalしたロジックの後)に

let point = 0;

を追記します。
また、keydownした時に実行される部分({}波括弧のなか)に

if(event.originalEvent.key === $('#display_area').html()){
    point += 1;
    $('#point').html(point);
}

これを追記しましょう。
JavaScriptの部分の全体は

$(function(){
    //以降ここにJavaScriptを追記していく
    let charactors = 'abcdefghijklmnopqrstuvwxyz'.split('');
    setInterval(()=>{
        $('#display_area').html(charactors[Math.floor(Math.random()*charactors.length)]);
    },1000);
    let point = 0;
    $(window).on('keydown',(event)=>{
        $('#typing_text').html(event.originalEvent.key);
        if(event.originalEvent.key === $('#display_area').html()){
            point += 1;
            $('#point').html(point);
        }
    })
})

こんな感じになるわけですね。
流れとしては

  1. pointの値を0にする

  2. キーが押された時に

  3. そのキーとdisplay_areaに表示された文字が一致していれば

  4. pointに1を足す

  5. span要素の中身をpointで上書きする

という流れになります。

結果、たった14行でタイピングゲームを作ることができましたね。

得点が表示される

最後に、このコードの全体を記しておきます。

<!DOCTYPE html>
<html lang='ja'>
    <head>
        <meta charset='UTF-8'>
        <title>タイピングアプリ</title>
        <style>
            #display_area{
                font-size: 30px;
                font-weight:bold;
                width: 40px;
                padding: 5px;
                background-color:gray;
                color:white;
                text-align:center;
            }
            #typing_text{
                font-size: 30px;
                font-weight:bold;
                width: 40px;
                padding: 5px;
                background-color:royalblue;
                color:white;
                text-align:center;
            }
        </style>
        <script
            src="https://code.jquery.com/jquery-3.6.0.js"
            integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
            crossorigin="anonymous"></script>
        <script type='text/javascript'>
            $(function(){
                let charactors = 'abcdefghijklmnopqrstuvwxyz'.split('');
                setInterval(()=>{
                    $('#display_area').html(charactors[Math.floor(Math.random()*charactors.length)]);
                },1000);
                let point = 0;
                $(window).on('keydown',(event)=>{
                    $('#typing_text').html(event.originalEvent.key);
                    if(event.originalEvent.key === $('#display_area').html()){
                        point += 1;
                        $('#point').html(point);
                    }
                })
            })
        </script>
    </head>
    <body>
        <div id='display_area'></div>
        <div id='typing_text'></div>
        <p>現在の得点<span id='point'>0</span>点</p>
    </body>
</html>

この記事が気に入ったらサポートをしてみませんか?