javascriptmedia-queriesmatchmedia

matchMedia / Javascript Media Query Issue


I created this function to handle the toggle for my mobile nav.

const mobileNav = document.getElementById('mobile-nav');
let tabs = document.getElementsByClassName('nav_tabs');

//nav toggle control
mobileNav.onclick = (event) => {
 event.preventDefault();
  for(let i = 0; i < tabs.length; i++) {
    if(tabs[i].style.display === "block"){
      tabs[i].style.display = "none";
    } else {
      tabs[i].style.display = "block";
    }
  }   
};

It's working on great on mobile. The problem is when I resize, the toggle is still set to display none and the toggled menu options are not visible. I have tried using this JS Media Query to reset the display block based on a min-width of 786px but it is not reseting the menu.

// media query event handler
if (matchMedia) {
const dsktp = window.matchMedia("(min-width: 768px)");
dsktp.addListener(WidthChange);
WidthChange(dsktp);
}

function WidthChange(elem) {
 for(let i = 0; i < elem.length; i++) {
  tabs[i].style.display = "block";
 } 
}

Here's a codepen of the problem.


Solution

  • Your code does not work because of this code (pay attention to the comments):

    if (matchMedia) {
      const dsktp = window.matchMedia("(min-width: 768px)");
      dsktp.addListener(WidthChange); // <-- add function as handler
      WidthChange(dsktp);
    }
    
    function WidthChange(elem) { // elem argument it is not the dom elements here
      for(let i = 0; i < elem.length; i++) {
        tabs[i].style.display = "block";
      } 
    }
    

    So you should rewrite your code this way:

    if (matchMedia) {
      const dsktp = window.matchMedia("(min-width: 768px)");
      dsktp.addListener(WidthChange);
      WidthChange(dsktp);
    }
    
    function WidthChange(mediaQueryEvent) {
      for(let i = 0; i < tabs.length; i++) {
        tabs[i].style.display = mediaQueryEvent.matches ? "block" : "none";
      } 
    }
    

    Check my fork of your pen.