<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JavaScript ループ練習アプリ</title>
<style>
body { font-family: "Segoe UI", sans-serif; background: #f8fafc; margin: 2rem; }
h1 { text-align: center; color: #1e293b; }
.question { background: white; padding: 1rem; margin-bottom: 1rem; border-radius: 12px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); }
pre { background: #f1f5f9; padding: 0.5rem; border-radius: 8px; overflow-x: auto; }
textarea { width: 100%; height: 100px; font-family: monospace; font-size: 14px; }
button { margin-top: 0.5rem; padding: 0.5rem 1rem; background: #2563eb; color: white; border: none; border-radius: 8px; cursor: pointer; }
button:hover { background: #1d4ed8; }
.result { margin-top: 0.5rem; font-weight: bold; }
.correct { color: #16a34a; }
.wrong { color: #dc2626; }
</style>
</head>
<body>
<h1>🧩 JavaScript ループ練習アプリ</h1>
<div id="app"></div>
<script>
const questions = [
{
title: "初級①:0〜4を出力する",
prompt: "0, 1, 2, 3, 4 を順番に console.log してください。",
test: () => {
const logs = captureLogs(() => {
// ユーザーコード
userCode();
});
return JSON.stringify(logs) === JSON.stringify(["0","1","2","3","4"]);
},
hint: "for文を使って i を 0 から 4 まで増やしましょう。"
},
{
title: "中級②:配列の合計を出す",
prompt: "配列 [1, 2, 3, 4, 5] の合計を console.log してください。",
test: () => {
const logs = captureLogs(() => userCode());
return logs.includes("15");
},
hint: "for文と += を使って足し算します。"
},
{
title: "上級③:for…ofで配列を出力",
prompt: "配列 ['apple','banana','orange'] を for…of で順に出力してください。",
test: () => {
const logs = captureLogs(() => userCode());
return JSON.stringify(logs) === JSON.stringify(["apple","banana","orange"]);
},
hint: "for (const item of 配列) { console.log(item); }"
}
];
const app = document.getElementById("app");
questions.forEach((q, idx) => {
const div = document.createElement("div");
div.className = "question";
div.innerHTML = `
<h2>${q.title}</h2>
<p>${q.prompt}</p>
<textarea id="code${idx}" placeholder="// ここにコードを書いてください"></textarea>
<button onclick="runTest(${idx})">実行して採点</button>
<div class="result" id="result${idx}"></div>
<p><small>💡ヒント: ${q.hint}</small></p>
`;
app.appendChild(div);
});
function captureLogs(fn) {
const logs = [];
const originalLog = console.log;
console.log = (...args) => logs.push(...args.map(a => String(a)));
try { fn(); } catch(e) { logs.push("Error:" + e.message); }
console.log = originalLog;
return logs;
}
function runTest(i) {
const code = document.getElementById("code" + i).value;
const resultDiv = document.getElementById("result" + i);
try {
userCode = new Function(code);
const ok = questions[i].test();
if (ok) {
resultDiv.innerHTML = "✅ 正解!すばらしい!";
resultDiv.className = "result correct";
} else {
resultDiv.innerHTML = "❌ 出力が違うようです。ヒントを見てもう一度!";
resultDiv.className = "result wrong";
}
} catch(e) {
resultDiv.innerHTML = "⚠️ エラー: " + e.message;
resultDiv.className = "result wrong";
}
}
</script>
</body>
</html>
HTML