Working With Pseudo-classes in JavaScript
Elements on a webpage can have several states, such as :active
, :focus
, :hover
and :visited
. From time to time, we may want to know what's the currently focused element or currently hovered elements. To accomplish that, we may refer to several web APIs. But beware that behaviors of these pseudo-classes vary greatly from browsers to browsers.
pseudo-classes
Elements with:active
The :active
element is the Event.target
of mousedown
event.
In Chrome, Firefox, Edge, but not IE,
- Its parents are also considered active.
In IE, Edge, Chrome, but not Firefox
- When the mouse button is released, it's not active any more. While in Firefox, if the element is clicked and drag-and-dropped, another
mousedown
event is required to make it not active.
As to the button pressed,
- In Chrome, if the pressed button is not the primary one, the active state can only last for 1 or 2 seconds;
- In Firefox, the active state has nothing to do with non-primary buttons;
- In IE and Edge, elements that has been middle-button clicked and drag-and-dropped in the process become active forever, and elements being secondary-button clicked become active until button released;
:focus
MDN:
The :focus CSS pseudo-class is applied when an element has received focus, either from the user selecting it with the use of a keyboard or by activating with the mouse (e.g. a form input).
This pseudo class applies only to the focused element, not its parents, like :checked and :enabled but unlike :active or :hover.
What's more, the containing window of the element should have focus for the element to be considered focused.
:hover
MDN:
The :hover CSS pseudo-class matches when the user designates an element with a pointing device, but does not necessarily activate it.
Besides, parents of the hovered element are also considered hovered.
:visited
The :visited CSS pseudo-class lets you select only links that have been visited.
This pseudo-class is intended for visually styling visited links, and not much can be done with :visited
in JavaScript as to protect user's privacy. See Privacy and the :visited selector.
Dealing with pseudo-classes in JavaScript
Getting :active/:focus/:hover elements
-
jQuery style
$(':active')
-
Vanilla js
document.querySelectorAll(':active')
Checking if an element is :active/:focus/:hover
-
jQuery style using
.is()
$(element).is(':active')
-
Vanilla js using
Element.matches()
element.matches(':active')
-
Vanilla js using
querySelector()
element.parentElement.querySelector(':active') === element
Reference: pure javascript to check if something has hover (without setting on mouseover/out) - Stack Overflow
Getting :active/:focus/:hover elements in event handlers
The :active
/:focus
/:hover
elements are usually the event.target
in related event handlers, so we can just refer to it in event handlers.
// (IE 9+ and other browsers)
document.addEventListener('mousedown', function(event) {
var element = event.target;
// or
element = document.elementFromPoint(event.clientX, event.clientY);
});
// (IE 6-10)
document.attachEvent('onmousedown', function(event) {
var element = event.srcElement;
// or
element = document.elementFromPoint(event.clientX, event.clientY);
});
Notes:
-
mousemove
can be other events as well if appropriate. -
Document.elementFromPoint()
returns the topmost element under the given position, and accepts position relative to the origin of the viewport, that's the reason why MouseEvent.clientX and MouseEvent.clientY are used.