Get videos to play with (“script”) inside the coverClickHandler function

Right now, when the page loads, the YouTube api is launched right away.

How do I set it up so that the YouTube api doesn’t launch until the play image is clicked?

Is there anyone who knows how this would be done?

https://jsfiddle.net/182tL0f5/

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

(function manageCurtain() {
       "use strict";
    
       function show(el) {
         el.classList.remove("hide");
       }
    
       function hide(el) {
         el.classList.add("hide");
       }
    
       function openCurtain(cover) {
         hide(cover);
         const curtain = document.querySelector(".curtain");
         curtain.classList.add("slide");
         return curtain;
       }
       
       function showVideo(curtain) {
         const thewrap = curtain.parentElement.querySelector(".wrap");
         show(thewrap);
       }
       function coverClickHandler(evt) {
         const cover = evt.currentTarget;
         const curtain = openCurtain(cover);
         showVideo(curtain);
       }
    
       const cover = document.querySelector(".play");
       cover.addEventListener("click", coverClickHandler);
     }());
    
    
     const videoPlayer = (function makeVideoPlayer() {
       "use strict";
    
       let player = null;
    
       const tag = document.createElement("script");
       tag.src = "https://www.youtube.com/iframe_api";
       const firstScriptTag = document.getElementsByTagName("script")[0];
       firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    
       function onPlayerReady(event) {
         player = event.target;
         player.setVolume(100); // percent
       }
       let hasShuffled = false;
    
       function onPlayerStateChange(event) {
         player = event.target;
         const shufflePlaylist = true;
    
         if (!hasShuffled) {
           player.setShuffle(shufflePlaylist);
           player.playVideoAt(0);
           hasShuffled = true;
         }
       }
    
       function addPlayer(video) {
    
         const playlist = "M7lc1UVf-VE";
         const config = {
           height: 360,
           host: "https://www.youtube-nocookie.com",
           width: 640
         };
         config.playerVars = {
           autoplay: 0,
           cc_load_policy: 0,
           controls: 1,
           disablekb: 1,
           fs: 0,
           iv_load_policy: 3,
           loop: 1,
           playlist,
           rel: 0
         };
         config.events = {
           "onReady": onPlayerReady,
           "onStateChange": onPlayerStateChange
         };
         player = new YT.Player(video, config);
    
       }
    
       function play() {
         player.playVideo();
       }
       return {
         addPlayer,
         play
       };
     }());
    
     function onYouTubeIframeAPIReady() {
       const cover = document.querySelector(".play");
       const wrapper = cover.parentElement;
       const frameContainer = wrapper.querySelector(".video");
       videoPlayer.addPlayer(frameContainer);
     }
    
    (function iife() {
      "use strict";
    
      function coverClickHandler(evt) {
        videoPlayer.play();
      }
    
      const cover = document.querySelector(".play");
      cover.addEventListener("click", coverClickHandler);
    }());

Sorry I didn’t get back to this.

I’m a React guy so I don’t do much DOM manipulation.

When I look at your code:

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

   let player = null;

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

That last line is what actually puts it on the DOM. For example, if I put a timeout on that last line, then it doesn’t load until that timeout is done. So, can you have that line of that function run after your button is pressed?

Furthermore, I would ask why you are worried about this? Is there some problem you are trying to solve?

Doing this worked:
https://jsfiddle.net/r1c09z38/

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const curtain = openCurtain(cover);
    showVideo(curtain);
    const tag = document.createElement("script");
    tag.src = "https://www.youtube.com/iframe_api";
    const firstScriptTag = document.getElementsByTagName("script")[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  }

How would that be done when 3 videos are being used in the javascript? @snowmonkey

Where would this be placed?

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

https://jsfiddle.net/0nhgax6t/

(function manageCovera() {
  "use strict";

  function hide(el) {
    el.classList.add("hide");
  }

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    hide(cover);
  }
  const cover = document.querySelector(".jacket-left");
  cover.addEventListener("click", coverClickHandler);
}());

(function manageCoverb() {
  "use strict";

  function hide(el) {
    el.classList.add("hide");
  }

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    hide(cover);
  }
  const cover = document.querySelector(".jacket-middle");
  cover.addEventListener("click", coverClickHandler);
}());

