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

src Works:

var temp = event.target.a.src;
if (players[i].a.src != temp) players[i].pauseVideo();

getVideoUrl Doesn’t Work:

const temp = event.target.getVideoUrl();
if (players[i].getVideoUrl() != temp) players[i].pauseVideo();

Well let’s take a look at what’s not going right, and why.

That’s happening because of what I warned you about earlier on. The code that you copied isn’t designed to do what you want it to do, and falls apart when the video URL is the same for any of the videos.

      const temp = event.target.getVideoUrl();
      ...
        if (players[i].getVideoUrl() != temp) players[i].pauseVideo();

You don’t need to get getVideoUrl() and check that. You can instead directly compare if the player equals the event target.

      // const temp = event.target.getVideoUrl();
      ...
        // if (players[i].getVideoUrl() != temp) players[i].pauseVideo();
        if (players[i] !== event.target) players[i].pauseVideo();

and that code is now ready to be converted to foreach code:

      players.forEach(function pauseOtherVideos(player) {
        if (player !== event.target) {
          player.pauseVideo();
        }
      });

and we can remove the if statement by filtering before using forEach:

      players.filter(function otherVideos(player) {
        return player !== event.target;
      }).forEach(function pauseVideo(player) {
        player.pauseVideo();
      });

And we can then move each function out of the code:

      function otherVideos(player) {
        return player !== event.target;
      }
      function pauseVideo(player) {
        player.pauseVideo();
      }
      players.filter(otherVideos).forEach(pauseVideo);

and you can then simplify those functions by using arrow notation:

      const otherVideos = (player) => player !== event.target;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);

And look - we suddenly have better code!

2 Likes

I found that src works:

src Works:

var temp = event.target.a.src;
if (players[i].a.src != temp) players[i].pauseVideo();

:banghead:

1 Like

What?

The code doesn’t seem to fall apart when src is used instead of video url.

I just did it your way:

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

How would I add this piece on to it?

I know this would come after playing

    const player = event.target;
    const playerVars = player.b.b.playerVars;
    if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
      player.seekTo(playerVars.start);
    }
  }

I think I figured it out:
Like this, right?

function onPlayerStateChange(event) {
        if (event.data === YT.PlayerState.PLAYING) {
            const tempPlayers = ("video");
            const otherVideos = (player) => player !== event.target;
            const pauseVideo = (player) => player.pauseVideo();
            players.filter(otherVideos).forEach(pauseVideo);
        } else {
            const player = event.target;
            const playerVars = player.b.b.playerVars;
            if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
                player.seekTo(playerVars.start);
            }
        }
    }

It’s much better when you don’t have the else part, and move the if statement for playing, down below the if statement for ended.

Why wouldn’t PLAYING come first?
Wouldn’t that make sense?

PLAYING
ENDED

Instead of:

ENDED
PLAYING

    function onPlayerStateChange(event) {
        const player = event.target;
        const playerVars = player.b.b.playerVars;
        if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
            player.seekTo(playerVars.start);
        }
        if (event.data === YT.PlayerState.PLAYING) {
            const tempPlayers = ("video");
            const otherVideos = (player) => player !== event.target;
            const pauseVideo = (player) => player.pauseVideo();
            players.filter(otherVideos).forEach(pauseVideo);
        }
    }

How come not like this?

    function onPlayerStateChange(event) {
        if (event.data === YT.PlayerState.PLAYING) {
            const tempPlayers = ("video");
            const otherVideos = (player) => player !== event.target;
            const pauseVideo = (player) => player.pauseVideo();
            players.filter(otherVideos).forEach(pauseVideo);
        }
        const player = event.target;
        const playerVars = player.b.b.playerVars;
        if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
            player.seekTo(playerVars.start);
        }
    }

I was thinking because the consts are usually at the top. The main interest was in removing the else clause.
The order doesn’t matter so Playing at the top is good.

2 Likes

To help avoid confusion, I would use video instead of player in the following code:

        if (event.data === YT.PlayerState.PLAYING) {
            const tempPlayers = ("video");
            // const otherVideos = (player) => player !== event.target;
            const otherVideos = (video) => video !== event.target;
            // const pauseVideo = (player) => player.pauseVideo();
            const pauseVideo = (video) => video.pauseVideo();
            players.filter(otherVideos).forEach(pauseVideo);
        }

That way, we are ensuring that player is only used to refer to the current player, and video is used to any of the videos.

That way, you can then have const player at the top of the code, being beneficial for both if statements.

        const player = event.target;
        if (event.data === YT.PlayerState.PLAYING) {
            const tempPlayers = ("video");
            // const otherVideos = (video) => video !== event.target;
            const otherVideos = (video) => video !== player;
            const pauseVideo = (video) => video.pauseVideo();
            players.filter(otherVideos).forEach(pauseVideo);
        }
        // const player = event.target;
        const playerVars = player.b.b.playerVars;
        if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
            player.seekTo(playerVars.start);
        }
1 Like

