Published on June 6, 2024
We’ll start with the basic structure of our HTML file.
First, we define the document type as HTML. This tells the browser that we’re working with an HTML5 document.
Next, we have our HTML tags, which enclose the entire document. Inside the HTML tags, we have the head and body sections.
In the head section, we include meta tags for responsive design, set the title of the document, and link to our CSS file for styling.
Now, let’s move on to the body section, where the content of our typing test will go.
First, we have an <h1> tag with the text ‘Typing Test‘. This will be the title of our page.
Next, we have a <div> with the class ‘container‘. This container will hold all the elements of our typing test.
Inside the container, we have another <div> with the class ‘stats’ to display the timer and mistake count.
In the stats div, we have two paragraphs: one for the time and one for the mistakes. We use <span> tags with IDs ‘timer’ and ‘mistakes‘ to dynamically update these values with JavaScript.
Next, we have a <div> with the ID ‘quote’ where the typing quote will be displayed. We’ve added ‘onmousedown‘ and ‘onselectstart‘ attributes set to ‘return false’ to prevent users from copying the text.
Below the quote div, we have a <textarea> with the ID ‘quote-input’ where users will type the quote. It has a placeholder that prompts users to start typing when the test begins.
Next, we have two buttons: one to start the test and one to stop it. These buttons have IDs ‘start-test’ and ‘stop-test’ respectively, and are linked to the startTest and displayResult functions in JavaScript.
Finally, we have a result div that will display the accuracy and speed of the user after they finish the test. It contains an <h3> tag for the title and another wrapper div with two paragraphs for accuracy and speed.
CSS
Let’s start with the basic styles applied to all elements using the universal selector.
The asterisk (*) selector applies styles to all elements. We set padding and margin to zero, ensure that the box-sizing is set to border-box, and use the Georgia font family.
Next, we set the background colour of the body to a light yellow using the hex colour #ffeaa7. This gives our page a pleasant, soft background.
For the <h1> tag, we centre-align the text, add a margin at the top to give it some space from the top of the page, and set the colour to a dark grey using #2a2a2a.
Moving on to the container class, we set its width to 80 min to ensure it scales nicely across different screen sizes. We add padding for some inner space and set the background colour to a soft orange using #ffbb64.
We use the position property set to absolute to centre the container in the viewport, using top: 40% and left: 50%. The transform property helps to perfectly centre it by translating it by -50% in both the x and y directions.
We also add a border-radius of 10px for rounded corners and a box-shadow to give it a subtle depth effect.
Next, let’s look at the stats class. We align the text to the right, set the font size to 18px, and give it some margin at the bottom. We also use flexbox to space out the items evenly and align them in the centre.
For the span elements inside stats, we increase the font weight to 600 and set the font size to 20px. We also change the colour to a bright red using #e81c4e.
The #quote ID is styled to justify the text, add margins to create space around it, and set the color to a dark grey.
For the textarea, we prevent resizing, set its width to 100%, add padding for better text spacing, and give it a border-radius for rounded corners. The font size is set to 16px.
The button styles include centering it, setting a bright red background with white text, removing borders, adding padding, rounding the corners, and setting the cursor to pointer. We also ensure it takes up the full width.
Finally, we have the result class. Initially, it’s hidden using display: none. When it’s shown, it will have a margin at the top. The result h3 tag is centre-aligned and has a larger font size.
The wrapper class is a flexbox container that spaces out its children. The span elements inside the wrapper have a bold font weight.
We also add success and fail classes to style the result text with green and red colours, respectively.
JAVASCRIPT
Let’s start by defining some essential variables and constants.
We have a constant quoteApiUrl that stores the URL of the API we’ll use to fetch random quotes. Then, we get references to the quoteSection and userInput elements from our HTML by their IDs.
Next, we declare variables for the quote, time limit, timer, and mistakes counter.
Now, let’s create a function to fetch and render a new quote from the API. This is an asynchronous function named renderNewQuote.
We start by fetching the data from the API and converting the response to JSON. The quote text is stored in the quote variable. We then split the quote into individual characters and wrap each character in a span element with the class ‘quote-chars’. Finally, we join these span elements into a string and set the innerHTML of quoteSection.
Next, we add an event listener to the user input. This will track the user’s typing and compare it to the quote characters.
Inside this event listener, we convert the NodeList of quoteChars to an array and split the user’s input into individual characters. For each character in the quote, we check if it matches the corresponding character in the user input.
If the characters match, we add the ‘success‘ class to the quote character. If there’s no corresponding user input character, we remove any existing ‘success’ or ‘fail’ classes. If the characters don’t match, we add the ‘fail’ class and increment the mistakes counter.
We also check if all characters have the ‘success’ class, indicating the user has correctly typed the entire quote. If so, we call the displayResult function.
Now, let’s look at the timer functionality. We have an updateTimer function that decrements the time and updates the timer display. If the time reaches zero, we call the displayResult function.
The timeReduce function sets the time to 60 seconds and starts a timer that calls updateTimer every second.
The displayResult function shows the result section, stops the timer, disables the user input, and calculates the typing speed (WPM) and accuracy. We display these results in the respective elements.
The startTest function initialises the test by resetting the mistakes counter, starting the timer, enabling the user input, and hiding the start button while showing the stop button.
Finally, we have the window.onload function that initialises the page when it loads. It resets the user input, displays the start button, hides the stop button, disables the user input, and renders a new quote.
And that’s it for the JavaScript part! We’ve now added functionality to our typing test. You can start the test, type the quote, and see your typing speed and accuracy at the end. Thanks for watching, and happy coding!