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
    From Webcam to Animated GIF: the Secret Behind chat.meatspac.es!

    My team mate Edna Piranha is not only an awesome hacker; she's also a fantastic philosopher! Communication and online interactions is a subject that has kept her mind busy for a long time, and it has also resulted in a bunch of interesting experimental projects...

  • By
    I’m an Impostor

    This is the hardest thing I've ever had to write, much less admit to myself.  I've written resignation letters from jobs I've loved, I've ended relationships, I've failed at a host of tasks, and let myself down in my life.  All of those feelings were very...

Incredible Demos

  • By
    HTML5 Context Menus

    One of the hidden gems within the HTML5 spec is context menus. The HTML5 context menu spec allows developers to create custom context menus for given blocks within simple menu and menuitem elements. The menu information lives right within the page so...

  • By
    Form Element AJAX Spinner Attachment Using MooTools

    Many times you'll see a form dynamically change available values based on the value of a form field. For example, a "State" field will change based on which Country a user selects. What annoys me about these forms is that they'll often do an...

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 ;
       }
    
    

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