Closing a modal

Clicking the close button while the video is playing shuts it off.

Clicking on the background while it is playing does not.

I am trying to fix that so when the background is clicked, it does shut off.

https://jsfiddle.net/edkr2w7p/

function createResetHandler(player) {
  const myModal = document.querySelector("#myModal");
  const close = document.querySelector(".close");
  const resetVideo = close;

  resetVideo.addEventListener("click", function resetVideoHandler() {
    resetVideo.removeEventListener("click", resetVideoHandler);
    player.destroy();
    myModal.classList.remove("open");
    console.log("hit");
  });
}

You will need to duplicate the js that you are doing for .close but do it for the overlay as well. You should be able to work that out as I already added an event listener to it to close the modal.

I don’t understand, what do you mean the overlay?

Look at my demo. What two elements do I add a click listener that will close the modal? One is the close button and the other is…,

Now only the 1st video shuts off when the x button is clicked.

https://jsfiddle.net/7vwogtqa/

Up to your question.

blog-pager close

I don’t understand still what you mean by duplicate the javascript.

(function (d) {
  const myModal = d.querySelector("#myModal");
  const close = d.querySelector(".close");
  close.addEventListener("click", clickMenu);
    myModal.addEventListener("click", clickMenu);
  function clickMenu() {
    myModal.classList.remove("open");
  }
})(document);
(function (d) {
  const myModal = d.querySelector("#myModal");
  const close = d.querySelector(".blog-pager");
  close.addEventListener("click", clickMenu);
    myModal.addEventListener("click", clickMenu);
  function clickMenu() {
    myModal.classList.remove("open");
  }
})(document);

The above is the code that closes the modal when you click close.

Replicate that code but do it for the modal not the button.

Change all the variables accordingly and add the event listener to the modal and not .close

e.g.This is unchecked as typing on a mobile at the moment but you should get the idea.

const close2 = document.querySelector(".myModal");
  const resetVideo2= close2;

  resetVideo2.addEventListener("click", function resetVideoHandler2() {
    resetVideo2.removeEventListener("click", resetVideoHandler2);
    player.destroy();
    myModal.classList.remove("open");
    console.log("hit");
  });

Once you have it working you could have the event listeners call a single named function instead of two routines.

As I said I’m only on a mobile at moment so you’ll have to wait until tomorrow if you can’t do it yourself.

too confusing. I’ll wait.

AI came up with this that works: https://jsfiddle.net/vbu2k9yr/3/

Now I’m trying to improve it.

function createResetHandler(player) {
  const myModal = document.querySelector("#myModal");
  const close = document.querySelector(".close");
  const ytplayer0 = document.querySelector("#ytplayer0");

  function clickMenu() {
    if (player && player.getIframe() && ytplayer0 && player.getIframe().id === ytplayer0.id) {
      player.destroy();
      myModal.classList.remove("open");
      console.log("hit");
    }
  }

  close.addEventListener("click", clickMenu);
  myModal.addEventListener("click", clickMenu);
}

That’s basically what I told you to do. :wink:

Would I be able to get it to work without the if statement?

These were taken from older codes:

