Checking For Focus and Hover with JavaScript

Easily check if an element is either hovered or in focus using plain JavaScript.

7014 views
d

By. Jacob

Edited: 2021-02-14 18:26

Hover and Focus, JavaScript

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:

  1. Some websites are blocking devtools with malicious JavaScript, so here is how to stop that without disabling JavaScript.
  2. We can not handle HTTP POST data from JavaScript, but we can still access the data while it is in the HTML form.
  3. getElementById should be used to select unique elements in a HTML document. Selected elements can be manipulated with JavaScript.
  4. Should you use querySelector or getElementById?; querySelector is more flexible, and able to perform more complex selections.
  5. the keydown event is not an ideal way to detect text-input by the user; instead you should consider using the input event.

More in: JavaScript Tutorials