[JS]Javascriptを使ったタイピングゲーム

練習のために JavaScript を使った簡易タイピングゲームを作ってみました。
単語一覧の中からランダムに出題され、制限時間以内にいくつ入力できたかを計測します。

DEMO

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
// 単語
var wordList = [
	"Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India",
	"Juliett", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo",
	"Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-ray", "Yankee", "Zulu"
];

// 時間制限
var timeLimit = 30;

var timer1;
var wordStr;
var wordChars;
var charIndex;
var messageArea;
var wordArea;
var typeArea;
var score;
var timeLeft;

window.onload = function (){
	messageArea = document.getElementById("message");
	wordArea    = document.getElementById("word");
	typeArea    = document.getElementById("type");
	startButton = document.getElementById("start-button");
}

// 3秒後に開始
function onStartButtonClick(){
	messageArea.textContent = "Ready?";
	setTimeout("startTyping()", 3000);
}

// 開始
function startTyping(){
	score = 0;
	timeLeft = timeLimit;
	nextWord();
	countDown();
	timer1 = setInterval("countDown()", 1000);
	startButton.disabled = true;
}

// 終了
function stopTyping(){
	clearInterval(timer1);
	wordChars = [];
	messageArea.textContent = "Score: " + score;
	wordArea.textContent = "";
	typeArea.textContent = "";
	startButton.disabled = false;
}

// 次の単語を表示
function nextWord(){
	charIndex = 0;
	var random = Math.floor( Math.random() * wordList.length );
	wordArea.textContent = wordList[random];
	typeArea.textContent = "";
	wordChars = wordList[random].toUpperCase().split('');
}

// 残り時間を計測
function countDown(){
	if(timeLeft <= 0) {
		stopTyping();
		return;
	}
	messageArea.textContent = timeLeft + " sec.";
	timeLeft--;
}

// キー押下時の処理
document.onkeydown = function (e){
	var keyStr;
	if(e.keyCode == 189){
		keyStr = "-";
	} else {
		keyStr = String.fromCharCode(e.keyCode);
	}
	
	if(wordChars[charIndex] == keyStr){
		charIndex++;
		typeArea.textContent = typeArea.textContent + keyStr;
		if(charIndex== wordChars.length){
			score++;
			nextWord();
		}
	}
};
</script>
</head>
<body>

<form><p><input type="button" id="start-button" value="Start" onClick="onStartButtonClick()">
<span id="message">Press Start</span></p></form>

<hr>

<div style="font-weight: bold;" id="word">&nbsp;</div>
<div id="type">&nbsp;</div>

</body>
</html>

単語を split() で一文字ごとに区切り、入力した文字と先頭の文字が一致すれば一文字進めます。同様にその文字と一致すれば更に一文字進め、最後まで到達したら別の単語を表示します。

タイマーで残り時間を計測し、時間が来たらスコアを表示して終わります。

[JS][jQuery]フォームから複数のファイルをアップロード(入力欄の動的追加)

フォームを使ってアップロードする際、ファイル数を制限することなくアップロードをする場合、たいていは jQuery UploadFilePlupload などの高性能なプログラムを利用するケースがほとんどだと思いますが、単純に必要な数だけファイル入力欄が表示されていれば良いという程度であれば次のようなものでも十分実現できます。

<!DOCTYPE html>
<html>
<head>
<title>File Upload</title>
<meta charset="utf-8">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$("document").ready(function(){
	$(".fileinput").change(fileInputChange);
});

function fileInputChange(){
	if($(".fileinput").last().val() != ""){
		$("#filelist").append('<li><input type="file" name="uploadfile[]" class="fileinput" /></li>')
		.bind('change', fileInputChange);
	}
}
</script>
</head>
<body>

<form action="upload.php" method="post" enctype="multipart/form-data">
<ul id="filelist">
  <li><input type="file" name="uploadfile[]" class="fileinput" /></li>
</ul>
<p><input type="submit" value="Upload" /></p>
</form>

</body>
</html>

form

初期状態ではファイル入力フィールドは1つだけ表示されていますが、ファイルを指定すると新しいフィールドが動的に追加されます。原理的には最後の項目が空欄でなければ新しい input フィールドを自動追加するというものです。

万一ブラウザで JavaScript が無効化されていたとしても最低1つはアップロードできます。

もちろん <input> に「multiple」を指定するという方法でも一度に複数のファイルを選択できますが、フォルダをまたいだ選択や、順序が重要なケースでは使いにくいこともあるのでこういったシンプルな方法を取るのもひとつの手だと思います。

[PHP, JS]jQuery UI autocompleteを使った自動補完(候補予測)

キーワード検索を行う際、入力欄に文字の一部を入力すると当てはまる単語をリストアップしてくれるオートコンプリート(自動補完)機能は便利です。
jQuery UI には Autocomplete というウィジェットが用意されており、それを使えば簡単に実現できます。
あらかじめ単語が決まっていて、数が少ないのであればそのまま Javascript 内に単語一覧を書いてしまえばいいのですが、MySQL などのデータベースに登録されている情報を元に候補一覧を表示したい場合、Ajax を利用して PHP などから動的に取得する必要があります。

form.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Auto Complete</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/jquery-ui.min.js"></script>
<script>
$(function() {
	$("#sample").autocomplete({
		source: "./autocomplete.php"
	});
});
</script>
</head>
<body>

<form>
<input type="text" id="sample" />
</form>

</body>
</html>

autocomplete.php

<?php
// 単語のリスト
$list = array(
	'Apple',
	'Orange',
	'Grape',
	'Banana',
	'Pear',
	'Melon',
	'Peach',
	'Lemon'
);

$words = array();

// 現在入力中の文字を取得
$term = (isset($_GET['term']) && is_string($_GET['term'])) ? $_GET['term'] : '';

// 部分一致で検索
foreach($list as $word){
	if(mb_stripos( $word, $term) !== FALSE){
		$words[] = $word;
	}	
}

header("Content-Type: application/json; charset=utf-8");
echo json_encode($words);

必要となるのはフォームの記述されたファイルと Ajax 処理を行う PHP ファイルです。
データの受け渡しは JSON で行われ、テキストボックスに現在入力中の文字は通常 term に格納されて渡されます。
サンプルでは単純に固定の単語一覧を JSON に変換して表示していますが、データベースから取得する場合は WHERE ~ LIKE で絞り込んだ単語一覧を JSON に変換します。データベースへの負荷を減らすためにセッション等にキャッシュするのも良いと思います。
デフォルトでは一文字入力していれば候補を表示しますが、オプションで minLength を指定すれば最小文字数を変更できます。

$( "#sample" ).autocomplete({
    source: "./autocomplete.php",
    minLength: 3
});

参考: Autocomplete Widget
http://api.jqueryui.com/autocomplete/