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


#41

This might help you with that:
This part but I’m not sure.
.playing

<iframe class="js-playera .playinga" ></iframe>


.wrap .playa,
.playinga {
  margin: 0;
}

.wrap .playb,
.playingb {
  margin: 0 201px 0;
}

.wrap .playc,
.playingc {
  margin: 0 402px 0;
}

.wrap .playd,
.playingd {
  margin: 201px 0 0;
}

.wrap .playe,
.playinge {
  margin: 201px 201px 0;
}

.wrap .playf,
.playingf {
  margin: 201px 402px 0;
}

.wrap .playg,
.playingg {
  margin: 402px 0 0;
}

.wrap .playh,
.playingh {
  margin: 402px 201px 0;
}

.wrap .playi,
.playingi {
  margin: 402px 402px 0;
}

#42

No, that’s of no help at all.


#43

All Fixed:
https://jsfiddle.net/d72Lp43v/1/


#44

What I’m working on is for more than one of those youtube videos to be visible at the same time.
The technique that you’re using for showing the svg arrow overlay is not useful, as only one of those svg arrows ever shows at the same time.

Giving up is not a valid option either.


#45

Very good. I left one of the original iframes commented out, in case you want to use other information from it to further improve things.


#46

Is it done now?


#47

There’s more that can be done, but seems to be suitable for now.

I’ll be away next week, so it’s better to leave big changes until after then.


#48

