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

Originally it was set like this how I thought it was supposed to be.

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

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

Reversing it puts it in scope.

Last Updated:

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

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


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 onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(0); // percent
}

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

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);

I add strict in and the audio isn’t off.


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 onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(0); // percent
}

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

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);

}());

This is the only error I get for this part of the code:

(function iife() {
    "use strict";

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);

}());

I need help figuring out how to get the youtube api javascript part to work

Inside

[

(function iife() {
    "use strict";

}());

]

Right now it’s set to mute, when it’s put inside iife there’s sound and mute is gone.

inside iife

outside iife



-----------------------------------
<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 onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(0); // percent
}

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

</script>

I found this, this might be the same issue I’m trying to figure out how to resolve.

I’m going to work forward with the code from https://jsfiddle.net/8aebp5zt/24/ on jslint.

Put JS code in the JS section

The HTML section of code is more suitable for HTML code, not for JS code.
As a result, I’ve moved the scripting code down to the JS section.
I saw that the volume was being set to 0, so I’ve updated that to set it to 50 instead.

    // youtubePlayer.setVolume(0); // percent
    youtubePlayer.setVolume(50); // percent

Clean up the formatting of the code

Because jslint complains about things being off by even a single space. all of those minor complaints are fixed by running the code through beautifier.io

Undeclared document

JSLint expects everything to be declared. Sometimes it’s appropriate to pass in a reference to the document. In this case there’s no benefit from doing so, and we can just add a JSLint declaration at the top of the code saying that we intend to run the code in a browser.

/* jslint browser */
...

Strict pragma

The “use strict” pragma tells the javascript interpreter to tighten up its standards, making it easier to find out when code starts doing bad things.

It’s applied at the start of a function, which is why it helps to use an IIFE to wrap all of the code, so that the strict pragma then applies to everything inside of it.

(function iife() {
    "use strict";
    ...
});

Undeclared YT

It’s expected that an object needs to be defined first, before it is used. Because the code loads a script that actually defines a global YT variable, we tell JSLint that it’s expected to be global.

/*global YT */

onPlayerReady is out of scope

It is expected that an object is first defined, before it is used. We can move the onPlayerReady function up above the onYouTubePlayerAPIReady function to fix that problem.

    function onPlayerReady(event) {
        ...
    }
    function onYouTubePlayerAPIReady() {
        ...
    }

Unexpected statement ‘=’ in expression position.

The problem here is with this line of code:

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

The part that says el.src = is what’s confusing things there. Arrow notation is much less confusing when assignments aren’t messing things up, so we can use setAttribute instead to keep that happy.

    // const autoplay = (el) => el.src = el.src.replace("autoplay=0", "autoplay=1");
    const autoplay = (el) => el.setAttribute("src", el.src.replace("autoplay=0", "autoplay=1"));

Line is longer than 80 characters.

This restriction helps us to keep the code nice and concise. We can use a separate method for the replace.

    // const autoplay = (el) => el.setAttribute("src", el.src.replace("autoplay=0", "autoplay=1"));
    const enableAutoplay = (el) => el.src.replace("autoplay=0", "autoplay=1");
    const autoplay = (el) => el.setAttribute("src", enableAutoplay(el));

Unused player

Check if it’s needed by anything. We don’t need to assign anything to player so that it can be accessed from elsewhere, so delete it.

//     var player;

undeclared player

Here’s the line in question:

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

There’s no need to assign it now. Future work on the code might dictate that need, but not as of yet so it’s removed.

        // player = new YT.Player("player", {
        new YT.Player("player", {

Unused onYouTubePlayerAPIReady

This onYouTubePlayerAPIReady function is called by YT, but not by our own code. We need to make that function global, so that YT can access it.

    // function onYouTubePlayerAPIReady () {
    window.onYouTubePlayerAPIReady = function () {

That’s all

And the code now minimally satisfies what JSLint is concerned about.

You can find the updated code at https://jsfiddle.net/8aebp5zt/36/

2 Likes

I have a question:

If I wanted to change the ‘id’ to a ‘class,’ how would I do that?

I found this, but how would I implement it?

I wasn’t able to get it to work.

var player = new YT.Player(
                 document.querySelector('.your-class'), 
                 ... API Stuff ...
             );

You can use document.querySelector(“.js-player”) to target the iframe.

Just rename the identifier to a class:

  <!-- <iframe id="player" ...> -->
  <iframe class="js-player"

The reason for using js-player is so that it’s a useful reminder that it’s only for scripting to use. It’s also handy reminder to expect that there’s no CSS style associated with that class name.

And then use querySelector to retrieve a reference to that element.

       // new YT.Player("player", {
       new YT.Player(document.querySelector("js-player"), {

You can find the updated code at https://jsfiddle.net/8aebp5zt/39/

The cover disappeared.

Two separate class attributes on an element are not good.

  <!-- <iframe class="js-player" class="hide" ...> -->
  <iframe class="js-player hide" ...>

That’ll teach me to just assume that a simple update is automatically going to work. Always check your work.

You can find the working code at https://jsfiddle.net/8aebp5zt/40/

The sound is on mute 0 and you can hear the audio.

You forgot the period.


(".js-player"),

Thanks for checking further. The query selector needed a fullstop at the start.

        // new YT.Player(document.querySelector("js-player"), {
        new YT.Player(document.querySelector(".js-player"), {

The updated code, now working with volume changes too, is at https://jsfiddle.net/8aebp5zt/43/

What’s this for, do I leave it in?
What does it do?
console.log(youtubePlayer);

That was just for checking that things work well. Here’s the code without it. https://jsfiddle.net/8aebp5zt/44/

You forgot to remove:
debugger;

The new update https://jsfiddle.net/8aebp5zt/45/

After all that, is it better as a class or an id?

It’s better as a class, because identifiers become like straight-jackets preventing you from doing things.

1 Like

I found out what this piece is.

Does that mean anything at all?

Is it still useless?

// global variable for the player
var player;

  // 3. This function creates an <iframe> (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          height: '390',
          width: '640',
          videoId: 'M7lc1UVf-VE',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }