Javascript that runs based on CSS Media Queries

Nicholas Zakas wrote this little ditty:
isMedia()

So people have thought it would be cool to have certain scripts only run based on whether the browser is loading a certain stylesheet based on media type.

What this doesn’t do is stop someone whose media is “handheld” from downloading some ginormous script… just means the script will check first to see if it should run.

Still, this is a nice added bit of flexibility without going to the serverside (where we were first checking the user agent string and then determining which scripts to add to the page).

Looks interesting, but I don’t really get how that works or what it’s for. Is there a page somewhere that explains it a bit more?

Not that I know of, he was tweeting about it : )

But, say you have a function that colours widgets. Everyone with JS enabled gets coloured widgets.

Now say you only wanted users with the regular “screen” media to get coloured widgets, while those with a media query of max-width: 320px don’t run that function and don’t get the funky coloured widgets (they get whatever you have when that function doesn’t run).

Or suppose Javascript is adding social garbage icons to somewhere on your page. But when the screen is like 320px wide, there’s no room for the stupid popups that appear with forms in them (searchThis, I’m looking at you and your garbage HTML and garbage popups). So your other function that would run instead (because it returns true that the stylesheet-for-320px-devices was loaded) creates instead some links that go to other pages with the forms and no popups appear if the user manages to mouse over them or tap them once by accident. (yeah this all depends on whether you build for mobile first and then layer on the larger screen device widths, or do it the other way around)

So this isMedia() function is only checking to see IF a stylesheet was loaded, which would only happen if a user agent understands the query to that media type (the UA must know what max-width: 320px means or they won’t load that stylesheet anyway). So you can decide if different functions run.

That’s pretty interesting.

I think for overall functionality (whether it needs the script at all or not), that’s probably better left to server-side (to prevent a large script from needlessly being sent).

However, for switching up a function (so using functionA for screen and functionB for handheld) would make this very handy.

This is one of those things which has a fairly limited use, but when you did hit one of those it’s nice to have in your toolbox.

Thanks.

You could use it to detect whether to download a massive script if you used a dynmic script tag generation function

Why should the server know about the screen res?

It’s also a tiny script.

What this doesn’t do is stop someone whose media is “handheld” from downloading some ginormous script

It could, You just can’t load all of your scripts the usual way with <script></script>. e.g.


function require(path) {
  try{
    document.write('<script type="text/javascript" src="'+path+'"><\\/script>');
  } catch(e) {
    var script = document.createElement('script');
    script.src = path;
    document.getElementsByTagName('head')[0].appendChild(script);
  }
}
if (isMedia("screen and (max-width:800px)"){
  require('/js/small-screen.js');
}
else {
  require('/js/big-screen.js');
}

Edit: As Stormrider said ^

The script looks really useful.
It reminds me a lot of @JimmyP’s ie detection script http://james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/
Injecting html into the doc to test support for a feature.

I love how these different patterns give people inspiration to think outside the square.
The same thing happened with the Module Pattern.

It inserts a div that’s positioned off screen as well as a style block.
Then tests if the style block with your media query is effecting the position of the div.

So it’s a way of testing if a browser is meeting the @media query.
It could be used for loading different scripts, enabling / disabling functionality on smaller screens.

It would stop large scripts from loading unnecessarily if you used it properly.

What you could do is have just that small script linked into the page. The action to take if the media query is satisfied is to add the script tag to the page that will load and run the rest of the required JavaScript.

That seems to work in with what is apparently the latest technique to use these days. That is, to presume a mobile browsing device, and then to progressively enhance from there.

It could, You just can’t load all of your scripts the usual way with <script></script>…

Ah neat, I’ve not used dynamic script-calling at all yet.

I also hadn’t thought of JS adding the detection div— I was thinking, just look at some element who gets style x with media-query Y, but generating an element makes more sense, since then the script doesn’t have to care what the HTML or design of the page is… could be added anywhere.

There is of course the fact that small screen != small bandwidth necessarily… but if the site is working for everyone anyway this isn’t a big issue for me, and most of the people who would be using my sites via a mobile would indeed be on crappy/public/busy internets. They’ve recently made the train line nearest me all free Wi-Fi now : ) I doubt it’s terribly fast though.

That is, to presume a mobile browsing device, and then to progressively enhance from there.

I’ve been doing this but it does leave a problem for mobile IE’s. They get the GinormousDesktop.css no matter what : )