Converting the inline javascript to pure javascript, how would this be done?


#1

I have not been able to figure out how to do this.

This is the only thing I haven’t removed the inline javascript from which is a bad practice.

Let’s get rid of the inline!!!

I know how to set up the regular javascript api, I don’t know how to incorporate it with the inline javascript which I would be removing.

This is the CSS part that went with the inline javascript:

.wrapg .video {
  width: 606px;
  display: block;
}

.wrapg #thevideo {
  display: none;
}

.wrapg #thevideo,
iframe {
  width: 600px;
  height: 338px;
}

working version using inline javascript:
https://jsfiddle.net/8aebp5zt/4/

javascript added
https://jsfiddle.net/7rhx1kpt/75/

The audio is set to 0 because I haven’t figured out how to stop it from auto playing before it’s clicked.


<div class="wrapg">

  <div class="video" onclick="thevid=document.getElementById('thevideo');
thevid.style.display='block'; this.style.display='none';
document.getElementById('iframe').src =
document.getElementById('iframe').src.replace('autoplay=0','autoplay=1');">

    <svg class="play" width="600" height="338" viewbox="-3 -0.3 30 24.655">
<path fill="#FA33FC" d="M16.036 11.58l-6-3.82a.5.5 0 0 0-.77.42v7.64a.498.498 0 0 0 .77.419l6-3.817c.145-.092.23-.25.23-.422s-.085-.33-.23-.42z"></path>

<path fill="#FA33FC" d="M12 22.75C6.072 22.75 1.25 17.928 1.25 12S6.072 1.25 12 1.25 22.75 6.072 22.75 12 17.928 22.75 12 22.75zm0-20C6.9 2.75 2.75 6.9 2.75 12S6.9 21.25 12 21.25s9.25-4.15 9.25-9.25S17.1 2.75 12 2.75z"></path></svg>

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

  <div id="thevideo">


    <div id="player" id="iframe" class="playing"></div>


    <script>
      var tag = document.createElement('script');
      tag.src = "https://www.youtube.com/player_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

      var player;

      function onYouTubePlayerAPIReady() {
        player = new YT.Player('player', {
          height: '375',
          width: '606',
          videoId: 'M7lc1UVf-VE',
          playerVars: {
            autoplay: 1,
            loop: 0,
            controls: 1,
            showinfo: 0,
            autohide: 0,
            rel: 0,
            iv_load_policy: 3,
            cc_load_policy: 0,
            fs: 0,
            disablekb: 1,

          },
          events: {
            'onReady': onPlayerReady
          }
        });
      }

      function onPlayerReady(event) {
        event.target.setVolume(0);
        event.target.playVideo();

      }

    </script>

  </div>
</div>

#2

The simple answer is: Take everything in the inline, slap it inside a function. Lets say we call it myUsedToBeInline().
Then you have a couple of options for invoking said function.
1: Leave the onclick= in your HTML, but point it to your function: onclick = "myUsedToBeInline();"
2: Add an Event Listener in your script (not in your function, but in the script) that listens for a click on the target element, and executes your function.
(3: If you’re using certain frameworks like jQuery, it may have additional ways to invoke event listeners, but under the hood it’s doing #2)


#3

Thanks!.. @Paul_Wilkins has been helping me with these so I’ll wait for him. I don’t think it should be that difficult to do. I just can’t believe I haven’t removed the inline from it since it’s been some time.


#4

@Paul_Wilkins I got up this far with the javascript and CSS.
https://jsfiddle.net/8Lay0mhu/86/

I think I’m up to adding in the youtube api javascript stuff.

I’m at the point where I’m stuck.

.wrape {
  position: relative;
  width: 606px;
  height: 344px;
  margin-top: 8px;
  border: 3px solid #0059dd;
  box-sizing: border-box;
}

.wrape.active .playing {
  position: absolute;
  top: -3px;
  left: -3px;
  width: 606px;
  height: 344px;
  border: 3px solid #FA33FC;
  box-sizing: border-box;
}

.wrape .playcover {
  fill: #FA33FC;
}

.wrape .play {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  margin: auto;
  cursor: pointer;
}

.wrape .cover {
  width: 600;
  height: 338px;
  cursor: pointer;
  background: url("https://i.imgur.com/AJDZEOX.jpg") no-repeat;
}

.wrape .cover {
  display: none;
}

.wrape.inactive .cover {
  display: block;
}

.wrape .cover::before,
.wrape .cover::after {
  content: "";
  position: absolute;
  top: 0;
  left: 198px;
  width: 3px;
  height: 100%;
  background: #0059dd;
}

.wrape .cover::after {
  left: 399px;
}

.hide {
  display: none;
}
<div class="wrape">

  <svg class="play" width="600" height="338" viewbox="-3 -0.3 30 24.655">
<path class="playcover" d="M16.036 11.58l-6-3.82a.5.5 0 0 0-.77.42v7.64a.498.498 0 0 0 .77.419l6-3.817c.145-.092.23-.25.23-.422s-.085-.33-.23-.42z"></path>

<path class="playcover" d="M12 22.75C6.072 22.75 1.25 17.928 1.25 12S6.072 1.25 12 1.25 22.75 6.072 22.75 12 17.928 22.75 12 22.75zm0-20C6.9 2.75 2.75 6.9 2.75 12S6.9 21.25 12 21.25s9.25-4.15 9.25-9.25S17.1 2.75 12 2.75z"></path></svg>

  <div class="cover" title="OPEN"></div>

  <div class="playing"></div>


(function iife() {
    "use strict";

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

    function hideInitialOverlay(wrapper) {
        wrapper.classList.remove("inactive");
        wrapper.classList.add("active");
        hide(wrapper.querySelector(".play"));
        hide(wrapper.querySelector(".cover"));
    }

    function initialOverlayClickHandler() {
        var wrapper = document.querySelector(".wrape");
        hideInitialOverlay(wrapper);
        wrapper.removeEventListener("click", initialOverlayClickHandler);
    }

    function initButton(selector) {
        var wrapper = document.querySelector(selector);
        wrapper.classList.add("inactive");
        wrapper.addEventListener("click", initialOverlayClickHandler);
    }
    initButton(".wrape");
}());


#5

I’m here now, I’ll see what I can do with it.


#6

ok. thanks.


#7

I was using parts of the javascript in here as the template for the youtube code.
https://jsfiddle.net/8prs9vgd/1/

I was trying to piece things together.


(function iife() {
    "use strict";

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

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

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

    function hideAllButtons(button) {
        button.querySelectorAll(".play, .pause").forEach(hide);
    }

    function getPlay(button) {
        return button.querySelector(".play");
    }

    function getPause(button) {
        return button.querySelector(".pause");
    }

    function hideInitialOverlay(wrapper) {
        wrapper.classList.remove("inactive");
        wrapper.classList.add("active");
        hide(wrapper.querySelector(".link"));
        hide(wrapper.querySelector(".cover"));
    }

    function showPlayButton(button) {
        var play = getPlay(button);
        hideAllButtons(button);
        show(play);
        button.classList.remove("active");
    }

    function isPlaying(button) {
        var play = getPlay(button);
        return play.classList.contains("hide");
    }

    function showPauseButton(button) {
        var pause = getPause(button);
        hideAllButtons(button);
        show(pause);
    }

    function getAudio() {
        return document.querySelector("audio");
    }

    function playAudio(player, src) {
        player.volume = 1.0;
        player.setAttribute("src", src);
        player.play();
    }

    function showButton(button, opts) {
        if (opts.playing) {
            showPlayButton(button);
        } else {
            showPauseButton(button);
        }
    }

    function pauseAudio(player) {
        player.pause();
    }

    function manageAudio(player, opts) {
        if (opts.playing) {
            pauseAudio(player);
        } else {
            playAudio(player, opts.src);
        }
    }

    function togglePlayButton(button) {
        var player = getAudio();
        var playing = isPlaying(button);
        showButton(button, {
            playing
        });
        manageAudio(player, {
            src: button.getAttribute("data-audio"),
            playing
        });
    }

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

    function initialOverlayClickHandler() {
        var wrapper = document.querySelector(".wrape");
        var button = wrapper.querySelector(".playButton");
        hideInitialOverlay(wrapper);
        showPlayButton(button);
        wrapper.removeEventListener("click", initialOverlayClickHandler);
        button.addEventListener("click", playButtonClickHandler);
    }

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

#8

This would be the youtube javascript code


 <div id="player"></div>



    <script>
      var tag = document.createElement('script');
      tag.src = "https://www.youtube.com/player_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

      var player;

      function onYouTubePlayerAPIReady() {
        player = new YT.Player('player', {
          height: '338',
          width: '600',
          videoId: 'M7lc1UVf-VE',
          playerVars: {
            autoplay: 1,
            controls: 1,
            showinfo: 0,
            autohide: 0,
            rel: 0,
            iv_load_policy: 3,
            cc_load_policy: 0,
            fs: 0,
            disablekb: 1,

          },
          events: {
            'onReady': onPlayerReady
          }
        });
      }

      function onPlayerReady(event) {
        event.target.setVolume(0);
        event.target.playVideo();

      }

    </script>

#9

From the working version that you mentioned above, here’s the unwanted inline scripting that you refer to.

  <div class="video" onclick="thevid=document.getElementById('thevideo');
thevid.style.display='block'; this.style.display='none';
document.getElementById('iframe').src =
document.getElementById('iframe').src.replace('autoplay=0','autoplay=1');">

Use meaningful names

That class name of video is confusing. It’s not actually a video. Cover is a better name for that element, as it’s not an image but is instead is like a book cover over the actual book.

<!--<div class="video" ...>-->
<div class="cover">
    ...
</div>

The css is the only thing that needs to be updated so that it can style the cover section.

/* .wrapg .video { */
.wrapg .cover {

Use an event handler

With the javascript, we can keep things simple and have the scripting look for only the first element that matches the .wrapg selector, and attach a click handler to that.

var cover = document.querySelector(".wrapg .cover");
....
cover.addEventListener("click", coverClickHandler);

That coverClickHandler function contains the scripting code:

function coverClickHandler(evt) {
    thevid = document.getElementById('thevideo');
    thevid.style.display = 'block';
    this.style.display='none';
    document.getElementById('iframe').src =
document.getElementById('iframe').src.replace('autoplay=0','autoplay=1');
}

That works, but it’s not yet good. We can go through the code making improvements.

Replace global variables with local variables

Global variables are almost always a bad idea. It’s better if we define the variables instead.

    // thevid = document.getElementById('thevideo');
    const thevid = document.getElementById('thevideo');

The this keyword is better replaced with a more obvious reference to the cover.

    // this.style.display='none';
    cover.style.display='none';

Use styles to change things

It’s normally a bad idea to use javascript to reach in and mess around with the styles, when using a style class can achieve the same thing instead.

In this case, using a .hide style helps to avoid all of that messing around.

.hide {
  display: none;
}

We can now add that class to the thevideo element:

<!-- <div id="thevideo"> -->
<div id="thevideo" class="hide">

This lets us remove the following style declaration:

/* .wrapg #thevideo {
  display: none;
} */

Change class names, not styles

And we can now use scripting to add/remove class names, which is a lot more preferable than messing around with separate styles.

    // style.display = 'block';
    thevid.classList.remove("hide");
    // cover.style.display='none';
    cover.classList.add("hide");

We can make things even more expressive, by using some functions to help handle the details:

const show = (el) => el.classList.remove("hide");
const hide = (el) => el.classList.add("hide");
...
    // thevid.classList.remove("hide");
    show(thevid);
    // cover.classList.add("hide");
    hide(cover);

Prefer tags before classes, and classes before identifiers

Using identifiers is the most restrictive thing that you can do, so it’s almost always better to use class names or tags names instead.

The thevideo section doesn’t seem to be needed at all, and acts as another wrapper without achieving anything for that.

We can remove that thevideo element and just refer to the iframe instead.

<!--   <div id="thevideo" class="hide"> -->
<!--     <iframe id="iframe" class="playing" ...> -->
    <iframe class="hide playing"...>
    </iframe>
<!--   </div> -->

That iframe shouldn’t have playing in there right now, that should only be added by scripting when it’s actually playing. We’ll do that shortly.

The css only needs to refer to the iframe now.

/* .wrapg #thevideo, iframe { */
.wrapg iframe {

The scripting can now more easily access the video iframe.

    const cover = evt.currentTarget;
    // const thevid = document.getElementById('thevideo');
    const thevid = cover.parentNode.querySelector("iframe");
...
    // document.getElementById('iframe').src = document.getElementB...
    thevid.src = thevid.src.replace('autoplay=0','autoplay=1');

Is there more?

Here’s the updated coverClickHandler function:

function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thevid = cover.parentNode.querySelector("iframe");
    hide(cover);
    show(thevid);
    thevid.src = thevid.src.replace('autoplay=0','autoplay=1');
}

There’s still some issues there. We’re doing work with the replace stuff, when from the handler we really should be instructing a function to do that instead, and instead of both show/hide, we can use a higher-level function called toggle.

Use toggle instead of show/hide?

We can add a simple function that toggles elements, and also supports multiple items.

const isHidden = (el) => el.classList.contains("hide");
const toggleEach = (el) => isHidden(el) ? show(el) : hide(el);
const toggle = (els) => els.map(toggleEach);
...
    // hide(cover);
    // show(thevid);
    toggle([cover, thevid]);

Is that better? I don’t think so. Using an array here seems to be messier than just having the two clear statements of intent. I prefer the hide/show code that we had before.

Use a separate play function

Wouldn’t it be great if the click handler function didn’t have the replace code in there, and instead was simpler, like this?

function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thevid = cover.parentNode.querySelector("iframe");
    hide(cover);
    show(thevid);
    play(thevid);
}

We can do that by moving the play code to a separate function.

const play = (el) => el.src = el.src.replace('autoplay=0','autoplay=1');
...

The end

And the final javascript code that we end up with is:

const show = (el) => el.classList.remove("hide");
const hide = (el) => el.classList.add("hide");
const play = (el) => el.src = el.src.replace('autoplay=0','autoplay=1');

function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thevid = cover.parentNode.querySelector("iframe");
    hide(cover);
    show(thevid);
    play(thevid);
}
const cover = document.querySelector(".wrapg .cover");
cover.addEventListener("click", coverClickHandler);

The reason why this JavaScript code is preferable, is that the click handler gives the big ideas. We hide, show, then play. It’s important for us as people reading the code, to get a big-picture understanding of what the code is doing. The details of how those things are achieved is best kept elsewhere instead.

I was going to keep fiddling with the play function, but there’s no benefit to be currently gained from doing that. Later on perhaps, but not at this stage.

There are other improvements that should be made to the HTML and CSS code, but what we have currently is about all that’s related to the JavaScript code itself.

The above improvements can be found at https://jsfiddle.net/8aebp5zt/7/


#10

Oh yes, that playing classname.

You can remove it from the classlist:

<!--  <iframe class="hide playing" ...> -->
  <iframe class="hide" ...>

Then add it when the event handler is clicked.

const setPlaying = (el) => el.classList.add("playing");
const autoplay = (el) => el.src = el.src.replace('autoplay=0','autoplay=1');
...
    setPlaying(thevid);
    autoplay(thevid);

Is playing even needed?

What happens if we remove that playing class,

// const setPlaying = (el) => el.classList.add("playing");
...
//     setPlaying(thevid);

and rename its playing style to be for the iframe instead?

/* .wrapg .playing { */
.wrapg iframe {
  ...
}
...
/* .wrapg iframe {
  width: 600px;
  height: 338px;
} */

That looks like it works just the same, without needing that playing stuff.

Here’s the working code: https://jsfiddle.net/8aebp5zt/8/


#11

Thank you for methodically going through this in precise and clear detail.

How can I add this small piece of code to it?

 },
          events: {
            'onReady': onPlayerReady
          }
        });
      }

      function onPlayerReady(event) {
        event.target.setVolume(0);

      }

