How to keep curtains open?

How would I be able to keep the curtains open and not have them close after exiting out of the video/page?

After they open once, they would stay open, even if you go back into the same video again.

Meaning, after you click on the same svg play a 2nd time, there would be no curtain there and it would already be opened.

I figured out a way to do that here:
https://jsfiddle.net/86fdzvr4/

I was able to do this but the line is longer than 80 characters.

  function exitClickHandler(evt) {
    resetPage();
    evt.currentTarget.closest(".inner-container").querySelector(".sliding-panels").setAttribute("hidden", true);
  }

Can that line be adjusted, or written a different way? @Paul_Wilkins

Is there another way that line can be written?

What adding that line in does is: Once the curtain opens 1 time, after you exit out of the video/page, and you go back into the same one a 2nd time, no curtain will show this time.

Updated forEach code:
https://jsfiddle.net/c5f7ozum/

With this line added, that needs to be fixed and adjusted.

I think it can be written better than what I was able to come up with.

  function exitClickHandler(evt) {
    resetPage();
    evt.currentTarget.closest(".inner-container").querySelector(".sliding-panels").setAttribute("hidden", true);
  }

Let’s make the handler function easier to understand by moving the code into a separate function. The evt.currentTarget is referring to an exit button, so we will call it exitButton.

  function hideCurtains(exitButton) {
    exitButton.closest(".inner-container").querySelector(".sliding-panels").setAttribute("hidden", true);
  }
  function exitClickHandler(evt) {
    resetPage();
    hideCurtains();
  }

We can now work on improving the hideCurtains function, which is to assign a container and curtain variable. As we are using a classname there, it’s good policy to use techniques that are capable of handling multiples of them.

  function hideCurtains(exitButton) {
    const container = exitButton.closest(".inner-container");
    const curtains = container.querySelectorAll(".sliding-panels");
    curtains.forEach((curtain) => curtain.setAttribute("hidden", true));
  }
1 Like

It’s not working for some reason:
https://jsfiddle.net/4f9rzvpw/

Did I do something wrong?

Uncaught TypeError: Cannot read properties of undefined (reading ‘closest’)"

  function hideCurtains(exitButton) {
    const container = exitButton.closest(".inner-container");
    const curtains = container.querySelectorAll(".sliding-panels");
    curtains.forEach((curtain) => curtain.setAttribute("hidden", true));
  }

  function exitClickHandler() {
    resetPage();
    hideCurtains();
  }

This gave me the same error:

Uncaught TypeError: Cannot read properties of undefined (reading ‘closest’)"

  function hideCurtains(exitButton) {
    exitButton.closest(".inner-container").querySelector(".sliding-panels").setAttribute("hidden", true);
  }
  function exitClickHandler() {
    resetPage();
    hideCurtains();
  }

Just call the hideCurtains function with evt.currentTarget as the function argument.

1 Like

That worked:
https://jsfiddle.net/L0pmo9xn/

function hideCurtains(exitButton) {
    const container = exitButton.closest(".inner-container");
    const curtains = container.querySelectorAll(".sliding-panels");
    curtains.forEach(function(curtain) {
      curtain.setAttribute("hidden", true)
    });
  }

  function exitClickHandler(evt) {
    resetPage();
    hideCurtains(evt.currentTarget);
  }

I made an improvement here I think.

When I first wrote the code it used: .setAttribute

I didn’t think .setAttribute belonged in the code and wanted to use hide,
hide doesn’t work with .setAttribute but it does work with .classList

When the page resets, there’s no curtain a 2nd time. That’s how it works.

  function exitClickHandler(evt) {
    resetPage();
    hideCurtains(evt.currentTarget);
  }

Using: .classList.add("hide");

https://jsfiddle.net/df7bkxga/

  function hideCurtains(exitButton) {
    const container = exitButton.closest(".inner-container");
    const curtains = container.querySelectorAll(".sliding-panels");
    curtains.forEach(function(curtain) {
      curtain.classList.add("hide");
    });
  }

Instead of: .setAttribute("hidden", true);

https://jsfiddle.net/df7bkxga/1/

function hideCurtains(exitButton) {
    const container = exitButton.closest(".inner-container");
    const curtains = container.querySelectorAll(".sliding-panels");
    curtains.forEach(function(curtain) {
      curtain.setAttribute("hidden", true)
    });
  }

Can you at least reduce the complexity that exists in a function with one single statement, by using arrow-notation for that instead?

  function hideCurtains(exitButton) {
    const container = exitButton.closest(".inner-container");
    const curtains = container.querySelectorAll(".sliding-panels");

    curtains.forEach((curtain) => curtain.classList.add("hide"));
  }

You could even move out the arrow-notation to a named variable, so that the code becomes easier to understand.

  function hideCurtains(exitButton) {
    const container = exitButton.closest(".inner-container");
    const curtains = container.querySelectorAll(".sliding-panels");
    const hideCurtain = (curtain) => curtain.classList.add("hide");

    curtains.forEach(hideCurtain);
  }

I prefer not to use an arrow function, and this looks better I think.

https://jsfiddle.net/qmo1t89x/

  function hideCurtains(exitButton) {
    const container = exitButton.closest(".inner-container");
    const curtains = container.querySelector(".sliding-panels");
    curtains.classList.add("hide");
  }

What troubles do you have with arrow functions?

One is, jslint doesn’t like them.

JSLint doesn’t like arrow notation when they are done poorly.

JSLint likes how I do arrow notation.

2 Likes

I’ve just tried to stay away from using them.

I like to be able to see a function there and not an arrow.