I am making a simple drop down menu app.
My goal is to update the look of the menu through DOM manipulation using an if else statement for specific keyboard key clicks.
Here is the code in question along with an explanation of what is happening currently as well as what I want the code to actually do.
componentDidMount() {
window.addEventListener('keydown', e => {
// This listens for a key press
if (e.key === 'Enter') {
if (this.state.menuIsOpen === false) {
menuOptions[0].style.backgroundColor = 'cornflowerblue'
this.setState(() => ({
menuIsOpen: true,
height: '350px'
}));
// ^ This opens the menu and changes a state property.
} else if (this.state.menuIsOpen === true) {
// This does the opposite.
h1.innerHTML = menuOptions[count].innerHTML;
menuOptions[count].style.backgroundColor = '#a9c4f5'
this.setState(() => ({
menuIsOpen: false,
height: '50px'
}));
}
}
})
}
I know what the issue is, my problem is how to get around it. Right now what is happening is when the 'Enter' key is clicked, the code checks the state to see if the condition is false. Because it is, the state gets changed to true, which in turn causes the next if else block to run because now the condition is true.
What I want is for 1 block to run on the 'Enter', once if the menu is closed and once is the menu is already opened. Not both simultaneously.
Thank you in advance for the help :)
CodePudding user response:
I believe that it called multiple times because this event fires not only when you hit some key, but also when you hold it. So it is probably fires few times when you hit enter once.
Maybe try to just change the event that you listen to.
Simple fix is to set event to keyup, so you know for sure that it would be fired only once.
Also if I would have a whole picture, we would can to find out some solution by changing the UX (I believe that you might not want close any menu by hitting enter, so solution might be just to make menu close handler on esc button for example)
CodePudding user response:
I figured it out!
As someone else stated, the event listener was firing twice (I suspect, correct me if I am wrong). To fix this I simply added 2 lines of code which I have highlighted.
Heres an explanation for the 2 lines: .preventDefault() .stopImmediatePropagation()
Thank you to everyone who tried to help :)
componentDidMount() {
window.addEventListener('keyup', e => {
e.preventDefault(); // Added this line
e.stopImmediatePropagation(); // And this one
if (e.key === 'Enter') {
if (this.state.menuIsOpen === false) {
menuOptions[0].style.backgroundColor = 'cornflowerblue'
this.setState(() => ({
menuIsOpen: true,
height: '350px'
}));
} else if (this.state.menuIsOpen === true) {
h1.innerHTML = menuOptions[count].innerHTML;
menuOptions[count].style.backgroundColor = '#a9c4f5'
this.setState(() => ({
menuIsOpen: false,
height: '50px'
}));
}
}
})
}