Both of these work.

Would one be long form and the other short form?

Both are shown on here.
Is there a difference between them, and if so, what?

player.setVolume(50);

event.target.setVolume(50);

#12

In this circumstance I would be using ‘event’ because ‘player’ is referencing an id name.


#13

Would this go in-between here?

 },
          events: {
            'onReady': onPlayerReady
          }
        });
      }

      function onPlayerReady(event) {
        event.target.setVolume(0);

      }

Here?

function coverClickHandler(evt) {
  const cover = evt.currentTarget;
  const thevid = cover.parentNode.querySelector("iframe");
  hide(cover);
  show(thevid);
  autoplay(thevid);
}






const cover = document.querySelector(".wrapg .cover");
cover.addEventListener("click", coverClickHandler);

or would it be added on as the very last part at the end of the code ?

And would I need to add this code with it too?
Or is it not needed?
event.target.playVideo();


#14

Like this? Controlling the volume
https://jsfiddle.net/2e07dymf/3/

I removed this because it’s not being used with this:

   playerVars: {

      },
<iframe id="player" class="hide" src="https://www.youtube-nocookie.com/embed/M7lc1UVf-VE?rel=0&showinfo=0&autoplay=0&iv_load_policy=3&cc_load_policy=0&fs=0&disablekb=1&enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>