(function manageCoverc() {
  "use strict";

  function hide(el) {
    el.classList.add("hide");
  }

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    hide(cover);
  }
  const cover = document.querySelector(".jacket-right");
  cover.addEventListener("click", coverClickHandler);
}());

I almost got it working here. Not all the videos play when each is clicked on. @snowmonkey @kevinSmith

How is that fixed?

Doing this allows for the api not to load until it is clicked.

https://jsfiddle.net/4ymf9n8h/

(function manageCover() {

    function hide(el) {
        el.classList.add("hide");
    }

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

    const covers = document.querySelectorAll(".jacket");
    covers.forEach(function (cover) {
        cover.addEventListener("click", coverClickHandler);
    });
}());

OK, first of all, this is the kind of thread that I hate dealing with. Not only is it libraries and patterns with which I’m not familiar, but it seems to be stuff with which you are not familiar. I would recommend focussing on fundamentals first.

I’ve spent a little time and I can’t figure out why this is happening. I do however see that if I comment out this line:

    function hide(el) {
        // el.classList.add("hide");
    }

Things work more normally. I see that you are also using that on the player wrapper. It seems to be sometimes left on the players after the button is pressed, causing them to never be seen.

I think there are some issues with your DOM. Things seem to be affecting others.I also don’t understand why the video containers are divs - I wouldn’t want block elements for those. And you do a lot of positioning on these elements - why not just use a more organic layout like flex?

I don’t know, I don’t think I’m the guy to help you. The process of thinking that went into this is very different than what I do in React Native. This is about the polar opposite. I don’t think I’m the right guy to help you with this.

The hide keeps the videos hidden behind the images .

When the videos are clicked on, then the videos appear on the screen.

          <div class="wrap hide">
            <div class="video" data-id="9phZWySNsXY"></div>
          </div>

          <div class="wrap hide">
            <div class="video" data-id="qe5WF4qCSkQ"></div>
          </div>

          <div class="wrap hide">
            <div class="video" data-id="-SiGnAi845o"></div>
          </div>

With hide removed:

    function hide(el) {
        // el.classList.add("hide");
    }

Yes, I get that that is what they are supposed to do. I’m saying that it isn’t working that way. Use the dev tools inspector and see how those class tags are applied and removed.

It should be applied differently, but how then?

I’m sorry, but I’m not going to build your app for you. This is not a car repair shop or a built-to-order car shop. This is a “we will help you learn how to build a car and here is a path to learn how to do that.”

I showed you what the issue is. I suggest you spend some time trying to figure out what is going wrong. I also suggest reading up on some of the fundamentals on which this is built.

Is this your code or is it someone else’s code that you are trying to monkey into doing what you want?

How can hide be being used incorrectly?

If when I remove:

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

From here:

(function manageCover() {

    function hide(el) {
        el.classList.add("hide");
    }

    function coverClickHandler(evt) {
        const cover = evt.currentTarget;
        hide(cover);
    }

    const covers = document.querySelectorAll(".jacket");
    covers.forEach(function (cover) {
        cover.addEventListener("click", coverClickHandler);
    });
}());

And add it back to here:

const videoPlayer = (function makeVideoPlayer() {

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

Then the hide is working:

https://jsfiddle.net/5s6o8kgb/1/

or is it still being used wrong?

I’m sorry, my head hurts from looking at this. This is the exact opposite of what I do. I’m an airplane mechanic and you’re asking me to repair your speedboat. I don’t have time to take a speedboat maintenance course to help you.

I don’t have some secret knowledge here. Rather than me spend the time learning these patterns so I can lead you along each step until you get the answer, I would recommend that you spend that time learning.

I asked you if this is your code or if this is cut and pasted from somewhere else? Using code from somewhere else is not a problem - we all do it. But I never use code that I don’t understand, ever.

If this is not your code, then I’d suggest starting over and writing it yourself from scratch. Test each step along the way and understand what it is doing and how it is working.

If this is your code, then I’d suggest simplifying it until it is at a level that you understand and slowly add to it. I might even suggest starting over from scratch. For my first few “I have an idea and I want to build it” projects, I had to do that a few times. I learned a lot in the process, which with the ultimate goal of FCC, n’est-ce pas?

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.