They all use destroy.

 const resetVideos = document.querySelectorAll(".exit");
  resetVideos.forEach(function resetVideoHandler(video) {
    video.addEventListener("click", function resetVideoHandler() {
      video.parentElement.player.destroy();
      console.log('hit')
    });
  })

  function createResetHandler(player) {
    const exitButton = player.getIframe().closest(".container")
    const resetVideo = exitButton.querySelector(".exit");
    resetVideo.addEventListener('click', function resetVideoHandler() {
      resetVideo.removeEventListener('click', resetVideoHandler);
      player.destroy();
      console.log('hit')
    });
  }

  function createResetHandler(player) {
    const exitBtn = player.getIframe().closest('.container').querySelector('.exit');
    exitBtn.addEventListener('click', function resetVideoHandler() {
      player.destroy();
      console.log('hit')
    });
  }

  function createResetHandler(player) {
    const exitBtn = player.getIframe().closest('.container')
    const exitBtnb = exitBtn.querySelector('.exit');
    exitBtn.addEventListener('click', function resetVideoHandler() {
      exitBtn.removeEventListener('click', resetVideoHandler);
      player.destroy();
      console.log('hit')
    });
  }

  let resetHandlerDone = false;

  function createResetHandler(player) {
    if (resetHandlerDone) return;
    resetHandlerDone = true;

    function resetVideoHandler() {
      player.destroy();
      console.log('hit')
    }

    const resetVideos = document.querySelectorAll(".exit");
    resetVideos.forEach(function resetVideo(video) {
      video.addEventListener("click", resetVideoHandler);
    });
  }

  let resetHandlerDone = false;

  function createResetHandler(player) {
    if (resetHandlerDone) return;
    resetHandlerDone = true;
    const resetVideos = document.querySelectorAll(".exit");
    resetVideos.forEach(function resetVideoHandler(video) {
      video.addEventListener("click", function resetVideoHandler() {
        player.destroy();
      });
    });
  }

  let resetHandlerDone = false;

  function createResetHandler(player) {
    if (resetHandlerDone) return;
    resetHandlerDone = true;

    function resetVideoHandler() {
      player.destroy();
      console.log('hit')
    }

    const resetVideos = document.querySelectorAll('.exit');
    for (let i = 0; i < resetVideos.length; i++) {
      resetVideos[i].addEventListener('click', resetVideoHandler);
    }
  }


  function createResetHandler(player) {
    const resetVideos = document.querySelectorAll('.exit');
    for (let i = 0; i < resetVideos.length; i++) {
      resetVideos[i].addEventListener('click', function resetVideoHandler() {
        player.destroy();
      });
    }
  }



  function Once(fn) {
    let run = true
    return function(...args) {
      if (!run) return
      run = false
      return fn(...args)
    }

  }

  const createResetHandler = Once(function(player) {
    const resetVideos = document.querySelectorAll('.exit')
    resetVideos.forEach(function resetVideoHandler(video) {
      video.addEventListener('click', function resetVideoHandler() {
        player.destroy()
        console.log('hit')
      })
    })
  })

  const resetVideo = document.querySelectorAll(".exit");
  resetVideo.forEach(function resetVideoHandler(video) {
    video.addEventListener("click", function resetVideoHandler() {
      video.parentElement.querySelector(".wrap").player.destroy();
      console.log("hit");
    });
  })

  const createResetHandler = Once(function(player) {

    function resetVideoHandler() {
      player.destroy();
      console.log('hit')
    }

    const resetVideos = document.querySelectorAll('.exit');
    for (let i = 0; i < resetVideos.length; i++) {
      resetVideos[i].addEventListener('click', resetVideoHandler);

    }
  })


  function createResetHandler(player) {
    document.addEventListener("click", function({
      target
    }) {
      if (target.closest(".exit")) {
        player.destroy();
        console.log("hit")
      }
    }, {
      once: true
    });
  }

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

To remove the if statement, I was told:

You can restructure your HTML so that the close element is outside the modal element.

Here is the code without the if statement: https://jsfiddle.net/hypd6m4b/

function createResetHandler(player) {
  const myModal = document.querySelector("#myModal");
  const close = document.querySelector(".close");
  const ytplayer0 = document.querySelector("#ytplayer0");

  function clickMenu() {
    player.destroy();
    myModal.classList.remove("open");
    console.log("hit");
  }

  close.addEventListener("click", clickMenu);
  myModal.addEventListener("click", clickMenu);
}

“Script error.” comes up in console log.

When I click on a 2nd video, any video.

“Script error.” comes up in console log.

I think you’ll needs to ask this JS question in the JS forum now as the original question was about coding the popup but now has moved on to a more specific JS question…

1 Like

Agreed. I’ve split the thread. smile

2 Likes

I have this here where all the videos are showing:

Which is what I want, what I am trying to do:

I most likely removed too much from the working code for the videos to be visible on the screen.

I think I am closer to getting it working.

