javascriptscopeglobal-variablesaddeventlistener

Global Variable is not being accesses in a particular block


I created a boolean variable at the top of my js code, It worked perfectly throughout the code and changes globally when its value changes in all Functions/Block where it is used. But in a particular block, I had to declare and initialize it again before it could be accessed in that block.It was a "document.addEventListener" block

I'm working on a responsive design so I created different event listeners for different width sizes.

It happened like this:

let isVisible = false
let query = window.matchMedia("(max-width: 600px)");

document.addEventListener("DOMContentLoaded", () => {
  if (query.matches) {
    button.addEventListener("click", () => {
      if (!isVisible) {
        searchBar.style.display = "block";
        isVisible = true;
      } else if (isVisible && searchBar.value) {
        get_movie(searchBar.value);
      } else {
        searchBar.style.display = "none";
        isVisible = false;
      }
    });
  }
});

The button.addEventListener doesn't run at all because the isVisible conditions are yet to be met which is because the global variable is not being accessed.

It only starts running when I declare isVisible again inside that document.addEventListener block.


Solution

  • The problem isn't the isVisible variable, it's query. It's set to the media query result when the page is first loaded. If it doesn't match at that time, the button.addEventListener() call is never executed.

    Add the click event listener unconditionally. Then do the media check inside it, so it will be responsive.

    let isVisible = false
    
    document.addEventListener("DOMContentLoaded", () => {
      const button = document.querySelector("put selector here");
      button.addEventListener("click", () => {
        if (window.matchMedia("(max-width: 600px)").matches) {
          if (!isVisible) {
            searchBar.style.display = "block";
            isVisible = true;
          } else if (isVisible && searchBar.value) {
            get_movie(searchBar.value);
          } else {
            searchBar.style.display = "none";
            isVisible = false;
          }
        }
      });
    });

    An alternative is to listen for changes in the media query, and add/remove the click event listener as needed.

    let isVisible = false
    let query = window.matchMedia("(max-width: 600px)");
    
    query.addEventListener("change", () => {
      const button = document.querySelector("put selector here");
      if (query.matches) {
        button.addEventListener("click", toggleSearchBar);
      } else {
        button.removeEventListener("click", toggleSearchBar);
      }
    });
    
    function toggleSearchBar() {
      if (!isVisible) {
        searchBar.style.display = "block";
        isVisible = true;
      } else if (isVisible && searchBar.value) {
        get_movie(searchBar.value);
      } else {
        searchBar.style.display = "none";
        isVisible = false;
      }
    }