Checking For Focus and Hover with JavaScript
Easily check if an element is either hovered or in focus using plain JavaScript.
By. Jacob
Edited: 2021-02-14 18:26
Sometimes you may want to check whether an element has focus before changing the visual appearance of the element.
The CSS :hover and :focus pseudo classes may be used to create more interactive UIs, and for the most part, using pure CSS will work just fine. However, in the cases where you have more complex effects on UI elements, using pure CSS might not always accomplish what you want. Instead, you may choose a JavaScript based-approach, which is totally fine.
However, care should be taken to ensure you do not break accessibility features, such as using tab to select elements in a GUI. You should also avoid using elements such as div and span, and instead use a and button (whichever makes sense in the situation).
You can use button elements for JavaScript- based features, and use a for HTML links. Both can actually be styled to look precisely alike, so there is no excuse to use div.
If a user has changed the focus using the tab key, and later hovers the same element with a pointing device, it is important that the element does not change appearance until the focus is actually lost. We can therefor not rely on the mouseenter and mouseleave events alone. We also need to check for focus. Luckily, this is very easy in JavaScript.
To solve the problem, we may use querySelector to determine if the element has indeed lost focus. The below example does just that:
if (event.srcElement !== document.querySelector(":focus")) {
event.srcElement.className = '';
}
In the above example, we simply check if the triggering element equals the current element that has focus.
Note. If nothing is in focus, a null value will be returned.
Checking for focus and hover with JavaScript
The below is a fully working example that inserts a class on elements that are either hovered or in focus.
The purpose of the class is to change the appearance of the UI elements, which is a common design goal in web applications. The script uses querySelectorAll to select a elements that appear inside li elements of the navigation (nav) element of the application.
One advantage of using querySelector and querySelectorAll is that we can use simple CSS selectors to target elements on a page, without the need to use unique IDs or classes on the elements. It is well supported in all modern browsers.
The script
document.addEventListener("DOMContentLoaded", main);
function main() {
let elementsUI = document.querySelectorAll("nav li a");
elementsUI.forEach(function(item) {
item.addEventListener("mouseenter", show);
item.addEventListener("focus", show);
item.addEventListener("mouseleave", hide);
item.addEventListener("focusout", hide);
});
}
function hide(event) {
if (event.srcElement !== document.querySelector(":focus")) {
event.srcElement.className = '';
}
}
function show(event) {
event.srcElement.className = 'selected';
}
You can then include the following CSS in your StyleSheet to change the border of UI elements when users interact with them:
nav li a {
border: 1px solid transparent;
transition:all 0.4s ease-in;
}
.selected {
border: 1px solid rgb(0, 0, 0);
}
Tell us what you think: