Not seeing the square links with javascript disabled

I don’t see that.

I do, with Firefox too, so you can’t be using the inspector correctly.

I see it now, but…

That doesn’t mean anything.

It’s still not serving a purpose yet.

As I understand it.

It will serve a purpose when that code is used to control multiple buttons.

2 Likes

Where we go from here is to use diffchecker to compare one set of code with another set, which helps us to easily see where all of the differences are. The goal is to remove all of the differences.

1 Like

Here is updated code for codeA and codeB, where the only difference is in two lines at the very end of the code.

    var playButtons = document.querySelectorAll(".wrapa");
    playButtons.forEach(function (button) {
        button.addEventListener("click", playButtonClickHandler);
    });

versus

    var playButtons = document.querySelectorAll(".wrapb");
    playButtons.forEach(function (button) {
        button.addEventListener("click", initialOverlayClickHandler);
    });

Those differences can be easily removed too, by moving configuration info outside of the code, and by checking if any initial element exists on the button.

1 Like

We can first check if the initial element exists, and use that initial overlay click handler for that.

    playButtons.forEach(function (button) {
        if (button.querySelector(".initial")) {
            return button.addEventListener("click", initialOverlayClickHandler);
        }
        button.addEventListener("click", playButtonClickHandler);
    });

Returning from that if statement means that we don’t need an else clause for the playButton handler.

However, because I feel compelled to explain that about this code, an else clause makes good sense to use instead, and doesn’t require any explaining either.

And now there is only one difference between the code:

    var playButtons = document.querySelectorAll(".wrapa");

versus

    var playButtons = document.querySelectorAll(".wrapb");
1 Like

The only way to get rid of that difference is to pass information in to the code.
That is something that you see virtually all libraries do, where they are initialized with some config information.

How do we want this code to be initialized? Some thing like this would be good to use:

playButton.init(".playButton");

which will initialize all play buttons. We cannot do that yet because there are some play buttons that the code doesn’t know how to properly control, so we can instead tell it to initialize for the ones that it does know how to control:

playButton.init(".playButton.wrapa");
playButton.init(".playButton.wrapb");

The only question that remains now is how do we get that selector to an init function?

We can put the code inside of an init function:

    function initPlayButton(selector) {
        var playButtons = document.querySelectorAll(selector);
        playButtons.forEach(function (button) {
            ...
        });
    }

and we can return that init function outside, to a playButton variable.

var playButton = (function iife() {
    ...
    return {
        init: initPlayButton
    };
}());

That then removes all differences from inside of the IIFE and lets us call the init function with whichever button we want to initialize.

We can see that taking place in the updated code at https://jsfiddle.net/v1gfjnm9/230/

1 Like

We can apply that var playButton technique to the rest of the code, and the initPlayButton() function, without changing the rest of the code. That way we remove as many differences as we can between codes C-F, making them easier to convert.

Code C becomes:

    function initPlayButton(selector) {
    //  var playButtons = document.querySelectorAll(".wrapc");
        var playButtons = document.querySelectorAll(selector);
        playButtons.forEach(function (button) {
            button.addEventListener("click", playButtonClickHandler);
        });
    }
    initPlayButton(".wrapc .playButton");

Code D becomes:

    function initPlayButton(selector) {
    //  var playButton = document.querySelector(".wrapd");
        var playButton = document.querySelector(selector);
        playButton.addEventListener("click", playButtonClickHandler);
    }
    initPlayButton(".wrapd.playButton");

Code E becomes:

    function initPlayButton(selector) {
    //  var wrapper = document.querySelector(".wrape");
        var wrapper = document.querySelector(selector);
        var button = wrapper.querySelector(".playButton");
        wrapper.classList.add("inactive");
        wrapper.addEventListener("click", initialOverlayClickHandler);
        hideAllButtons(button);
    }
    initPlayButton(".wrape");

Code F becomes:

    function initPlayButton(selector) {
    //  var playButtons = document.querySelectorAll(".wrapf");
        var playButtons = document.querySelectorAll(selector);
        playButtons.forEach(function (button) {
            button.addEventListener("click", playButtonClickHandler);
        });
    }
    initPlayButton(".playButton.wrapf");

The updated code can be seen at: https://jsfiddle.net/v1gfjnm9/234/

1 Like

We can then move the different config information out of each IIFE set of code, by assigning it to a variable called playButton, and returning that initPlayButton function out to it.

Code C becomes:

// (function iife() {
var playButton = (function iife() {
    ...
    // initPlayButton(".wrapc .playButton");
    return {
        init: initPlayButton
    };
}());
playButton.init(".wrapc .playButton");

Code D becomes:

// (function iife() {
var playButton = (function iife() {
    ...
    // initPlayButton(".wrapd.playButton");
    return {
        init: initPlayButton
    };
}());
playButton.init(".wrapd.playButton");

Code E becomes:

// (function iife() {
var playButton = (function iife() {
    ...
    // initPlayButton(".wrape");
    return {
        init: initPlayButton
    };
}());
playButton.init(".wrape");

Code F becomes:

// (function iife() {
var playButton = (function iife() {
    ...
    // initPlayButton(".wrapf.playButton");
    return {
        init: playButton
    };
}());
playButton.init(".wrapf.playButton");

These changes that make the code closer to the first function, leaves us with the code at https://jsfiddle.net/v1gfjnm9/236/

We can now more easily compare the functions and resolve differences between them, without needing to worry as much about the configuration information that’s used to initialize them.

1 Like

Click on the middle left border:

