0

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?

Kiki-ko
  • 1
  • 5
  • See [this question](https://stackoverflow.com/a/59623249/5774952) for how to test media queries on load in JS. But that won't fix all your problems: you have several typos. `screenSiz -> screenSize`, `checkTablet -> tablet`, `checkDesktop -> desktop` (or vice versa). – Zac Anger Jul 23 '23 at 03:03
  • Thanks Zac, typo error corrected. However, I can’t seamz to be able to have my head rap around those solution that are posted in that link. Considering the fact that I already have a function that is already wrapped around some viewport listeners – Kiki-ko Jul 23 '23 at 07:02
  • Yeah so the core problem is that you really need to check if the query matches on load, not wait for a listener to fire. I'll add an answer with some example code, though there are several ways to do it (including ones in the answers to the question I linked) – Zac Anger Jul 23 '23 at 18:03

1 Answers1

0

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()
    })
}
Zac Anger
  • 6,983
  • 2
  • 15
  • 42
  • one more thing. now that I have been able to fire the onload by default with your solution. how can I run a function for each viewport? previously this is what I did. – Kiki-ko Jul 24 '23 at 05:28
  • `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) { mobi () } }); tablet.addListener(function(evt){ if(evt.matches) { tab () } }) desktop.addListener(function(evt){ if(evt.matches) { desk () } }); } screenSize()` – Kiki-ko Jul 24 '23 at 05:29
  • and these are the functions that I want to run for each viewport, `() mobi => {}`, `() tab => {}`, `() desk => {}` so how can I incorporate each of these functions with the appropriate viewports. Many thanks for your earlier code. – Kiki-ko Jul 24 '23 at 05:30
  • @Kiki-ko Check out what I just added to my answer — there are several ways you could do this but the core idea is to map your breakpoints to your listeners, so using the same concept as the initial version, I just changed the object being iterated over to include custom listeners per breakpoint – Zac Anger Jul 25 '23 at 00:05
  • perfect. That solves it. putting my function in each listener `const mobileListener = (e) => { mobi () }` `const tabletListener = (e) => { tab () }`, `const desktopListener = (e) => { desk () ) ` was triggered according to the viewports. Many thanks, Problem solved – Kiki-ko Jul 25 '23 at 07:26