├── README.md
├── aa.html
├── style.css
└── script.js
/README.md:
--------------------------------------------------------------------------------
1 | # HTML-2
--------------------------------------------------------------------------------
/aa.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Typing Test
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Time: 0s
17 |
Mistakes: 0
18 |
19 |
24 |
29 |
30 |
31 |
32 |
Result
33 |
34 |
Accuracy:
35 |
Speed:
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | font-family: "Poppins", sans-serif;
6 | }
7 | body {
8 | background-color: #dd3b12dc;
9 | }
10 | .container {
11 | width: 80vmin;
12 | padding: 50px 30px;
13 | background-color: #ffffff;
14 | position: absolute;
15 | transform: translate(-50%, 50%);
16 | top: 50%;
17 | left: 50%;
18 | border-radius: 10px;
19 | box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
20 | }
21 | .stats {
22 | text-align: right;
23 | font-size: 18px;
24 | margin-bottom: 30px;
25 | }
26 | .stats span {
27 | font-weight: 600;
28 | }
29 | #quote {
30 | text-align: justify;
31 | margin: 50px 0 30px 0;
32 | }
33 | textarea {
34 | resize: none;
35 | width: 100%;
36 | border-radius: 5px;
37 | padding: 10px 5px;
38 | font-size: 16px;
39 | }
40 | button {
41 | float: right;
42 | margin-top: 20px;
43 | background-color: #30f662;
44 | color: #39078a;
45 | border: none;
46 | padding: 10px 30px;
47 | border-radius: 5px;
48 | font-size: 18px;
49 | }
50 | .result {
51 | margin-top: 40px;
52 | display: none;
53 | }
54 | .result h3 {
55 | text-align: center;
56 | margin-bottom: 20px;
57 | font-size: 22px;
58 | }
59 | .wrapper {
60 | display: flex;
61 | justify-content: space-around;
62 | }
63 | .wrapper span {
64 | font-weight: 600;
65 | }
66 | .success {
67 | color: #d462a9;
68 | }
69 | .fail {
70 | color: #e81c4e;
71 | }
--------------------------------------------------------------------------------
/script.js:
--------------------------------------------------------------------------------
1 | //Random Quotes Api URL
2 | const quoteApiUrl = "https://api.quotable.io/random?minLength=80&maxLength=100";
3 | const quoteSection = document.getElementById("quote");
4 | const userInput = document.getElementById("quote-input");
5 | let quote = "";
6 | let time = 60;
7 | let timer = "";
8 | let mistakes = 0;
9 |
10 | //Display random quotes
11 | const renderNewQuote = async () => {
12 | //Fetch contents from url
13 | const response = await fetch(quoteApiUrl);
14 |
15 | //Store response
16 | let data = await response.json();
17 |
18 | //Access quote
19 | quote = data.content;
20 |
21 | //Array of characters in the quote
22 | let arr = quote.split("").map((value) => {
23 | //wrap the characters in a span tag
24 | return "" + value + "";
25 | });
26 | //join array for displaying
27 | quoteSection.innerHTML += arr.join("");
28 | };
29 |
30 | //Logic for comparing input words with quote
31 | userInput.addEventListener("input", () => {
32 | let quoteChars = document.querySelectorAll(".quote-chars");
33 | //Create an arrat from received span tags
34 | quoteChars = Array.from(quoteChars);
35 |
36 | //array of user input characters
37 | let userInputChars = userInput.value.split("");
38 |
39 | //loop through each character in quote
40 | quoteChars.forEach((char, index) => {
41 | //Check if char(quote character) = userInputChars[index](input character)
42 | if (char.innerText == userInputChars[index]) {
43 | char.classList.add("success");
44 | }
45 | //If user hasn't entered anything or backspaced
46 | else if (userInputChars[index] == null) {
47 | //Remove class if any
48 | if (char.classList.contains("success")) {
49 | char.classList.remove("success");
50 | } else {
51 | char.classList.remove("fail");
52 | }
53 | }
54 | //If user enter wrong character
55 | else {
56 | //Checks if we alreasy have added fail class
57 | if (!char.classList.contains("fail")) {
58 | //increment and display mistakes
59 | mistakes += 1;
60 | char.classList.add("fail");
61 | }
62 | document.getElementById("mistakes").innerText = mistakes;
63 | }
64 | //Returns true if all the characters are entered correctly
65 | let check = quoteChars.every((element) => {
66 | return element.classList.contains("success");
67 | });
68 | //End test if all characters are correct
69 | if (check) {
70 | displayResult();
71 | }
72 | });
73 | });
74 |
75 | //Update Timer on screen
76 | function updateTimer() {
77 | if (time == 0) {
78 | //End test if timer reaches 0
79 | displayResult();
80 | } else {
81 | document.getElementById("timer").innerText = --time + "s";
82 | }
83 | }
84 |
85 | //Sets timer
86 | const timeReduce = () => {
87 | time = 60;
88 | timer = setInterval(updateTimer, 1000);
89 | };
90 |
91 | //End Test
92 | const displayResult = () => {
93 | //display result div
94 | document.querySelector(".result").style.display = "block";
95 | clearInterval(timer);
96 | document.getElementById("stop-test").style.display = "none";
97 | userInput.disabled = true;
98 | let timeTaken = 1;
99 | if (time != 0) {
100 | timeTaken = (60 - time) / 100;
101 | }
102 | document.getElementById("wpm").innerText =
103 | (userInput.value.length / 5 / timeTaken).toFixed(2) + " wpm";
104 | document.getElementById("accuracy").innerText =
105 | Math.round(
106 | ((userInput.value.length - mistakes) / userInput.value.length) * 100
107 | ) + " %";
108 | };
109 |
110 | //Start Test
111 | const startTest = () => {
112 | mistakes = 0;
113 | timer = "";
114 | userInput.disabled = false;
115 | timeReduce();
116 | document.getElementById("start-test").style.display = "none";
117 | document.getElementById("stop-test").style.display = "block";
118 | };
119 |
120 | window.onload = () => {
121 | userInput.value = "";
122 | document.getElementById("start-test").style.display = "block";
123 | document.getElementById("stop-test").style.display = "none";
124 | userInput.disabled = true;
125 | renderNewQuote();
126 | };
--------------------------------------------------------------------------------