Conditional Matches

Let’s do this one next:

    while (!el.classList.matches(selector)) {
    }

function getPlayButton(el) {
    while (!el.classList.matches(selector)) {
           el = el.parentNode;
        }
        return el;
    }

  function playButtonClickHandler(evt) {
    var button = getPlayButton(evt.target);
    togglePlayButton(button);
  }

  var playButton = document.querySelector(".playButton");
  playButton.addEventListener("click", playButtonClickHandler);

}());

Do you see how the getPlayButton function has only el as a parameter to that function, and that selector is also used inside that function?

You need to either:

  • change selector to a string value of what you’re wanting to match, or
  • if you want the function to be able to match any given selector, you need to change that function to be the upTo() function that we’ve used elsewhere instead.

Alternatively, you can have the getPlayButton call the upTo function instead.

function getPlayButton(el) {
    return upTo(el, ".playButton");
}

change selector to a string value of what you’re wanting to match

How do I do that?

Well that would be going back to using matches("playButton") but that would be mean that you are making backwards progress instead of forwards progress.

Like this?

Yes, with the upTo function above the getPlayButton one, that would work well.

You also have two getPlayButton functions in there, get rid of the second one.

What am I supposed to do?

(function iife() {
    "use strict";

function getPlayButton(el) {
    return upTo(el, ".playButton");
}

    function show(el) {
      el.classList.remove("hide");
    }

    function hide(el) {
      el.classList.add("hide");
    }

    function togglePlayButton(button) {
      var player = button.querySelector("audio");
      var play = button.querySelector(".play");
      var pause = button.querySelector(".pause");
      player.volume = 1.0;
      if (player.paused) {
        hide(play);
        show(pause);
        player.play();
        button.classList.add("active");
      } else {
        button.classList.remove("active");
        show(play);
        hide(pause);
        player.pause();
      }

    }

function getPlayButton(el) {
    while (!el.classList.matches(selector)) {
           el = el.parentNode;
        }
        return el;
    }

  function playButtonClickHandler(evt) {
    var button = getPlayButton(evt.target);
    togglePlayButton(button);
  }

  var playButton = document.querySelector(".playButton");
  playButton.addEventListener("click", playButtonClickHandler);
  
}());

ok…

You’ve seen the upTo() function from other code of yours. That is the function that you need to put above the getPlayButton() function.

   function upTo(el, selector) {
     while (el.matches(selector) === false) {
       el = el.parentNode;
     }
     return el;
   }
1 Like

Let’s do this one next:

What do I need to do?

    while (noMatch(el, selector)) {
    }

These are the 2 conditional matches that are left:

    while (noMatch(el, selector)) {
    }

    while (!hasMatch(el, selector)) {
    }

With match(el, selector) you would need a match function, that looks like this:

function match(el, selector) {
    return el.matches(selector);
}

The noMatch function might then look like this:

function noMatch(el, selector) {
    return !el.matches(selector);

But it’s better to keep the match function around, and use that from the noMatch function instead:

function noMatch(el, selector) {
    return !match(el, selector);

Do I keep this in there?



   function upTo(el, selector) {
     while (el.matches(selector) === false) {
       el = el.parentNode;
     }
     return el;
   }
   function upTo(el, selector) {
     while (el.matches(selector) === false) {
       el = el.parentNode;
     }
     return el;
   }

function noMatch(el, selector) {
    return !match(el, selector);
}

You certainly could keep the upTo() function in there, and with the match() and noMatch functions above the upTo() function, you could make use of it by updating the condition of the while loop:

   function upTo(el, selector) {
     while (noMatch(el, selector)) {
       el = el.parentNode;
     }
     return el;
   }

I’m confused now.

Are you saying, upTo isn’t required for this?