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


#1

How exactly would I set this up so that the browser doesn’t read the code until the image was clicked?

So it doesn’t take a long time for it to load?

Is this even possible to do?

https://jsfiddle.net/zb6mkug3/532/

image


#2

Is the "Waiting for ..." message what you want to prevent?


#3

How do I prevent all the YouTube stuff from loading before anything is clicked?

For example:
https://jsfiddle.net/zb6mkug3/535/

How do I prevent all this stuff from loading before anything is clicked?
image

It happens with this one also:

Fixed Link:
https://jsfiddle.net/zb6mkug3/540/

image


#4

You want the image clickable only after the video fully loads so the “waiting” message does not appear?

I suppose you want the image button to be grayed out so the user knows it’s not ready, then when the video is available, the image goes full color.

You need to detect when the video is completely buffered. Here is how that is detected: https://stackoverflow.com/questions/8685038/tell-whether-video-is-loaded-or-not-in-javascript

Specifically:

var video = document.getElementById("video-id-name");

if ( video.readyState === 4 ) {
    // it's loaded
}

So in your CSS, you set the button as #button1 {opacity: .5} and in the JS code in the above link where it says “// it’s loaded” you’ll do the following to make it full color:

var button1 = document.getElementById('button1');
button1.style.opacity = 1;

#5

Do you recall what I was saying about using an init function, where you don’t initialize the code until you’re ready for it to do so?

Here’s an example, assigning videoplayer to a variable, and adding an init function.

const videoPlayer = (function () {
  ...
  function init(iframeSelector) {
    window.onYouTubePlayerAPIReady = function() {
      new YT.Player(document.querySelector(iframeSelector), {
        events: {
          "onReady": onPlayerReady
        }
      });
    };
  }
  return {
    init
  };
}());
videoPlayer.init(".js-playera");

That last line doesn’t need to be there, and can be moved to the jacket eventhandler code instead. Jut make sure that the videoPlayer is defined first above the jacket.


#6

I just made some adjustments:

I changed this:
https://jsfiddle.net/zb6mkug3/535/


(function iife() {
  "use strict";
  const show = (el) => el.classList.remove("hide");
  const hide = (el) => el.classList.add("hide");

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thewrap = cover.parentNode.querySelector(".wrapa");
    hide(cover);
    show(thewrap);
  }
  const cover = document.querySelector(".playa");
  cover.addEventListener("click", coverClickHandler);
}());

To this:
https://jsfiddle.net/zb6mkug3/550/