<script>
   var tag = document.createElement('script');
  tag.src = "https://www.youtube.com/player_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  var player;

  function onYouTubePlayerAPIReady() {
    player = new YT.Player('player', {

      events: {
        'onReady': onPlayerReady
      }
    });
  }

  function onPlayerReady(event) {
    event.target.setVolume(0);


  }

</script>

How would I add that into the working code?
https://jsfiddle.net/8aebp5zt/8/


const show = (el) => el.classList.remove("hide");
const hide = (el) => el.classList.add("hide");
const autoplay = (el) => el.src = el.src.replace('autoplay=0', 'autoplay=1');

function coverClickHandler(evt) {
  const cover = evt.currentTarget;
  const thevid = cover.parentNode.querySelector("iframe");
  hide(cover);
  show(thevid);
  autoplay(thevid);
}
const cover = document.querySelector(".wrapg .cover");
cover.addEventListener("click", coverClickHandler);

#16

I think I got it
https://jsfiddle.net/8aebp5zt/18/

How would I organize this code now?

Should the youtube javascript be put at the bottom of the code, or at the top?

I’m thinking at the bottom because the cover comes first, or am I wrong?

var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;

function onYouTubePlayerAPIReady() {
    player = new YT.Player('player', {
        events: {
            'onReady': onPlayerReady
        }
    });
}

