50 questions JavaScript





Bonjour mes amis!



J'attire votre attention sur un petit quiz JavaScript interactif, actuellement composé de 50 questions.



À mon avis, résoudre de tels problèmes est le meilleur moyen de déterminer votre niveau de compétence.



Continué ici .



Préface



Cette partie est basée sur ce référentiel . Son auteur, Lydia Hallie, positionne son projet comme une liste de questions avancées et, en effet, parmi elles, il y en a certaines que, je pense, même un développeur JavaScript expérimenté trouvera difficile. Cependant, parmi ces questions, il y a aussi celles pour lesquelles il suffit d'avoir des connaissances de base pour répondre. Il y a une traduction russe dans le référentiel, mais, pour le moins dire, cela laisse beaucoup à désirer, donc la plupart des réponses (explications) ont dû être traduites à nouveau.



Il est à noter que les explications (réponses) fournies ne révèlent pas toujours pleinement l'essence du problème. Cela est dû à la forme du projet - c'est une liste de contrôle, pas un didacticiel. Les réponses sont plutôt un indice pour d'autres recherches sur MDN ouJavascript.ru . Cependant, de nombreuses explications contiennent des réponses complètes.



Bien que le code ait été testé à plusieurs reprises, personne n'est à l'abri des erreurs, bien sûr, sauf ceux qui ne font rien. Par conséquent, si vous trouvez des erreurs, des fautes de frappe, des inexactitudes, des mots incorrects, etc., ainsi que si vous souhaitez améliorer la traduction, veuillez écrire à titre personnel, je vous en serai reconnaissant (l'activité sur GitHub est également encouragée).



En fait, c'est tout ce que je voulais dire en guise de préface.



règles



Les règles sont simples: 50 questions, 3-4 réponses possibles, notation: nombre de réponses correctes et incorrectes, progression: nombre et nombre de questions.



Sur la base des résultats, le pourcentage de bonnes réponses est déterminé et une conclusion est faite sur le niveau de maîtrise de JavaScript: plus de 80% c'est excellent, plus de 50% c'est pas mal, moins de 50% ... eh bien, vous comprenez.



Une explication est jointe à chaque question. Si la réponse est incorrecte, cette explication est divulguée.



En raison du fait que le nombre de réponses correctes et incorrectes, ainsi que le numéro de série de la question, sont enregistrés dans le stockage local, vous avez la possibilité de faire une pause, de faire une pause et à tout moment de continuer à partir de l'endroit où vous vous êtes arrêté.



Passons du quiz lui-même.



Quiz





Le code du projet est ici .



Nous partageons les résultats dans les commentaires.



Mécanique



Quelques mots sur la façon dont le quiz est mis en œuvre pour ceux qui sont intéressés.



Le balisage ressemble à ceci:



<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>


Ajoutez des styles minimaux:



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;
}




Les actifs sont un tableau d'objets, où chaque objet a des propriétés question (question), réponses (réponses), rightAnswer (bonne réponse) et explication (explication):



[
{
    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.
    `
},
...
]


Script principal:



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)




Merci de votre attention.



All Articles