Two versions of a playButton Binding Audio With a grid link structure

Fixed.

Audio should be off though.

That code is getting confusing, I’m sure that you might agree.

Please move all of the event handler functions down below the other functions, to help remove some of that confusion.

This?

     function playButtonClickHandler() {
       var button = this;
       togglePlayButton(button);
     }

Yes, that qualifies as an event handler function.

Please move all of the event handler functions down below all of the other functions.

Lets put these in the right order then.

 document.querySelector(".myLink").classList.add("hide");

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

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

   function togglePlayButton(button) {
     var wrap = upTo(button, "wrap");
     var player = button.querySelector("audio");
     var play = button.querySelector(".play");
     var pause = button.querySelector(".pause");
     button.classList.add("playing");
     hide(button.querySelector(".initial"));
     show(wrap.querySelector(".myLink"));
     player.volume = 1.0;
     if (player.paused) {
       show(play);
       hide(pause);
       player.play();
     } else {
       hide(play);
       show(pause);
       player.pause();
     }

     function playButtonClickHandler() {
       var button = this;
       togglePlayButton(button);
     }


     function linksClickHandler() {
       var button = document.querySelector(".playButton");
       hide(wrap.querySelector(".myLink"));
       hide(button.querySelector(".initial"));
       playButton.addEventListener("click", playButtonClickHandler);
       show(play);
       hide(pause);
       button.classList.add("playing");
     }
   }

   function getPlayButton(el) {
     while (el.classList.contains("playButton") === false) {
       el = el.parentNode;
     }
     return el;
   }

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

   function upTo(el, className) {
     while (el.classList.contains(className) === false) {
       el = el.parentNode;
     }
     return el;
   }
   var playButton = document.querySelector(".playButton");
   playButton.addEventListener("click", playButtonClickHandler);
 }());

Like this?

function getPlayButton(el) {
     while (el.classList.contains("playButton") === false) {
       el = el.parentNode;
     }
     return el;
   }

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


    function playButtonClickHandler() {
       var button = this;
       togglePlayButton(button);
     }

This is how it’s supposed to work:

For comparison:

What needs to be adjusted?

In here:

The right order is given to you by JSLint.

I can tell that you haven’t been using that, because your code is full of problems right now.
Let’s use JSLint to remove those easy to fix problems from your code.

To get annoying spacing issues dealt with, run the code through JSBeautifier or other code indenting tool, so that it has a nice 4-space indent.

JSLint tells us undefined document for which we can scroll down to the bottom of the page and tell it to assume a browser

The next issue is that a call to upTo is out of scope. That means that the function is further down below, when it should be above. The issue occurred in the togglePlayButton function, so move the upTo function up above the togglePlayButton function,

The next issue is a strange one, Redefinition of 'button' from line 18. Why is it being redefined? It’s the first thing that’s being done in that function. But, comparing that function with other ones around it, we can see from the indenting that the togglePlayButton function is missing a closing brace to end the function. Put one of those in, and that issue is dealt with. It does mean indenting the rest of the code though, so passing the code through JSBeautifier again is an easy fix for that.

The next issue is Unexpected 'this' which is dealt with by removing the this keyword and using getPlayButton instead.

The next issue is a really strange Expected ')' to match '(' from line 0 and instead saw 'function'. which shows that JSLint is getting really confused. Looking at the code it’s because you have too many closing braces up above the function. Get rid of one of them (and re-indent the code with JSBeautifier), and that issue is dealt with.

The next issue is that 'getPlayButton' is out of scope. which is because the event handlers are higher up than they should be. Move the getPlayButton function up above the event handler to fix that one.

Then we have Undeclared 'evt' which is because the function parameter is empty. Tell the click event that it’s to expect evt as a function parameter and things go well there.

Next there is an unused 'linksClickHander'. Is that because it’s left over from other code? If so, remove it.

Then we have, Redefinition of 'playButtonClickHandler' which tells us that we have a duplicate of that function. Remove the one that’s not needed.

The code now has no more problems according to JSLint, and putting that code back in to JSFiddle shows that it now works. There is one remaining issue, but that’s easy to spot during testing, and fixing it is easy.

That’s what’s needed to fix this code, and using JSLint makes it easy to clean up your code so that easy to fix problems can be found and dealt with.

1 Like
'upTo' is out of scope.
        var wrap = upTo(button, "wrap");

With reference to the function that the above line was copied from, move the upTo function up above that function.


(function iife() {
    "use strict";
    document.querySelector(".myLink").classList.add("hide");

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

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

    function togglePlayButton(button) {
        var wrap = upTo(button, "wrap");

Do you see the upTo function up above the togglePlayButton one? I don’t. Do that.

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

  var wrap = upTo(button, "wrap");

    function togglePlayButton(button) {

No, don’t move the var wrap line from where it was.

It’s the upTo function that you need to move, so that it’s up above the togglePlayButton function.

(function iife() {
    "use strict";
    document.querySelector(".myLink").classList.add("hide");

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

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

    function upTo(el, className) {
        while (el.classList.contains(className) === false) {
            el = el.parentNode;
        }
        return el;
    }

    function togglePlayButton(button) {
        var wrap = upTo(button, "wrap");
        var player = button.querySelector("audio");
        var play = button.querySelector(".play");
        var pause = button.querySelector(".pause");
        button.classList.add("playing");
        hide(button.querySelector(".initial"));
        show(wrap.querySelector(".myLink"));
        player.volume = 1.0;
        if (player.paused) {
            show(play);
            hide(pause);
            player.play();
        } else {
            hide(play);
            show(pause);
            player.pause();
        }


    function getPlayButton(el) {
        while (el.classList.contains("playButton") === false) {
            el = el.parentNode;
        }
        return el;
    }




        function linksClickHandler() {
            var button = document.querySelector(".playButton");
            hide(wrap.querySelector(".myLink"));
            hide(button.querySelector(".initial"));
            playButton.addEventListener("click", playButtonClickHandler);
            show(play);
            hide(pause);
            button.classList.add("playing");
        }
    }

    function playButtonClickHandler() {
        var button = this;
        togglePlayButton(button);
    }


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

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

That didn’t move the upTo function up above the togglePlayButton function. Please do that.

I forgot how to, waited to do it last.

It was atleast working somewhat in here:

Before you made me put it through jslint.

upTo’ is out of scope.
var wrap = upTo(button, "wrap");

Unused ‘getPlayButton’.
function getPlayButton(el) {

Unused ‘linksClickHandler’.
function linksClickHandler() {
48.16
Redefinition of ‘button’ from line 12.
var button = document.querySelector(".playButton");
51.12
‘playButton’ is out of scope.
playButton.addEventListener("click", playButtonClickHandler);
51.49
‘playButtonClickHandler’ is out of scope.
playButton.addEventListener("click", playButtonClickHandler);
59.21
Unexpected ‘this’.
var button = this;
64.13
Redefinition of ‘playButtonClickHandler’ from line 58.
function playButtonClickHandler(evt) {
65.21
Undeclared ‘getPlayButton’.
var button = getPlayButton(evt.target);

Yes, upTo is out of scope, for the upTo function is lower than is needs to be. The upTo function must be moved up above the togglePlayButton function.