Preventing the browser from reading the YouTube code until the image was clicked

I like to see the before and after transformation.
From ‘for loop’ to ‘forEach.’

So I can learn to do (convert) them on my own.

Here is a for loop:

var i;
for (i = 0; i < array.length; i += 1) {
    // do stuff with array[i]
}

And here is a forEach loop

array.forEach(function (item) {
  // array[i] from the previous for loop, is the same as item here
});
1 Like

What I’m wanting to do is:

Get this code:

Working in the grid code:

That’s the first objective.

The jquery has been removed, and I’m looking to transfer one code over to the other so that it is working.

After it’s working in the grid code then I want to convert it to forEach.

I’m saving both examples so I have a before and after.

This one is it working with for loop,
and this is how it looks when converted to forEach.

The trouble that I see is that the grid code seems to be already working well.

That’s why I’m asking you if you understand what the for loop does, because I think that what it does is already being done.

1 Like

In the Grid code the videos don’t pause after a new video is clicked.

That’s the functionality I want to add to the grid code.

In this code the videos do pause after a new video is clicked

Good one, so in the state change function, you’ll want to check if the current state is play, before running any kind of looping code.

Will I be doing it differently from how it is done here?

If so, I’ll just forget about how that one is set up.

And follow your directions.

Yes, that one looks it it does the job. Get it working first, and then after it’s working you can focus on converting the loop code.

1 Like

Thank you.

Step one

Before moving on to step two, this error message in the web console would need to be resolved.:

After this line is added,
players = new Array();

I get this in the web console:
ReferenceError: assignment to undeclared variable players

(1)

Adding ‘let’ resolved the console error.
let players = new Array();

But there’s still a yellow dot next to it.

The code is still working though, which is good.

Last Updated:

https://i.imgur.com/K1z5aCS.png

Would I ignore that, or is that something I would fix?

jslint doesn’t have an issue with this line.
let players = new Array();

Looking at other examples that use this:

It’s common for it to be written like this:
So, then it can stay like this, unless you think otherwise.
let players = new Array();

Step Two:

Would be moving this part:

function onYouTubeIframeAPIReady() {
    const temp = document.querySelectorAll("video");
    for (let i = 0; i < temp.length; i++) {
        const t = new YT.Player(temp[i].id, {
            events: {
                'onStateChange': onPlayerStateChange
            }
        });
        players.push(t);
    }
}

Into Here:

const playerVars = Object.assign(defaultPlayerVars, desiredPlayerVars);
    new YT.Player(video, {
      width: 200,
      height: 200,
      videoId: videoId,
      // defaultPlayerVars,
      playerVars,
      events: {
        "onReady": onPlayerReady,
        "onStateChange": onPlayerStateChange
      }
    });
  }

This is as far as I was able to get:

I’m having trouble adding this line in:
const t = new YT.Player(temp[i].id, {

It would need to be combined with this line somehow:
Which I don’t understand how I would be able to do that.
new YT.Player(video, {

const playerVars = Object.assign(defaultPlayerVars, desiredPlayerVars);
const temp = document.querySelectorAll("video");
for (let i = 0; i < temp.length; i++) {
// const t = new YT.Player(temp[i].id, {

new YT.Player(video, {
  width: 200,
  height: 200,
  videoId: videoId,
  // defaultPlayerVars,
  playerVars,
  events: {
    "onReady": onPlayerReady,
    "onStateChange": onPlayerStateChange
        }
    });
    players.push(t);
}
}

I’m noticing some different things from that code.

It checks that the url is the same, which is not as reliable as checking that the frame element is the same.
The multiple arrays (like the players array) doesn’t seem like it’s needed either.

I think that it’s best to start over without that code. Use it for inspiration certainly, but it’ll take more effort to get it working well than if you were to just edit the existing code to add that feature in.

1 Like

To help figure out a better way to do it, I had found that code here:

Give every iframe a class so that it can be identified as an iframe for youtube player.

Here’s another way of doing it I found here:

Every player object’s id can be accessed by its a.id property( a is itself an object , id is a property(string) )

Now when user plays a given player you have to just pause all other except the one being played(id of which you get in stopVideo ).Since you have id it’s easy

  function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING) {
      stopVideo(event.target.a.id);
    }
  }

  function stopVideo(player_id) {

    for (var i = 0; i < vids.length; i++) {
      if (player_id != vids[i].a.id)
        vids[i].pauseVideo();
    }
  }

http://jsfiddle.net/4t9ah1La/19/

<div id="player1"></div>
<div id="player2"></div>
<div id="player3"></div>
<div id="player4"></div>
<script>
  var tag = document.createElement('script');
  tag.src = "//www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  var player;
  var vids = [];

  function onYouTubeIframeAPIReady() {
    player1 = new YT.Player('player1', {
      height: '200',
      width: '400',
      videoId: 'gbug3zTm3Ws',
      events: {
        'onStateChange': onPlayerStateChange
      }
    });
    vids.push(player1);
    player2 = new YT.Player('player2', {
      height: '200',
      width: '400',
      videoId: 'JFBUJ6kNl28',
      events: {
        'onStateChange': onPlayerStateChange
      }
    });
    vids.push(player2);

    player3 = new YT.Player('player3', {
      height: '200',
      width: '400',
      videoId: 'pUjE9H8QlA4',
      events: {
        'onStateChange': onPlayerStateChange
      }
    });
    vids.push(player3);

    player4 = new YT.Player('player4', {
      height: '200',
      width: '400',
      videoId: 'saz1vsk69KI',
      events: {
        'onStateChange': onPlayerStateChange
      }
    });
    vids.push(player4);
  }

  function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING) {
      stopVideo(event.target.a.id);
    }
  }

  function stopVideo(player_id) {

    for (var i = 0; i < vids.length; i++) {
      if (player_id != vids[i].a.id)
        vids[i].pauseVideo();
    }
  }

</script>

These were the two spots where ‘players’ were used in the code.

This piece here:
let players = new Array();

Went with this:

  function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING) {
      const temp = event.target.getVideoUrl();
      const tempPlayers = ("video");
      for (let i = 0; i < players.length; i++) {
        if (players[i].getVideoUrl() != temp) players[i].pauseVideo();
      }
    }
  }

And this:

const playerVars = Object.assign(defaultPlayerVars, desiredPlayerVars);
const temp = document.querySelectorAll("video");
for (let i = 0; i < temp.length; i++) {
  // const t = new YT.Player(temp[i].id, {

  new YT.Player(video, {
    width: 200,
    height: 200,
    videoId: videoId,
    // defaultPlayerVars,
    playerVars,
    events: {
      "onReady": onPlayerReady,
      "onStateChange": onPlayerStateChange
    }
  });
  players.push(t);
}
}

But as you have said, maybe there’s a better way to configure the code.

I don’t think that there’s a much better way.

Define a constant called players that is an array, near the top of the videoPlayer code.
You can then push each new player into that array, for use later on.

const players = [];
...
    players.push(new YT.Player(video, {
        ...
    }));
1 Like

It’s almost working

Click on the first box ‘it plays

Click on any 2nd box, the previous box ‘pauses

Click on a 3rd box, the previous box ‘keeps playing
Not Good.

How would I add this piece in?
const t = new YT.Player(temp[i].id, {
It’s the only piece missing from the code.


const playerVars = Object.assign(defaultPlayerVars, desiredPlayerVars);
const temp = document.querySelectorAll("video");
for (let i = 0; i < temp.length; i++) {
//const t = new YT.Player(temp[i].id, {

 players.push(new YT.Player(video, {
  width: 200,
  height: 200,
  videoId: videoId,
  // defaultPlayerVars,
  playerVars,
  events: {
    "onReady": onPlayerReady,
    "onStateChange": onPlayerStateChange
    }
  }));
}

}

You wouldn’t. You can’t. It doesn’t help in any way at all.

2 Likes

What else would I adjust in the code?

This was meant to go

Click on the first box ‘ it plays

Click on any 2nd box, the previous box ‘ pauses

Click on a 3rd box, the previous box ‘ keeps playing
Not Good.

With This: My mistake

  const players = [];

  function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING) {
      const temp = event.target.getVideoUrl();
      const tempPlayers = ("video");
      for (let i = 0; i < players.length; i++) {
        if (players[i].getVideoUrl() != temp) players[i].pauseVideo();
      }
    }
  }
    const playerVars = Object.assign(defaultPlayerVars, desiredPlayerVars);
    players.push(new YT.Player(video, {
      width: 200,
      height: 200,
      videoId: videoId,
      // defaultPlayerVars,
      playerVars,
      events: {
        "onReady": onPlayerReady,
        "onStateChange": onPlayerStateChange
        
      }
   }));

How would I fix this?

SyntaxError: expected expression, got ')'

    const playerVars = Object.assign(defaultPlayerVars, desiredPlayerVars);
    const temp = document.querySelectorAll("video");
    for (let i = 0; i < temp.length; i++) {
    players.push(new YT.Player(video, {

I just added this piece to it:

    const temp = document.querySelectorAll("video");
    for (let i = 0; i < temp.length; i++) {

I got it:

    const playerVars = Object.assign(defaultPlayerVars, desiredPlayerVars);
    const temp = document.querySelectorAll("video");
    for (let i = 0; i < temp.length; i++);
    players.push(new YT.Player(video, {

This is still occurring though.

Click on the first box ‘ it plays

Click on any 2nd box, the previous box ‘ pauses

Click on a 3rd box, the previous box ‘ keeps playing
Not Good.

It works the same way whether this piece is in there or not.

  const temp = document.querySelectorAll("video");
    for (let i = 0; i < temp.length; i++);