viewportonloadmatchmedia

How can I fire the following listener onload using the following matchMedia


I have the below code. How can it be triggered automatically when the screen load by defaults or it is refreshed?

function screenSize(){
  const mobile = window.matchMedia('screen and (max-width: 573px)');
  const tablet = window.matchMedia('screen and (min-width: 572px) and (max-width: 990px)');
  const desktop = window.matchMedia('screen and (min-width: 990px)');

  mobile.addListener(function(evt){
    if(evt.matches) {
      alert("Mobile-view")
    }
  });

  tablet.addListener(function(evt){
    if(evt.matches) {
      alert("Tablet-view")
    }
  })

  desktop.addListener(function(evt){
    if(evt.matches) {
      alert("desktop-view")
    }
  });
}

screenSize()

It is only triggered when the viewport is resized. How can I make it fire when the viewport is loaded or refreshed?


Solution

  • Per my comment above, this is a solution to this specific problem. The answer I linked in the comments has some other possible solutions. The core problem is that queries need to be checked for .matches (bool) on window or document load, not just have listeners added to them.

    window.onload = () => {
      // set up your queries just as strings
      const mobile = 'screen and (max-width: 573px)'
      const tablet = 'screen and (min-width: 572px) and (max-width: 990px)'
      const desktop = 'screen and (min-width: 990px)'
    
      // loop over those as an obj so you have convenient key names
      Object.entries({ mobile, tablet, desktop })
        .forEach(([key, val]) => {
          // create a query object
          const query = window.matchMedia(val)
          // check if the query currently matches and alert if so
          if (query.matches) {
            alert(`${key}-view`)
          }
    
          // add the listener for resize events
          query.addListener((e) => {
            if (e.matches) {
              alert(`${key}-view`)
            }
          })
        })
    }
    

    And to use different functions for each breakpoint, you could do it like this:

    window.onload = () => {
      const mobileQuery = 'screen and (max-width: 573px)'
      const tabletQuery = 'screen and (min-width: 572px) and (max-width: 990px)'
      const desktopQuery = 'screen and (min-width: 990px)'
    
      const mobileListener = (e) => { console.log('on mobile') }
      const tabletListener = (e) => { console.log('on tablet') }
      const desktopListener = (e) => { console.log('on desktop') }
    
      const breakpoints = {
        // this object has your media query strings as keys and
        // functions to run on those breakpoints as values
        [mobileQuery]: mobileListener,
        [tabletQuery]: tabletListener,
        [desktopQuery]: desktopListener
      }
    
      Object.entries(breakpoints)
        .forEach(([query, fn]) => {
          const q = window.matchMedia(query)
          q.addListener(fn)
          if (q.matches) fn()
        })
    }