<div class="container1 ">
  <div class="curtain1">
    <div class="ratio-keeper">
      <div class="wrap embed-youtube">
        <div class="video embed-youtube">
        </div>
        <div class="playa"></div>
      </div>
    </div>
    <div class="exit"></div>
  </div>
</div>

https://jsfiddle.net/vgjad360/2/

Here is the working code: https://jsfiddle.net/u2pn17we/

Videos are hidden:

And the remove player works on this one.

Which is what I am trying to have work in the other code.

  function removePlayer(wrapper) {
    wrapper.player.destroy();
    delete wrapper.player;
    console.log("removePlayer");
  }

  function removePlayerHandler(evt) {
    const el = evt.target;
    const container = el.closest(".container");
    const wrapper = container.querySelector(".wrap");
    if (wrapper.player) {
      return removePlayer(wrapper);
    }
  }

What I am trying to do now is,

Get the working code to be where, the videos are all showing.

Where clicking on the X or around the background area removes the player.

I am not really sure how to figure this one out.

Adding code back in I was able to get this far with no errors:

no videos appearing though.

https://jsfiddle.net/ux8jm6eq/5/

Here is the code with videos appearing:

https://jsfiddle.net/ux8jm6eq/2/

Here is the full working code: has buttons: https://jsfiddle.net/u2pn17we/

Update: Here I have the videos appearing: https://jsfiddle.net/aps6gjc1/

I think I am a bit closer of it working.

Next, trying to get remove player working.

Working on this code: https://jsfiddle.net/aps6gjc1/

 <div id="myModal" class="modal open">
  <div class="modal-content">
    <div class="blog-pager close">
      <a title="Exit" aria-label="Close"></a>
    </div><div class="container">
    <div class="ratio-keeper wrap">
      <div class="video " data-id="1Q1aDAnBsU8"></div>
    </div>  </div>
    <div class="playa"></div>
  </div>
</div>
const manageUI = (function makeManageUI() {

  function exitClickHandler() {
  
  }

  function addClickToExit(exitButtons) {
    exitButtons.forEach(function addExitButtonHandler(exitButtons) {
      exitButtons.addEventListener("click", exitClickHandler);
    });
  }

  function addExitHandlers(callback) {
    const resetVideo = document.querySelectorAll(".close");
    resetVideo.forEach(function resetVideoHandler(video) {
      video.addEventListener("click", callback);
    });
  }

  function init() {
    const exitButtons = document.querySelectorAll(".close");
    addClickToExit(exitButtons);
  }

  return {
    addExitHandlers,
    init
  };
}());
 function removePlayer(wrapper) {
    wrapper.player.destroy();
    delete wrapper.player;
    console.log("removePlayer");
  }

  function removePlayerHandler(evt) {
    const el = evt.target;
    //const container = el.closest(".container");
    const wrapper = document.querySelector(".wrap");
    if (wrapper.player) {
      return removePlayer(wrapper);
    }
  }

  function init() {
    manageCover.init({
      container: ".container"
    });

    manageUI.init({});
    manageUI.addExitHandlers(managePlayer.removePlayerHandler);
  }

  return {
    add: addPlayer,
    init
  };
}());
 function show(el) {
    el.classList.remove("hide");
  }

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

  function exitClickHandler() {
    const thewrap = document.querySelector(".blog-pager");
    show(thewrap);
    const cover = document.querySelector(".close");
    hide(cover);
  }

Do you have a version that is fully working (i.e. the button stops the player) before you added the modal so we can see what it should look like?

Also are you now only turning off the one player or will you have buttons for all the other players?

That would be this one: https://jsfiddle.net/u2pn17we/

You click the blue play button.

then the red exit button.

then in console log it says: remove player.

I was thinking of this one where you had it all working except for shutting the player down when you clicked the background.

As I mentioned before you can just duplicate the existing routine like this:

That’s what you seemed to be asking for?

It should say 1 not 10 after clicking the close button. https://jsfiddle.net/5qbgnayt/

In that code, there is only 1 scroll bar.

How did you do that?

because I had this on viewable for some reason:

body:has(.modal.open){
  overflow: viewable;
}