Element matches / matchesSelector
I was thinking about HTML elements and selectors recently. We usually start by searching for an element(s) via querySelector
/querySelectorAll
, which makes sense, but what if you want to validate that an element that wasn't specifically selected matches a given selector? For example, say you have a function which assumes the presence of classes or attributes on the elements it has been passed, and things might go wrong if the element provided doesn't fit the bill? Enter Element.matches
!
The JavaScript
As MDN details, Element.matches
is the standard API but each vendor has implemented a matchesSelector
version:
function determineIfElementMatches(element, selector) { return element.matches(selector); } // Sample usage var matches = determineIfElementMatches(myDiv, 'div.someSelector[some-attribute=true]');
To work around all of the vendor mess, we can just use the Element
prototype:
function selectorMatches(el, selector) { var p = Element.prototype; var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) { return [].indexOf.call(document.querySelectorAll(s), this) !== -1; }; return f.call(el, selector); }
I've included a polyfill if the browser doesn't support matches
but modern browsers should support the function in some form. As I mentioned at the beginning of the post, I think `matches` is probably most used as a validation measure, but let me know if you see better uses!
The polyfill isn’t very useful, as it should be targeted to IE8 only (IE9 supports
msMatchesSelector
), but IE8 doesn’t supportindexOf
in arrays – unless you’re again using a polyfill, of course.This also mean that, potentially, the polyfill is much slower. Even slower if you’re planning to polyfill for IE7-, as it doesn’t even support
querySelectorAll
.Element.matches
can it get another attributes likesrc
orrel
?I added this in our compatibility js library we use at work.
This way we can write for modern browsers without mixing fallback code into site specific code.
When the time comes we can easily remove obsolete fallbacks like these from our library, do a republish on our sites and all the obsolete fallback code is gone.
this doesn’t work if you are testing an element that has been removed from the document or is in a document fragment.
We can use
hasClass()
andhasId()
methods to determine if the clicked element has a given class or id.Is there a performance boost when using
Element.matches()
vsin
operator withHTMLOrForeignElement.dataset
?