0
\$\begingroup\$

I built this web app to present a random group of questions for quizzes and tests. The page opens with random questions. Clicking anywhere shows (only) the spinner div. Clicking anywhere again brings up new questions.

One thing is bothering me, though. I have succeeded in moving all the JS out of the body except for this:

<div id="click" onclick="location.reload();">

I've tried using this in the script section, but it hasn't worked for me:

document.getElementById('click').onclick = location.reload();

Looks like it should do the same thing, but it doesn't, so I'm out of ideas. Other feedback is welcome, too.

jsFiddle

<!DOCTYPE html>

<html>

<head>
    <meta charset="utf-8">
    <title>Random Test Questions</title>

    <!-- Mobile viewport-->
    <meta name="viewport" content="width=device-width, height=device-height,initial-scale=1.0, user-scalable=no">

    <script language="javascript">
        // change questions here -- in quotes, comma separated
        function setUP() {
            var questionSets = [
                ["Set 1 Question 1", "Set 1 Question 2", "Set 1 Question 3", "Set 1 Question 4", "Set 1 Question 5"],
                ["Set 2 Question 1", "Set 2 Question 2", "Set 2 Question 3", "Set 2 Question 4", "Set 2 Question 5"],
                ["Set 3 Question 1", "Set 3 Question 2", "Set 3 Question 3", "Set 3 Question 4", "Set 3 Question 5"],
                ["Set 4 Question 1", "Set 4 Question 2", "Set 4 Question 4", "Set 4 Question 4", "Set 4 Question 5"],
                ["Set 5 Question 1", "Set 5 Question 2", "Set 5 Question 5", "Set 5 Question 4", "Set 5 Question 5"]
            ];

            for (var setIndex = 0; setIndex < questionSets.length; ++setIndex) {
                var questionSet = questionSets[setIndex];
                var questionIndex = Math.floor(Math.random() * questionSet.length);
                var question = questionSet[questionIndex];
                var selector = '#questions div:nth-child(' + (setIndex + 1).toString() + ')';
                document.querySelector(selector).innerHTML = question;
                //alternative method follows -- comment out above two lines, uncomment below two lines
                //var setId = 'set_' + (setIndex + 1).toString();
                //document.getElementById(setId).innerHTML = question;
            }
        }

        function showQuestions() {
            document.getElementById('spinner').style.display = "none";
            document.getElementById('click').style.display = "none";
            document.getElementById('questions').style.display = "block";

        }

        function showSpinner() {
            document.getElementById('questions').style.display = "none";
            document.getElementById('click').style.display = "block";
            document.getElementById('spinner').style.display = "block";
        }

        function startTimer(duration, display) {
            var timer = duration,
                minutes, seconds;
            setInterval(function() {
                minutes = parseInt(timer / 60, 10);
                seconds = parseInt(timer % 60, 10);

                minutes = minutes < 10 ? "0" + minutes : minutes;
                seconds = seconds < 10 ? "0" + seconds : seconds;

                display.textContent = minutes + ":" + seconds;

                if (--timer < 0) {
                    timer = 0;
                    document.getElementById('time').style.backgroundColor = "red";
                }
            }, 1000);
        }

        window.onload = function() {
            setUP();
            showQuestions();
            var minutesLeft = 239, //Change to minutes you need -- counted in seconds -- minus one second 
                display = document.querySelector('#time');
            startTimer(minutesLeft, display);
                        document.getElementById('questions').onclick = setUP;
                        document.getElementById('questions').onclick = showSpinner;


        };
    </script>

    <style>
        #questions div {
            font-family: Arial, Helvetica, sans-serif;
            font-size: 7vh;
            margin-top: 6vh;
            border: 1px solid gray;
            padding: 1vh;
            width: 100%;
        }

        .questions {
            background-color: #ececff;
        }

        .time {
            background-color: #4cdc4c;
            text-align: center;
        }

        #spinner {
            height: 30vw;
            width: 30vw;
            position: absolute;
            top: 12vh;
            margin-left: 35vw;
            overflow: hidden;
            -webkit-animation: rotation .6s infinite linear;
            -moz-animation: rotation .6s infinite linear;
            -o-animation: rotation .6s infinite linear;
            animation: rotation .6s infinite linear;
            border-left: 3vw solid #ececff;
            border-right: 3vw solid #ececff;
            border-bottom: 3vw solid #ececff;
            border-top: 3vw solid #4cdc4c;
            ;
            border-radius: 100%;
        }

        @-webkit-keyframes rotation {
            from {
                -webkit-transform: rotate(0deg);
            }
            to {
                -webkit-transform: rotate(359deg);
            }
        }

        @-moz-keyframes rotation {
            from {
                -moz-transform: rotate(0deg);
            }
            to {
                -moz-transform: rotate(359deg);
            }
        }

        @-o-keyframes rotation {
            from {
                -o-transform: rotate(0deg);
            }
            to {
                -o-transform: rotate(359deg);
            }
        }

        @keyframes rotation {
            from {
                transform: rotate(0deg);
            }
            to {
                transform: rotate(359deg);
            }
        }

        #click {
            height: 100vh;
            width: 100vw;
        }
    </style>
</head>

<body>

    <div id="questions">
        <div id="set_1" class="questions">First question</div>
        <div id="set_2" class="questions">Second question</div>
        <div id="set_3" class="questions">Third question</div>
        <div id="set_4" class="questions">Fourth question</div>
        <div id="set_5" class="questions">Fifth question</div>
        <div id="time" class="time">04:00</div>
    </div>
    <div id="click" onclick="location.reload();">
        <div id="spinner"></div>
    </div>

</body>

</html>
\$\endgroup\$
2
\$\begingroup\$

One problem you have lies in these two lines of code.

document.getElementById('questions').onclick = setUP;
document.getElementById('questions').onclick = showSpinner;

You're overwriting the previous value of onclick with the second assignment. Use the addEventListener method instead, like so.

document.getElementById('questions').addEventListener("click",function() {
    setUP();
    showSpinner();
});

Similarly, you can attach an event listener to div#click using the same method anywhere in your window load event listener.

document.getElementById("click").addEventListener("click",location.reload);

Also, in your startTimer function, you have this line of code, which can be improved slightly.

document.getElementById('time').style.backgroundColor = "red";

You already have a reference to this element. It was provided as the argument display. Therefore, you do not need to search the DOM for that element again, just reference display.

setUP could use some improvement too. First of all, I'd recommend renaming this to setUp, which is only a minor hiccup. Now in this function you have a large 2-dimensional array of strings which follow a very predictable pattern, and you only randomly select one element from each list. You could rewrite this to build the string for you rather than storing 25 nearly identical copies of it.

function setUp() {
    var totalSets = 5;
    var questionsPerSet = 5;

    for(var i = 0; i < totalSets; i++) {
        var questionIndex = Math.floor(Math.random() * questionsPerSet);
        var question = 'Set ' + i + ' Question ' + (questionIndex + 1);
        var selector = '#questions div:nth-child(' + (i + 1) + ')';
        document.querySelector(selector).innerHTML = question;
    }
}
\$\endgroup\$
  • \$\begingroup\$ "You're overwriting the previous value of onclick." Funny enough it still worked. I'll make that change, though. "Similarly, you can attach an event listener to div#click." I've tried that before and I tried it again just now. I also tried adding it to the showSpinner function. If you test in the fiddle, you see the page will not reload when you click the spinner div. It works fine with an inline onclick, so I'm kind of baffled why it's not working with addEventListener. Also, setUP's questions are just for demonstration purposes. But thanks! \$\endgroup\$ – Nic47 Aug 18 '16 at 5:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.