Because I think this is all the code that’s needed for this.


  (function iife() {
    "use strict";
    const show = (el) => el.classList.remove("hide");

    function coverClickHandler() {
      const thevid = document.querySelector(".wrapa");
      show(thevid);
    }

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

#7

Without the changes:
https://jsfiddle.net/zb6mkug3/550/

After the changes:

Now it’s not opening:
https://jsfiddle.net/zb6mkug3/548/

I’m going through the jslint errors right now.

Just this one:
https://jsfiddle.net/zb6mkug3/555/
Redefinition of ‘videoPlayer’ from line 25.
const videoPlayer = (function videoPlayer() {

I’m confused.


  const videaPlayer = (function videaPlayer () {
      "use strict";
      const tag = document.createElement("script");
      tag.src = "https://www.youtube.com/player_api";
      const firstScriptTag = document.getElementsByTagName("script")[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

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

      function init(iframeSelector) {
          window.onYouTubePlayerAPIReady = function() {
              new YT.Player(document.querySelector(iframeSelector), {
                  events: {
                      "onReady": onPlayerReady
                  }
              });
          };
      }
      return {
          init
      };
  }());
  videoPlayer.init(".js-playeri");

#8

I removed
const videoPlayer =

Off and it opens now.

const videoPlayer = (function videoPlayer() {
https://jsfiddle.net/zb6mkug3/556/

Click run, then click the cover right away:
The cover doesn’t open until all the YouTube stuff finishes loading.

I can get 3 clicks on it before the cover opens.

And now only the first image is clickable for some reason.

Back to the working version:
https://jsfiddle.net/zb6mkug3/557/

I just want to prevent the YouTube stuff from loading behind the cover.

So it opens on 1 click, not clicking 3 times waiting before it opens.


#9

This is the code that loads the youtube player

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

Put that code in a function, so that you can call it later.

    function loadPlayer() {
    	const tag = document.createElement("script");
    	tag.src = "https://www.youtube.com/player_api";
    	const firstScriptTag = document.getElementsByTagName("script")[0];
    	firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }
    loadPlayer();

Now the only thing that loads the youtube player is that loadPlayer() line. You can move that into an init function.

    // loadPlayer();
    function init() {
      loadPlayer();
    }
    init();

And we don’t want that init() to run immediately, so assign the videoplayer to a local variable, and return the init function.

// (function videoPlayer() {
const videoPlayer = (function videoPlayer() {
    ...
    return {
      init
    };
});
videoPlayer.init();

And we now have that videoPlayer.init statement that’s outside of the videoplayer code, letting you move that line to wherever you want to initialize the videoplayer, which seems to be in the cover click event.


#10

Which code am I using?

1.) , or 2.) ?

Like this?

1.)
https://jsfiddle.net/zb6mkug3/559/

Did I put something in the wrong place?
image

const videoPlayer = (function videoPlayer() {
    "use strict";

    function loadPlayer() {
      const tag = document.createElement("script");
      tag.src = "https://www.youtube.com/player_api";
      const firstScriptTag = document.getElementsByTagName("script")[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }
    loadPlayer();

    function init() {
      loadPlayer();
    }
    init();

    function onPlayerReady(event) {
      const youtubePlayer = event.target;
      youtubePlayer.setVolume(100);
    }
    window.onYouTubePlayerAPIReady = function() {
      new YT.Player(document.querySelector(".js-playera"), {
        events: {
          "onReady": onPlayerReady
        }
      });
    };
  }());
  return {
    init
  };
  });
  videoPlayer.init();

Or am I using this code?

2.)
https://jsfiddle.net/zb6mkug3/560/


const videoPlayer = (function videoPlayer() {
    "use strict";
    function loadPlayer() {
    	const tag = document.createElement("script");
    	tag.src = "https://www.youtube.com/player_api";
    	const firstScriptTag = document.getElementsByTagName("script")[0];
    	firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }
    loadPlayer();
    
       function init() {
      loadPlayer();
    }
    init();

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

    function init(iframeSelector) {
      window.onYouTubePlayerAPIReady = function() {
        new YT.Player(document.querySelector(iframeSelector), {
          events: {
            "onReady": onPlayerReady
          }
        });
      };
    }
    return {
      init
    };
});
videoPlayer.init();

I’m still not getting it.


#11

First I do this:

const videoPlayer = (function videoPlayer() {
    "use strict";
    function loadPlayer() {
    	const tag = document.createElement("script");
    	tag.src = "https://www.youtube.com/player_api";
    	const firstScriptTag = document.getElementsByTagName("script")[0];
    	firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }
    loadPlayer();

Then this gets added next:

    function init() {
      loadPlayer();
    }
    init();

Then this comes after that:

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

Am I adding this:

    function init(iframeSelector) {
      window.onYouTubePlayerAPIReady = function() {
        new YT.Player(document.querySelector(iframeSelector), {
          events: {
            "onReady": onPlayerReady

Or this after?

    window.onYouTubePlayerAPIReady = function() {
      new YT.Player(document.querySelector(".js-playera"), {
        events: {
          "onReady": onPlayerReady

After that, then this comes next:

        }
      });
    };
  }());
  return {
    init
  };
  });
  videoPlayer.init();

#12

What you are wanting is for the youtube players to be not there, so that later on you can use the youtube scripting code to put them there. Is that right?

If so, remove the jacket and remove the cover on one of them (the first for example), to help you confirm that the youtube player is not there.

I think that you’ll find that none of your scripting code currently shows the youtube player. That the youtube player itself shows without needing any of the scripting code.

I’ll be able to investigate this further later.


#13

So it’s not confusing I’ll do 1 player first, before I do the other 8.
https://jsfiddle.net/zb6mkug3/564/

I got up to here:
https://jsfiddle.net/zb6mkug3/565/

image


#14

If I remove the cover/jacket the YouTube player is still there.
https://jsfiddle.net/zb6mkug3/564/

Only the first cube opens because the rest of the javascript is hidden.

All of this comes up whether the cover is on or off.
Even if the YouTube stuff is hidden, all of that still comes up.
image


#15

How is this code able to do it?
https://jsfiddle.net/zb6mkug3/568/

This uses this:

How would I replicate that in my code?


  <div class="video-thumb embed" onclick="playVideo(this)" data-video-url="https://www.youtube.com/watch?v=JtV3ZB813bg">
  <iframe src="" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
  <figure >
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path d="M0 0h24v24H0z" fill="none"/>
      <path d="M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
    </svg>
  </figure>
</div>

<br>

<div class="video-thumb embed" onclick="playVideo(this)" data-video-url="https://www.youtube.com/watch?v=JtV3ZB813bg">
  <iframe src="" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
  <figure >
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path d="M0 0h24v24H0z" fill="none"/>
      <path d="M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
    </svg>
  </figure>
</div>



var videoActive;

function playVideo(element) {
  if (videoActive) {
    stopVideo();
  }
  var videoUrl = element.dataset.videoUrl;
  var vParam = videoUrl.split('v=');
  var videoId = vParam[1].includes('&') ? vParam[1].substring(0, vParam[1].indexOf('&')) : vParam[1];
  var embedUrl =
  'https://www.youtube.com/embed/' +
  videoId +
  '?rel=0&controls=1&showinfo=0&autoplay=1';

  var figure = element.querySelector('figure');
  var iframe = element.querySelector('iframe');

  element.classList.add('active');
  iframe.src = embedUrl;
  videoActive = element;
}

function stopVideo() {
  var figure = videoActive.querySelector('figure');
  var iframe = videoActive.querySelector('iframe');
  videoActive.classList.remove('active');
  iframe.src = '';
}



#16

I think that you need to go back to primary sources.

What does the youtube API have to say, (both HTML and JS), when it comes to using scripting to load in the youtube player.


#17

I don’t know.

It can’t be done then?

https://developers.google.com/youtube/player_parameters


#18

I have updated the code so that only one youtube player is being used, with the rest of them in the HTML code being commented out.

The error was to use the iframe, for that immediately creates the youtube player. Instead of doing that you want to use the scripting code to give the options for the youtube player.

Currently the code loads one youtube player, unconfigured, un the coverClickHandler function.
I’ve moved it down below the youtubePlayer code, as the later code needs to access the youtubePlayer to initialize it.

The updated code is at https://jsfiddle.net/zb6mkug3/570/ and needs to be configured to load a video into the first player area.


#19

I don’t see a difference though, am I supposed to?

I had thought that all that stuff could be blocked out so it’s not read until it’s clicked.

But I guess it can’t be.

image


#20

I don’t think that I understand what you want to achieve.