function onPlayerReady(event) {
    event.target.setVolume(0);
}
const show = (el) => el.classList.remove("hide");
const hide = (el) => el.classList.add("hide");
const autoplay = (el) => el.src = el.src.replace('autoplay=0', 'autoplay=1');

function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thevid = cover.parentNode.querySelector("iframe");
    hide(cover);
    show(thevid);
    autoplay(thevid);
}
const cover = document.querySelector(".wrapg .cover");
cover.addEventListener("click", coverClickHandler);

#17

If both of these work, which is the better syntax to use and why?

And what’s the difference?

function onPlayerReady(event) {
player.setVolume(50);
}

function onPlayerReady(event) {
event.target.setVolume(50);
}




#18

I wouldn’t code it either of those two ways, so let’s take a look at the differences between them and come up with a better solution.

The first event handler

It can be important to consider questions that rise in a persons mind when the first read the code.

function onPlayerReady(event) {
    player.setVolume(50);
}

In this case, those questions are:

  • What is the player variable?
  • What is the event variable?
  • Why is event given even though it’s not used.

To answer the first question, you must scan through the code to find where player is defined.

var player;

And that’s another problem You see that it’s undefined, and must scan further throughout the code to find out where it’s assigned.

    player = new YT.Player('player', {

That’s a lot of cognitive overload that doesn’t need to occur, and after finding that out you’re not even likely to carry on with the other questions.

The second event handler

function onPlayerReady(event) {
    event.target.setVolume(50);
}

What questions arise when looking at this code?

  • What is event.target?
  • What is the range of values for 50?

To answer that we scan once more through to code, to find that it’s the onready event of the player.

    player = new YT.Player('player', {
        events: {
            'onReady': onPlayerReady

And to answer that 50 value question, on the range of values, we must go to youtubes API website page to find out that it’s a percentage value.

A better solution

We can instead use well-named variables, to help answer some of those questions.

Give the player a well-named variable

First, assign event.target to a named variable, to help us understand what it is.

function onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(50);
}

Make the volume percent obvious

Then, move that 50 to a separate variable.

function onPlayerReady(event) {
    const youtubePlayer = event.target;
    const volumePercent = 50;
    youtubePlayer.setVolume(volumePercent);
}

Currently that volume is fixed, for a const value cannot change.
If we later on intend for it to change, we can move it out of the function and use let instead. That way other code can then change the value.

Reconsidering percentage

Is the issue with volume percentage important enough it important to make the volume percentage a separate variable? I don’t think so at this stage. Instead we can just leave a small comment to help clear up any such questions instead.

    // const volumePercent = 50;
    // youtubePlayer.setVolume(volumePercent);
    youtubePlayer.setVolume(50); // percent

If we later on want to make changes to the volume, that then is a better situation in which to then extract the value out to a variable.

The final recommended code

After all of the above and the questions that come to mind, the below code helps to answer a majority of those issues.

function onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(50); // percent
}

#19

Now that I have that in, how would the code be organized?

Which code should come first?

Wait a second, I just used jslint on this and a lot came up.

var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;

function onYouTubePlayerAPIReady() {
    player = new YT.Player('player', {
        events: {
            'onReady': onPlayerReady
        }
    });
}

function onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(0); // percent
}

const show = (el) => el.classList.remove("hide");
const hide = (el) => el.classList.add("hide");
const autoplay = (el) => el.src = el.src.replace('autoplay=0', 'autoplay=1');

function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thevid = cover.parentNode.querySelector("iframe");
    hide(cover);
    show(thevid);
    autoplay(thevid);
}
const cover = document.querySelector(".wrapg .cover");
cover.addEventListener("click", coverClickHandler);

#20

Last Updated:
https://jsfiddle.net/8aebp5zt/24/

I don’t have the code organized the right way.

From top to bottom, what should go where?

How do I fix this?
Unexpected statement ‘=’ in expression position.

var tag = document.createElement("script");
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;

function onYouTubePlayerAPIReady() {
    player = new YT.Player("player", {
        events: {
            "onReady": onPlayerReady
        }
    });
}

function onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(0); // percent
}
const show = (el) => el.classList.remove("hide");
const hide = (el) => el.classList.add("hide");
const autoplay = (el) => el.src = el.src.replace("autoplay=0", "autoplay=1");

function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thevid = cover.parentNode.querySelector("iframe");
    hide(cover);
    show(thevid);
    autoplay(thevid);
}
const cover = document.querySelector(".wrapg .cover");
cover.addEventListener("click", coverClickHandler);


#21

I would add strict like this?
https://jsfiddle.net/8aebp5zt/28/

And now the audio doesn’t work.

Meaning, I have it on mute, 0, and you can hear the audio playing.

(function iife() {
    "use strict";

var tag = document.createElement("script");
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;

function onYouTubePlayerAPIReady() {
    player = new YT.Player("player", {
        events: {
            "onReady": onPlayerReady
        }
    });
}

function onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(0); // percent
}
const show = (el) => el.classList.remove("hide");
const hide = (el) => el.classList.add("hide");
const autoplay = (el) => el.src = el.src.replace("autoplay=0", "autoplay=1");

function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thevid = cover.parentNode.querySelector("iframe");
    hide(cover);
    show(thevid);
    autoplay(thevid);
}
const cover = document.querySelector(".wrapg .cover");
cover.addEventListener("click", coverClickHandler);

}());