The code snippet below fails to combine the setTimeOut and event.key functions. The serchOverlay window closes when you press any key, but should only close when you press Escape. If you remove the setTimeOut function, then the window is closed only by pressing Escape. But because of this, the animation stops working - the smooth appearance of the overlay. How to deal with the problem?
function searchClose(event) {
searchOverlay.removeAttribute('style');
setTimeout(function () {
if (event.key === 'Escape' || !event.target.closest(".search-inner")) {
body.classList.remove('is-search-open');
event.stopPropagation();
}
}, 200);
}
searchOverlay.addEventListener('keydown', searchClose);
searchOverlay.addEventListener('click', searchClose);
I think this is what you want:
function searchClose(event) {
/*
The only keyboard event that should close the overlay is pressing Esc.
Any other keyboard event should do whatever is the browser-default behavior
for that event.
*/
if(event.key && event.key !== 'Escape') return true
/*
Mouse click should only dismiss the overlay if the click is outside the
overlay.
*/
if(!event.key && !event.currentTarget.closest('.search-inner')) return true
/*
At this point, we can be certain that this event should close the overlay.
*/
// task 1: set up a timer that will hide the overlay after a delay
setTimeout(closeOverlay, 200)
// task 2: consume the event so nothing else reacts to it
event.stopPropagation()
event.preventDefault()
return false
}
function closeOverlay() {
body.classList.remove('is-search-open')
}
searchOverlay.addEventListener('keydown', searchClose)
searchOverlay.addEventListener('click', searchClose)
Note that I moved the actual overlay-closing statement into its own function. That is not a requirement for this to work, but I think it makes this code sample clearer, and it encourages re-use.