新JavaScript入門 32

キー入力


このページはちょっと古くなってしまったので、 DOM event(1)event(2)をご覧ください。 そちらの方が正確かつ詳細な説明になっていると思います。
下の例はIE5(?)に対応しました(6/30)。

キー入力

Internet Explorer 4.0ではキー入力のイベントを拾うことができるようになりました。 イベントハンドラは
    onkeydown, onkeypress, onkeyup
の3つです。イベントが発生したときに実行するサブルーチンの指定は、
    window.onkeydown = functionname
などとします。
onkeyupと他の2つの違いは、 イベントが発生するのが押し上げたときか押し下げたときかです。 onkeydownonkeypressは 次に述べる値が違ってきます。

キーの判別方法

どのキーを押されたかの判別は、eventオブジェクトの keyCodeプロパティによって行います。 keyCodeは基本的に押されたキーのUnicodeを返しますが、 実際にはイベントハンドラによって異なってきます。 onkeyupの場合、大文字・小文字・!&#などの記号を Unicodeで返しますが、タブ・バックスペースなどの特殊文字は返しません。 他の2つの場合は、アルファベットはすべて大文字で記号は返しませんが、 タブ・バックスペースなどもコードを返します。

今回、タッチタイプの練習ソフトを作りました。
レベルを選択してボタンを押すと、上の欄に単語が表示されますので、 それに一致するようにキーを押します。 間違えたとき、カーソルキーは効かないのでバックスペースで戻ります。
キーコードはアルファベットの場合、次のようにシフトキーが押されていれば 大文字、押されていなければ小文字としています。キャップスロックは関係ありません。

function getkeycode() {
    var code = event.keyCode;            //コードを得る
    if(48 <= code & code <= 57)         //数字
        ;
    else if(65 <= code & code <= 90) {  //アルファベット
        if(!event.shiftKey)      //シフトキーが押されていない
            code += 32;                 //小文字に
    }
    else if(code == 8)                  //バックスペース
        ;
    else
        code = 0;                       //その他は0
    return code;
}
00:00:00

level 1
level 2
level 3
level 4
level 5

var arrkeys, cl, k;
var isrunning = false;

function start() {
    isrunning = true;
    k = new keys(getlevel());   //表示する単語集のオブジェクト
    cl = new clock();           //時計オブジェクト
    cl.idTimer = setTimeout("clockrun()", 30);
}

//30msごとに時計の表示を変える
function clockrun() {
    cl.next();
    cl.idTimer = setTimeout("clockrun()", 30);
}

//キーが入力されたときの処理
function inputkey() {
    var char, code, str;
    
    if(!isrunning)
        return;
    
    str = div2.innerText;
    
    if((code = getkeycode()) == 8) {    //バックスペース
        if(str.length > 0)
            str = str.slice(0, -1);     //最後の1文字カット
    }
    else if(code > 0)               //コードを文字に変換
        str += String.fromCharCode(code);
    
    div2.innerText = str;           //入力文字を表示
    if(k.isequal(str)) {    //入力した文字と単語が一致したら
        if(!k.next()) {         //次の単語が無ければ
            cl.stop();          //時計ストップ
            cl = "";
            k = "";
        }
        setTimeout('div2.innerText = ""', 30);
    }
    return false;
}

function keys(lev) {
    var i, j, k, len, tmp;
    //データベースから読み取った単語をスクランブルする
    len = arrkeys[lev].length;
    this.arr = new Array(len);
    for(i = 0; i < len; i++)
        this.arr[i] = arrkeys[lev][i];
    for(i = 0; i < 100; i++) {
        j = Math.floor(len * Math.random());
        k = Math.floor(len * Math.random());
        tmp = this.arr[j];
        this.arr[j] = this.arr[k];
        this.arr[k] = tmp;
    }
    this.next = nextkey;
    this.isequal = isequal;
    this.ikey = 0;
    div1.innerText = this.arr[0];
}

function clock() {
    this.time = 0;
    this.start = new Date();
    this.next = clocknext;
    this.stop = clockstop;
    this.draw = clockdraw;
    this.draw();
    this.idTimer;
}

//以下略
ちなみに、私はlevel1で35秒台でした。

first, back, next, exit
Written 7/9/98