Element matches / matchesSelector

By  on  

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!

Recent Features

  • By
    CSS vs. JS Animation: Which is Faster?

    How is it possible that JavaScript-based animation has secretly always been as fast — or faster — than CSS transitions? And, how is it possible that Adobe and Google consistently release media-rich mobile sites that rival the performance of native apps? This article serves as a point-by-point...

  • By
    Conquering Impostor Syndrome

    Two years ago I documented my struggles with Imposter Syndrome and the response was immense.  I received messages of support and commiseration from new web developers, veteran engineers, and even persons of all experience levels in other professions.  I've even caught myself reading the post...

Incredible Demos

  • By
    CSS :target

    One interesting CSS pseudo selector is :target.  The target pseudo selector provides styling capabilities for an element whose ID matches the window location's hash.  Let's have a quick look at how the CSS target pseudo selector works! The HTML Assume there are any number of HTML elements with...

  • By
    Comment Preview Using MooTools

    Comment previewing is an awesome addition to any blog. I've seen really simple comment previewing and some really complex comment previewing. The following is a tutorial on creating very basic comment previewing using MooTools. The XHTML You can set up your XHTML any way you'd like.

Discussion

  1. MaxArt

    The polyfill isn’t very useful, as it should be targeted to IE8 only (IE9 supports msMatchesSelector), but IE8 doesn’t support indexOf 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.

  2. Felipe

    Element.matches can it get another attributes like src or rel?

  3. 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.

    if (!Element.prototype.matches)
    {
      var ep = Element.prototype;
    
      if (ep.webkitMatchesSelector) // Chrome <34, SF<7.1, iOS<8
        ep.matches = ep.webkitMatchesSelector;
    
      if (ep.msMatchesSelector) // IE9/10/11 & Edge
        ep.matches = ep.msMatchesSelector;
    
      if (ep.mozMatchesSelector) // FF<34
        ep.matches = ep.mozMatchesSelector;
    }
    
  4. no

    this doesn’t work if you are testing an element that has been removed from the document or is in a document fragment.

  5. Amir Saleem

    We can use hasClass() and hasId() methods to determine if the clicked element has a given class or id.

      
      function hasClass(elem, match){
           return elem.className.split(" ").indexOf(match) > -1 ;
       }
    
      function hasId(elem, match){
           return elem.id.split(" ").indexOf(match) > -1 ;
       }
    
    
  6. Andrzej Berena

    Is there a performance boost when using Element.matches() vs in operator with HTMLOrForeignElement.dataset ?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!