Yes, that’s way better, thank you.

In the process of saving all these examples, an error came up on this one.
How would this have been fixed / resolved?

image


I think it wanted me to do this:
And that fixed those errors.

  function onPlayerStateChange(event) {
      function otherVideos(player) {
          return player !== event.target;
      }

      function pauseVideo(player) {
          player.pauseVideo();
      }
      if (event.data === YT.PlayerState.PLAYING) {
          players.filter(otherVideos).forEach(pauseVideo);
      }
  }

I just realized that this line isn’t needed or required in the code:
const tempPlayers = ("video");
Am I right?

function onPlayerStateChange(event) {
    const player = event.target;
    if (event.data === YT.PlayerState.PLAYING) {
        const otherVideos = (video) => video !== player;
        const pauseVideo = (video) => video.pauseVideo();
        players.filter(otherVideos).forEach(pauseVideo);
    }
    const playerVars = player.b.b.playerVars;
    if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
        player.seekTo(playerVars.start);
    }
}

How would I have been able to convert this to .forEach?

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

I would be trying to add it into something like this:

  function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
     players.forEach(function pauseOtherVideos(player) {
        if (player !== event.target) {
          player.pauseVideo();
        }
      });
    }
  }

Then into something like this:

      const otherVideos = (player) => player !== event.target;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);

I think I got the 1st part here:

function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      players.forEach(function pauseOtherVideos(player) {
        if (player.a.src !== temp) {
          player.pauseVideo();
        }
      });
    }
  }

Next would be putting it inside this:

 function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const otherVideos = (player) => player !== event.target;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }
  }

I tried this but that didn’t work:
https://jsfiddle.net/d72Lp43v/381/

 function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = (player) => player !== event.target.a.src;
      const pauseVideo = (player) => player.a.src !== temp.pauseVideo();
      players.filter(temp).forEach(pauseVideo);
    }
}

I also tried this:
https://jsfiddle.net/d72Lp43v/383/

  function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      const pauseVideo = (player) => player.a.src !== temp.pauseVideo();
      players.filter(temp).forEach(pauseVideo);
    }
}

I’m Stuck

Trying to put this piece:

function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      players.forEach(function pauseOtherVideos(player) {
        if (player.a.src !== temp) {
          player.pauseVideo();
        }
      });
    }
  }

Into Here
It seems like everything I try doesn’t work.

 function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const otherVideos = (player) => player !== event.target;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }
  }
1 Like

I think I got it Here:

This:

function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      players.forEach(function pauseOtherVideos(player) {
        if (player.a.src !== temp) {
          player.pauseVideo();
        }
      });
    }
  }

Would become this:

  function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      const otherVideos = (player) => player.a.src !== temp;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }
  }

And This:
https://jsfiddle.net/d72Lp43v/389/

  function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.getVideoUrl();
      players.forEach(function pauseOtherVideos(player) {
        if (player.getVideoUrl() != temp) {
          player.pauseVideo();
        }
      });
    }
  }

Would become this:
And I changed all the urls so it will work this time.
https://jsfiddle.net/d72Lp43v/391/

  function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.getVideoUrl();
      const otherVideos = (player) => player.getVideoUrl() != temp;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }
  }

Next would be putting this:

  function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      const otherVideos = (player) => player.a.src !== temp;
      const pauseVideo = (player) => player.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }
  }

Into Here:

      function onPlayerStateChange(event) {
        const player = event.target;
        if (event.data === YT.PlayerState.PLAYING) {
          const otherVideos = (video) => video !== player;
          const pauseVideo = (video) => video.pauseVideo();
          players.filter(otherVideos).forEach(pauseVideo);
        }
        const playerVars = player.b.b.playerVars;
        if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
          player.seekTo(playerVars.start);
        }
        }

This was my attempt:
But I didn’t get it.
How would this one be done?
I’m stuck.
I think I almost got it.
https://jsfiddle.net/d72Lp43v/396/

It’s this line here:
const otherVideos = (video) => video !== player.a.src !== temp;
Which I’m having issues with.

 function onPlayerStateChange(event) {
    const player = event.target;
    if (event.data === YT.PlayerState.PLAYING) {
      const temp = event.target.a.src;
      const otherVideos = (video) => video !== player.a.src !== temp;
      const pauseVideo = (video) => video.pauseVideo();
      players.filter(otherVideos).forEach(pauseVideo);
    }

    const playerVars = player.b.b.playerVars;
    if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
      player.seekTo(playerVars.start);
    }
  }

You don’t need temp. Just check that the video (which loops through each player) isn’t the current player.

      // const temp = event.target.a.src;
      // const otherVideos = (video) => video !== player.a.src !== temp;
      const otherVideos = (video) => video !== player;

I know that, I’m making different versions.

How would I get it to work using temp?
const otherVideos = (video) => video !== player.a.src !== temp;

How would I re-write that line differently?

The code works, it’s just that line:

What are you wanting to achieve with it that isn’t already being done?

1 Like