I would like to kindly ask to review my code. I'd like suggestions, criticisms, and discussions on what is good and what could be done better.
const wordsArray = [ "aardvark", "albatross", "alligator", "alpaca", "ant", "anteater", "antelope", "ape", "armadillo", "donkey", "baboon", "badger", "barracuda", "bat", "bear", "beaver", "bee", "bison", "boar", "buffalo", "butterfly", "camel", "capybara", "caribou", "cassowary", "cat", "caterpillar", "cattle", "chamois", "cheetah", "chicken", "chimpanzee", "chinchilla", "chough", "clam", "cobra", "cockroach", "cod", "cormorant", "coyote", "crab", "crane", "crocodile", "crow", "curlew", "deer", "dinosaur", "dog", "dogfish", "dolphin", "dotterel", "dove", "dragonfly", "duck", "dugong", "dunlin", "eagle", "echidna", "eel", "eland", "elephant", "elk", "emu", "falcon", "ferret", "finch", "fish", "flamingo", "fly", "fox", "frog", "gaur", "gazelle", "gerbil", "giraffe", "gnat", "gnu", "goat", "goldfinch", "goldfish", "goose", "gorilla", "goshawk", "grasshopper", "grouse", "guanaco", "gull", "hamster", "hare", "hawk", "hedgehog", "heron", "herring", "hippopotamus", "hornet", "horse", "human", "hummingbird", "hyena", "ibex", "ibis", "jackal", "jaguar", "jay", "jellyfish", "kangaroo", "kingfisher", "koala", "kookabura", "kouprey", "kudu", "lapwing", "lark", "lemur", "leopard", "lion", "llama", "lobster", "locust", "loris", "louse", "lyrebird", "magpie", "mallard", "manatee", "mandrill", "mantis", "marten", "meerkat", "mink", "mole", "mongoose", "monkey", "moose", "mosquito", "mouse", "mule", "narwhal", "newt", "nightingale", "octopus", "okapi", "opossum", "oryx", "ostrich", "otter", "owl", "oyster", "panther", "parrot", "partridge", "peafowl", "pelican", "penguin", "pheasant", "pig", "pigeon", "pony", "porcupine", "porpoise", "quail", "quelea", "quetzal", "rabbit", "raccoon", "rail", "ram", "rat", "raven", "reindeer", "rhinoceros", "rook", "salamander", "salmon", "sandpiper", "sardine", "scorpion", "seahorse", "seal", "shark", "sheep", "shrew", "skunk", "snail", "snake", "sparrow", "spider", "spoonbill", "squid", "squirrel", "starling", "stingray", "stinkbug", "stork", "swallow", "swan", "tapir", "tarsier", "termite", "tiger", "toad", "trout", "turkey", "turtle", "viper", "vulture", "wallaby", "walrus", "wasp", "weasel", "whale", "wildcat", "wolf", "wolverine", "wombat", "woodcock", "woodpecker", "worm", "wren", "yak", "zebra" ];
const inputs = document.querySelector('.input');
const wordsContainer = document.querySelector('.wordsContainer')
let clickSum = 0;
let wordsSum = 0;
let currentWord = 0;
let timeStart = true;
const time = 30; // seconds
function displayWords(array) {
wordsContainer.innerHTML = array.map( (value) => {return `<span class='word'>${value}</span>`}).join('');
}
function addActive() {
const spans = document.querySelectorAll('.word');
spans.item(currentWord).classList.add('active');
}
function removeActive() {
document.querySelector('.active').classList.remove('active');
}
function onFlyCheck() {
const span = document.querySelector('.active');
const wordSpell = span.textContent.split('');
const inputSpell = this.value.split('');
const output = wordSpell.map( (value) => `<span>${value}</span>`);
if (inputSpell.length > wordSpell.length) return;
inputSpell.map( (value, index) => {
if (wordSpell[index] === value) output[index] = `<span class="correct">${wordSpell[index]}</span>`;
else output[index] = `<span class="incorrect">${wordSpell[index]}</span>`
});
span.innerHTML = output.join('');
}
function commitWord(e) {
if (e.keyCode === 32 || e.keyCode === 13) {
checkWord(this.value.trim());
this.value = "";
}
}
function checkWord(word) {
const active = document.querySelector('.active');
active.innerHTML = wordsArray[currentWord];
if (word === wordsArray[currentWord]) {
active.classList.add('correct');
wordsSum++;
clickSum += (wordsArray[currentWord].length);
} else {
active.classList.add('incorrect')
}
currentWord++;
removeActive();
addActive();
scrollWords();
}
function startTime() {
if (timeStart) countDown();
timeStart = false
}
function countDown() {
setTimeout( endGame, time*1000);
}
function endGame() {
const cpm = clickSum / time * 60;
const score = document.querySelector('.score');
inputs.disabled = true;
score.innerHTML = `Congratulations! Your score is ... <br>
<p>${cpm} key press per minute </p>
<p>${wordsSum} correct word(s). </p>
<p> Refresh page (F5) to start again </p>`
}
function shuffle(array) {
for (let i = array.length; i; i--) {
let j = Math.floor(Math.random()*i);
[array[i-1], array[j]] = [array[j], array[i-1]];
}
}
let offset = 0;
function scrollWords() {
const active = document.querySelector('.active');
if (active.offsetTop -offset > active.offsetHeight) {
offset += active.offsetHeight;
wordsContainer.style.top =`-${offset}px`;
}
}
inputs.addEventListener('keyup', onFlyCheck);
inputs.addEventListener('keyup', commitWord);
inputs.addEventListener('keypress', startTime);
shuffle(wordsArray);
displayWords(wordsArray);
addActive();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Type speed calculator</title>
</head>
<body>
<div class="wrapper">
<div class="container">
<div class="wordsContainer">Loading sentence...</div>
</div>
<input type="text" class="input">
<div class="score"></div>
</div>
<script type="text/javascript" src="scripts.js"></script>
</body>
<style>
body {
background-color: #ff6c00;
font-size: 2rem;
}
.wrapper{
width: 50%;
margin: 75px auto;
display: block;
}
.wordsContainer{
position: relative;
transition: all 0.2s;
}
.container{
text-align: center;
/* padding: 1rem 2rem 0; */
width:100%;
height: 10rem;
overflow: hidden;
margin: 1rem 2rem;
display: inline-block;
background-color: #ffc500;
border-radius: 10px;
}
input{
margin: 0;
outline: none;
width: 100%;
font-size: 1.5rem;
text-align: center;
border-radius: 5px;
border: 1px solid black;
}
.currentWord{
background-color: white;
}
.word{
display: inline-block;
padding: 0.5rem 1rem;
}
.active{
background-color: white;
border-radius: .25em;
}
.incorrect{
color: red;
}
.correct{
color: green;
}
.score{
margin: 125px auto;
text-align: center;
}
</style>
</html>