Because this will be used with only one player:

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

  window.onYouTubePlayerAPIReady = function() {
      const videos = document.querySelectorAll(".video");
      videos.forEach(function(video) {
      const videoId = video.getAttribute("data-id");
      new YT.Player(video, {

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

    window.onYouTubePlayerAPIReady = function() {
        const video = document.querySelector(".video");
        const videoId = video.getAttribute("data-id");
        new YT.Player(video, {

If that’s all good.


#49

This will then get turned:

(function iife() {
    "use strict";
    document.querySelector(".loadplayer").addEventListener("click", function() {
        videoPlayer.init();
    });

}());

Into this I think, right?

or would this be written differently?

What would I change: “nextElementSibling” to?

If it’s only controlling 1 player?
https://jsfiddle.net/zb6mkug3/674/


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

  function coverClickHandler(evt) {
    const wrapper = evt.currentTarget.nextElementSibling;
    show(wrapper);
    videoPlayer.init(wrapper.querySelector(".video"));
  }

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

#50

It still works, there’s no need to change it.


#51

The class on this can either be: .jacketc, .play svg, or .newclassname.
https://jsfiddle.net/zb6mkug3/674/

Which would I go with?

const cover = document.querySelector(".jacketc");

#52

I’d just go with “div”. That’s the simpler situation that works.

const cover = document.querySelector("div");

[/quote]


#53

That will only work if I have only one div on the page, if I have other divs it won’t.


#54

Then stay with jacket.


#55

Would you suggest / recommend that I combine this:
https://jsfiddle.net/zb6mkug3/678/


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

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const thewrap = cover.parentNode.querySelector(".wrapg");
    hide(cover);

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

With this:


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

  function coverClickHandler(evt) {
    const wrapper = evt.currentTarget.nextElementSibling;
    show(wrapper);
    videoPlayer.init(wrapper.querySelector(".video"));
  }

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

To get this: ?
https://jsfiddle.net/zb6mkug3/676/


(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(".wrapg");
    const wrapper = evt.currentTarget.nextElementSibling;
    hide(cover);
    show(thewrap);
    show(wrapper);
    videoPlayer.init(wrapper.querySelector(".video"));
  }
  const cover = document.querySelector(".jacketc");
  cover.addEventListener("click", coverClickHandler);
}());

Would that be good to do?

Maybe it’s better to keep them separate to minimize confusion.


#56

To fix this in jslint:
image

I can do this:
https://jsfiddle.net/zb6mkug3/683/

let YT;
  window.onYouTubePlayerAPIReady = function() {
    YT = window.YT;

And that gets rid of that jslint error.

I read that here and it works:

If you are using some kind of JavaScript linting (such as jslint ot jshint) you may get errors in the console pointing out that YT is not defined. So, I simply create a variable called YT in my app and attach the one youtube will provide to it. I do this within the onYouTubeIframeAPIReady callback so it only happens when the API is definitely ready.

Is that good to do, or doesn’t make sense and I shouldn’t do it?


#57

You shouldn’t make such changes just to keep the linter happy. Making that change doesn’t benefit your code at all.

The better more honest approach is to tell jslint that YT is expected as a global variable.

/*jslint browser */
/*global YT */

#58

How would I have gotten this to work inside the javascript section?

It loads in the html
https://jsfiddle.net/zb6mkug3/684/

When I put it in the javascript it doesn’t work:
https://jsfiddle.net/zb6mkug3/685/

<script>

    document.addEventListener("DOMContentLoaded", function() {
      var div, n, v = document.getElementsByClassName("youtube");

      for (n = 0; n < v.length; n++) {
        div = document.createElement("div");
        div.setAttribute("data-id", v[n].dataset.id);
        div.innerHTML = thumb(v[n].dataset.id);
        div.onclick = iframe;
        v[n].appendChild(div);
      }
    });

    function thumb(id) {
      var thumb = '<img src="https://i.imgur.com/AJDZEOX.jpg">',
        play = '<div class="play"></div>';
      return thumb.replace("ID", id) + play;
    }

    function iframe() {
      var iframe = document.createElement("iframe");
      var embed = "https://www.youtube-nocookie.com/embed/ID?rel=0&amp;autoplay=1&amp;controls=1&amp;iv_load_policy=3&amp;cc_load_policy=0&amp;fs=0&disablekb=1";
      iframe.setAttribute("src", embed.replace("ID", this.dataset.id));
      iframe.setAttribute("frameborder", "0");
      iframe.setAttribute("width", "606");
      iframe.setAttribute("height", "344");
      this.parentNode.replaceChild(iframe, this);
      }
</script>

#59

The JavaScript is currently setup to be onload, when it needs to be set to no wrap at the bottom of the body instead.

The jvaascript panel has a top-left dropdown. Click that to find the settings.


#60

How would I get this part to work with the code?
Changing “var,” to “const ,” “for” to “let
https://jsfiddle.net/zb6mkug3/688/

Adding the iframe part to this:
https://jsfiddle.net/zb6mkug3/690/

How would I do that?

Both codes work off the same html:
<div class="video" data-id="M7lc1UVf-VE"></div>


  function iframe() {
    var iframe = document.createElement("iframe");
    var embed = "https://www.youtube.com/embed/ID?autoplay=0";
    iframe.setAttribute("src", embed.replace("ID", this.dataset.id));
    iframe.setAttribute("frameborder", "0");
    iframe.setAttribute("width", "606");
    iframe.setAttribute("height", "344");
    this.parentNode.replaceChild(iframe, this);
}

This was also with the code, I’m just not using the image stuff:


    document.addEventListener("DOMContentLoaded", function() {
      var div, n, v = document.getElementsByClassName("youtube");

      for (n = 0; n < v.length; n++) {
        div = document.createElement("div");
        div.setAttribute("data-id", v[n].dataset.id);
      /*  div.innerHTML = thumb(v[n].dataset.id);*/
        div.onclick = iframe;
        v[n].appendChild(div);
      }
    });

I’m not sure which one of these I would be using to do this:

Both are set up differently.

I think the function iframe would be the one I would be using to do this.

function iframe() {
}

1.)
This one is set up like this:
https://jsfiddle.net/zb6mkug3/728/

(function iife() {
   /* "use strict";*/

    document.addEventListener("DOMContentLoaded", function() {
      var div, n, v = document.getElementsByClassName("youtube");

      for (n = 0; n < v.length; n++) {
        div = document.createElement("div");
        div.setAttribute("data-id", v[n].dataset.id);
        /*div.innerHTML = thumb(v[n].dataset.id);*/
        div.onclick = iframe;
        v[n].appendChild(div);
      }
    });

    /*function thumb(id) {
      var thumb = '<img src="https://i.imgur.com/AJDZEOX.jpg">',
        play = '<div class="play"></div>';
      return thumb.replace("ID", id) + play;
    }*/

   function iframe() {
    var iframe = document.createElement("iframe");
    var embed = "https://www.youtube.com/embed/ID?autoplay=0";
    iframe.setAttribute("src", embed.replace("ID", this.dataset.id));
    iframe.setAttribute("frameborder", "0");
    iframe.setAttribute("width", "606");
    iframe.setAttribute("height", "344");
    this.parentNode.replaceChild(iframe, this);
}
}());

2.) This one is set up like this:
https://jsfiddle.net/zb6mkug3/727/


(function iife() {
  "use strict";

  let youtube = document.querySelector('.youtube');

  youtube.addEventListener('click', function() {
    const iframe = document.createElement("iframe");
    const embed = "https://www.youtube.com/embed/ID?autoplay=0";
    iframe.setAttribute("src", embed.replace("ID", this.dataset.id));
    iframe.setAttribute("frameborder", "0");
    iframe.setAttribute("width", "606");
    iframe.setAttribute("height", "344");
    this.parentNode.replaceChild(iframe, this);
  });
}());