こんにちは!
私は、現在50の質問で構成されている小さなインタラクティブなJavaScriptクイズに注目します。
私の意見では、そのような問題を解決することがあなたのスキルレベルを決定するための最良の方法です。ここに
続く。
序文
この部分はこのリポジトリに基づいています。その作者であるLydia Hallieは、彼のプロジェクトを高度な質問のリストとして位置づけており、実際、その中には、経験豊富なJavaScript開発者でさえ難しいと感じるものもいくつかあります。ただし、これらの質問の中には、回答するための基本的な知識があれば十分なものもあります。リポジトリにはロシア語の翻訳がありますが、控えめに言っても、まだ十分とは言えないので、ほとんどの回答(説明)を再度翻訳する必要がありました。
提供された説明(回答)が必ずしも問題の本質を完全に明らかにしているわけではないことに注意してください。これはプロジェクトの形式によるものです-これはチェックリストであり、チュートリアルではありません。答えは、MDNまたはJavascript.ru。ただし、多くの説明には包括的な回答が含まれています。
コードが何度もテストされているという事実にもかかわらず、何もしない人を除いて、誰もがエラーの影響を受けません。したがって、エラー、タイプミス、不正確、不適切な表現などを見つけた場合や、翻訳を改善したい場合は、個人的に書いてください。感謝します(GitHubでの活動も推奨されます)。
序文として言いたかったのはこれだけです。
ルール
ルールは単純です:50の質問、3〜4の可能な答え、評価:正解と不正解の数、進行状況:質問の数と数。
結果に基づいて、正解のパーセンテージが決定され、JavaScriptの習熟度のレベルについて結論が出されます。80%以上は優れている、50%以上は悪くない、50%未満...まあ、わかります。
各質問には説明が付いています。答えが正しくない場合は、この説明を公開します。
正解と不正解の数、および質問のシリアル番号がローカルストレージに記録されるため、一時停止したり、休憩したり、中断した場所からいつでも続行したりすることができます。
クイズ自体から進みましょう。
クイズ
プロジェクトコードはこちらです。
結果はコメントで共有します。
力学
興味のある人のためにクイズがどのように実装されているかについて一言。
マークアップは次のようになります。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>200+ JavaScript</title>
<!-- -->
<link href="https://fonts.googleapis.com/css2?family=Ubuntu&display=swap" rel="stylesheet">
<!-- -->
<link rel="stylesheet" href="style.css">
<!-- "" -->
<script type="module" src="script.js"></script>
</head>
<body></body>
最小限のスタイルを追加します。
CSS:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Ubuntu, sans-serif;
font-size: 1em;
text-align: center;
letter-spacing: 1.05px;
line-height: 1.5em;
color: #111;
user-select: none;
}
@media (max-width: 512px) {
* {
font-size: .95em;
}
}
html {
position: relative;
}
body {
padding: 1em;
min-height: 100vh;
background: radial-gradient(circle, skyblue, steelblue);
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
}
h1 {
margin: .5em;
font-size: 1.05em;
}
output {
margin: .5em;
display: block;
}
.score {
font-size: 1.25em;
}
form {
text-align: left;
}
form p {
text-align: left;
white-space: pre;
}
form button {
position: relative;
left: 50%;
transform: translateX(-50%);
}
button {
margin: 2em 0;
padding: .4em .8em;
outline: none;
border: none;
background: linear-gradient(lightgreen, darkgreen);
border-radius: 6px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .4);
font-size: .95em;
cursor: pointer;
transition: .2s;
}
button:hover {
color: #eee;
}
label {
cursor: pointer;
}
input {
margin: 0 10px 0 2em;
cursor: pointer;
}
details {
font-size: .95em;
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 90%;
background: #eee;
border-radius: 4px;
cursor: pointer;
}
details h3 {
margin: .5em;
}
details p {
margin: .5em 1.5em;
text-align: justify;
text-indent: 1.5em;
}
.right {
color: green;
}
.wrong {
color: red;
}
アセットはオブジェクトの配列であり、各オブジェクトには、プロパティ(質問)、回答(回答)、rightAnswer(正解)および説明(説明)があります。
[
{
question: `
function sayHi() {
console.log(name);
console.log(age);
var name = "Lydia";
let age = 21;
}
sayHi();
`,
answers: `
A: Lydia undefined
B: Lydia ReferenceError
C: ReferenceError 21
D: undefined ReferenceError
`,
rightAnswer: `D`,
explanation: `
name var. , name . Name undefined , , Lydia. name, , undefined. , let ( const), , var, . . " ". , JavaScript ReferenceError.
`
},
...
]
メインスクリプト:
JavaScript
// -
import assets from './assets.js'
// IIFE
;((D, B) => {
// -
const title = D.createElement('h1')
B.append(title)
// :
const score = D.createElement('output')
score.className = 'score'
B.append(score)
// :
const progress = D.createElement('output')
progress.className = 'progress'
B.append(progress)
// ,
const div = D.createElement('div')
B.append(div)
//
// 0
let rightAnswers = +localStorage.getItem('rightAnswers') || 0
let wrongAnswers = +localStorage.getItem('wrongAnswers') || 0
//
// 0
let i = +localStorage.getItem('i') || 0
//
showQuestion()
//
updateScoreAndProgress()
function showQuestion() {
//
// , ,
//
if (i === assets.length) {
return showResult()
}
// - -
const titleText = {
4: ` ?`,
9: ` ?`,
12: ` `,
13: ` ?`,
14: ` ?`,
20: ` sum?`,
21: ` cool_secret?`,
23: ` ?`,
25: ` : this`,
27: ` ?`,
29: ` ?`,
30: ` event.target ?`,
33: ` ?`,
34: ` ""?`,
38: ` JavaScript `,
39: ` ?`,
40: ` ?`,
41: ` setInterval?`,
42: ` ?`,
48: ` num?`,
49: ` ?`
}
title.textContent = titleText[i] || ` ?`
// - ,
// , ,
const {
question,
rightAnswer,
explanation
} = assets[i]
// - input type="radio",
// ( - \n)
// - ,
// slice(1, -1),
//
const answers = assets[i].answers
.split('\n')
.slice(1, -1)
.map(i => i.trim())
// HTML-
const template = `
<form action="#">
<p><em>:</em><br> ${question}</p>
<p><em> :</em></p><br>
${answers.reduce((html, item) => html += `<label><input type="radio" name="answer" value="${item}">${item}</label><br>`, '')}
<button type="submit"></button>
</form>
<details>
<summary> </summary>
<section>
<h3> : ${rightAnswer}</h3>
<p>${explanation}</p>
</section>
</details>`
//
div.innerHTML = template
//
const form = div.querySelector('form')
//
form.querySelector('input').setAttribute('checked', '')
//
form.addEventListener('submit', ev => {
//
ev.preventDefault()
//
const chosenAnswer = form.querySelector('input:checked').value.substr(0, 1)
//
checkAnswer(chosenAnswer, rightAnswer)
})
}
function checkAnswer(chosenAnswer, rightAnswer) {
//
let isRight = true
// ,
// ,
// ,
// ,
//
// false
if (chosenAnswer === rightAnswer) {
rightAnswers++
localStorage.setItem('rightAnswers', rightAnswers)
} else {
wrongAnswers++
localStorage.setItem('wrongAnswers', wrongAnswers)
isRight = false
}
//
const button = div.querySelector('button')
//
if (isRight) {
//
title.innerHTML = `<h1 class="right">!</h1>`
//
button.disabled = true
//
//
//
const timer = setTimeout(() => {
updateScoreAndProgress()
showQuestion()
clearTimeout(timer)
}, 1000)
//
} else {
//
title.innerHTML = `<h1 class="wrong">!</h1>`
//
div.querySelectorAll('input').forEach(input => input.disabled = true)
//
div.querySelector('details').setAttribute('open', '')
//
button.textContent = ''
//
//
//
button.addEventListener('click', () => {
updateScoreAndProgress()
showQuestion()
}, {
once: true
})
}
//
i++
//
localStorage.setItem('i', i)
}
function updateScoreAndProgress() {
//
score.innerHTML = `<span class="right">${rightAnswers}</span> - <span class="wrong">${wrongAnswers}</span>`
//
progress.innerHTML = `${i + 1} / ${assets.length}`
}
function showResult() {
//
const percent = (rightAnswers / assets.length * 100).toFixed()
//
let result
//
// result
if (percent >= 80) {
result = ` ! JavaScript.`
} else if (percent > 50) {
result = ` , .`
} else {
result = `, JavaScript.`
}
//
B.innerHTML = `
<h1> </h1>
<div>
<p> : <span class="right">${rightAnswers}</span></p>
<p> : <span class="wrong">${wrongAnswers}</span></p>
<p> : ${percent}</p>
<p>${result}</p>
<button></button>
</div>
`
//
//
// ,
//
B.querySelector('button').addEventListener('click', () => {
localStorage.clear()
location.reload()
}, {
once: true
})
}
})(document, document.body)
清聴ありがとうございました。