The simplest way to check the event.target

I’ve written a couple of posts recently about event delegation and guard clauses. There are many ways you can check the event.target when using event delegation: by its ID, by its classes, by its tag name, by its attributes, and more. But the easiest way is to use the matches() method.

The matches() method is analogous to the is() method in jQuery. You pass in any valid CSS selector and then the method will return true or false.

Basic usage

Given the following HTML element:

<h1 class="heading" data-heading>Heading 1</h1>

Assume we have already selected the element and saved it to the heading variable. Here are some examples of the matches() method:

// Returns TRUE (the element IS an <h1>)
heading.matches("h1");

// Returns TRUE (the element HAS the .heading class)
heading.matches(".heading");

// Returns TRUE (the element HAS the data-heading attribute)
heading.matches("[data-heading]");

// Returns FALSE (the element does NOT have the #heading ID)
heading.matches("#heading");

// Returns FALSE (the element is NOT an <input>)
heading.matches("input");

// Returns FALSE (the data-heading attribute does NOT have a value of 1)
heading.matches("[data-heading='1']");

Usage in an event listener

I’ll use the same example from my posts about event delegation and guard clauses. This time, though, I’ll use the matches() method.

Given the following HTML, imagine that when one of the three paragraphs is clicked, I want to log its textContent to the console:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Example</title>
  </head>
  <body>
    <header>
      <h1>Example</h1>
    </header>
    <main>
      <p>This is a paragraph.</p>
      <p>This is another paragraph.</p>
      <p>This is yet another paragraph.</p>
    </main>
    <footer>
      <p>
        <small>Copyright &copy; Example</small>
      </p>
    </footer>
  </body>
</html>

In the following snippet, you can see the matches() method in action. I used it within the logText() function.

Notice that I’m using the logical NOT operator (!) here, because I want to check if the element is NOT a paragraph:

// Get the main element
var main = document.querySelector("main");

/**
 * Log a paragraph's textContent
 * @param {Object} event The Event object
 */
function logText (event) {

  // If NOT a paragraph, do nothing
  if (!event.target.matches("p")) return;

  // Log the paragraph's textContent
  console.log(event.target.textContent);

}

// Log paragraphs' textContent on click
main.addEventListener("click", logText);

Polyfills

It’s important to note that the matches() method is implemented with vendor prefixes in a handful of browsers.

For consistent behaviour, you should either include the polyfill in your codebase or polyfill your site automatically using a service like polyfill.io.

Further reading

Check out the following resources to learn more about the matches() method:


If you have questions, feedback, or any other suggestions, please do email me. I'd love to hear from you!