That doesn’t happen with this code:

What’s the issue?

When you click on the middle left border, that turns on the far right button.

Do you see what I’m talking about?

With all buttons still working properly, it’s only the contents of the initPlayButton function that significantly differs between the A+B code (which I’ll call the main code) and the other sets of code.

The initPlayButton() function in codeC and codeD are easily replaced with the one from the main code.

The initPlayButton() function in codeE is more difficult to deal with:

    function initPlayButton(selector) {
        var wrapper = document.querySelector(selector);
        var button = wrapper.querySelector(".playButton");
        wrapper.classList.add("inactive");
        wrapper.addEventListener("click", initialOverlayClickHandler);
        hideAllButtons(button);
    }

CodeE uses an initial overlay called “cover” whereas codeB uses one called “initial”.
Those are both the same, and I think that you prefer to use “cover” instead of “initial” so I’ll rename all of the others to “cover” too.

<!--<svg class="initial" width="90" height="108" viewbox="0 -10 85 120">
  <svg class="initial" width="90" height="108" viewbox="0 -10 85 120">
/*.wrapb .initial,*/
.wrapb .cover,
...
/*.wrapb .initial {*/
.wrapb .cover {
//      button.querySelectorAll(".play, .pause, .initial, .speaker").forEach(hide);
        button.querySelectorAll(".play, .pause, .cover, .speaker").forEach(hide);
...
//      hide(button.querySelector(".initial"));
        hide(button.querySelector(".cover"));

Doing that helps to make things more consistent, gives the code that you see at https://jsfiddle.net/v1gfjnm9/238/

We can now move on to making the initPlayButton() functions more consistent with each other.

1 Like

div tag placement fixed:


    </svg>
  </div>
 <div class="lines"></div>
</div>

Looking at the different initPlayButton() functions, I see that codeE has the most different one, so it’s best to start with that one and move any updates to the other sets of code.

With codeE, we can add the inactive class before checking if the cover exists:

    function initPlayButton(selector) {
        var playButtons = document.querySelectorAll(selector);
        playButtons.forEach(function (button) {
          	button.classList.add("inactive");
            if (button.querySelector(".cover")) {
                hideAllButtons(button);
                return button.addEventListener("click", initialOverlayClickHandler);
            } else {
                button.addEventListener("click", playButtonClickHandler);
            }
        });
    }

When using that in the main code though, we don’t want the buttons to be hidden on button B.

Both button B and button E have an initial cover, but on one of them we don’t want the buttons to be hidden.
We can deal with that by either:

  • having the button B HTML code say that we want to show the buttons
  • or, having the button E HTML code say that we want to hide the buttons

As all the other buttons have play buttons showing, initially hiding the buttons seems to be the more unusual situation, so I’ll remove the hideAllButtons() line. Because the HTML code has them all initially hidden to begin with, the code still works without the hideAllButtons() so we’re fine there.

The updated initPlayButton() function (without the hideAllButtons() line) can now be copied over to the main code, and everything still works.

Replacing all of the other initPlayButton functions with the same code, and everything still continues to work well.

We are now in a better spot by which to compare the other sets of code with the main code.

1 Like

javascript Character Count

16984 Merged

15595 Not Merged

Shouldn’t merged be smaller?

With the main code on the right side of the DiffChecker (preferable because extra code is shown as green) and the other code, that being codeC on the left (so that new stuff is shown in red).

That way, the green code can be ignored, and the few red bits are the only thiings left to worry about.,

One of the red bits is that playButton() is used instead of togglePlayButton(), so making that togglePlayButton() consistently throughout the code is the next important step:

//  function playButton(button) {
    function togglePlayButton(button) {
...
//      playButton(button);
        togglePlayButton(button);

With that done, there’s just a minor bit of formatting that’s different at the end, where a gap is added before the return statement:

    function initPlayButton(selector) {
        ...
    }

    return {
        init: initPlayButton
    };

And there’s no other difference between them that doesn’t already exist in the main code.

Code C can now be deleted, with the main code now controlling three sets of buttons, with a total of 5 in all (as button C consists of 3 buttons).

playButton.init(".playButton.wrapa");
playButton.init(".playButton.wrapb");
//var playButton = (function iife() {
//    ...
//}());
playButton.init(".wrapc .playButton");

We can now use the same consistent formatting for the first and second playbutton too.

playButton.init(".wrapa.playButton");
playButton.init(".wrapb.playButton");
playButton.init(".wrapc .playButton");

The space is required for the C buttons, but only until the main code works with all of the buttons.
When the main code works with all of the buttons, the .wrapX can then be removed, and only one init line will be required to initialize all of the buttons.

Here’s the code with that update, where the main code is controlling the A+B+C buttons. https://jsfiddle.net/v1gfjnm9/242/

2 Likes

Checking code D in the diff checker shows that it has no new code at all so code D can be deleted now.

The main code is now handling all four sets of buttons:

playButton.init(".wrapa.playButton");
playButton.init(".wrapb.playButton");
playButton.init(".wrapc .playButton");
playButton.init(".wrapd.playButton");
2 Likes

That’s way smaller alright.

11071

If I want to implement pause on a button, and not stop/reset, how do I do that?

<button style="cursor:pointer;background:green;" onclick="document.getElementById('player').pause()">Pause</button>

<button style="cursor:pointer;background:green;" onclick="document.getElementById('player').pause() ;document.getElementById('player').currentTime=0;">Stop</button>

I’ll try it on here:

The audio player will only stop/reset when it’s src attribute is updated.

1 Like