Project summary : I have a div with id wordsContainer and inside there are multiple divs each having a word inside and that word is further split into span tags (each span tags carrying a letter) . The purpose behind it is to find out if typed letter is correct or incorrect (a simple typing game).
Problem : in the addEventListner function depending on the input I am trying to change classes on every keydown event . if for example we have a word "hello" it acts accordingly till it goes to letter "o" it doesn't change its class and on space-key it moves to the next word and does nothing with letters(span tags) in the next word. After the first word only thing works is pressing space-key to move to next word .
I am doing all this with nextSibling method.I tried using querySelector(classname) but it couldn't figure out the end of a word (i created all the letter with "letter" class and after keypress modified that class so that it could go to the next letter).
I created a codpen for visual presentation here :https://codepen.io/Marcian/pen/oNVBrQB
here is the code i am trying right now
function addClass(element, name){ // adds Class
element.className = ''+name;
}
function removeClass(element , name){ // Removes class
element.className= element.className.replace(name, ' ');
}
let wordSibling = wordsContainer.firstElementChild;
let letterSibling = wordSibling.firstChild;
addClass(wordSibling, "currentWord")
addClass(letterSibling, "currentLetter" )
document.addEventListener("keydown", function(e){
const typedKey = e.key;
const expected = document.querySelector(".currentLetter").innerHTML;
console.log({expected , typedKey});
if ( letterSibling.nextSibling){
addClass(letterSibling, "currentLetter")
letterSibling = letterSibling.nextSibling;
addClass(letterSibling, "currentLetter")
removeClass(letterSibling.previousSibling, "currentLetter")
addClass(letterSibling.previousSibling, expected===typedKey? "correct": "incorrect")
}else {
if (typedKey === " "){
wordSibling= wordSibling.nextSibling;
wordSibling.previousSibling.lastChild.className = expected===typedKey? "correct": "incorrect";
letterSibling = wordSibling.firstChild
addClass(letterSibling, "currentletter")
addClass(wordSibling, "currentWord")
removeClass(wordSibling.previousSibling, "currentWord")}
}
})
The way you intend to work with the space looks mixed up: the HTML/CSS you use does not have a way to distinctively identify a correctly typed or incorrectly typed space.
I would suggest to include also
spanelements for the spaces between words. That way you can also style those spaces to indicate whether they are current, correct or incorrect.I adapted a bit the styling (CSS) relying more on background colors than foreground colors, so that it also works well with spaces. I removed the
height: 100pxas it makes the spaces tall. Also fixed a typo you had (#wordsConatainer??).But the essence in this solution is to add spaces also as
spanelements in the HTML, and to style them. AsnextSiblingwould not work to find them, I have chosen to rely onquerySelectorAllinstead -- during initialisation -- and use an iterator over that collection.