I'm trying this but it is not working:
<html>
<head>
<script src="js/menu-collapser.js" type="text/javascript" media="media screen and (max-width: 599px)"></script>
</head>
...
</html>
//menu-collapser.js :
jQuery(document).ready(function($){
$('.main-navigation li ul').hide();
$('.main-navigation li').has('ul').click(function() {
$(this).children().toggle();
});
});
Do you have an idea on how to do this in the right way? The script work if used directly in the header with the tags.
You can't do that directly using Javascript <script>
tags. Media queries are used in linked CSS files or inline CSS styles. A basic example:
<link rel="stylesheet" media="screen and (min-width: 900px)" href="desktop.css"/>
<link rel="stylesheet" media="screen and (min-width: 571px)" href="tablet.css"/>
<link rel="stylesheet" media="screen and (max-width: 570px)" href="mobile.css"/>
Or directly in your stylesheets:
@media screen and (max-width: 599px) {
#mobile {
display: block;
}
}
However, you can use an external asset loader/media query library to do this (require.js, modernizr.js, enquire.js and others), In this case, I'm setting an example using enquire.js, as I think it's very effective and doesn't require jQuery by default:
Full example
1) Include enquire.js (available here):
<script type="text/javascript" src="/js/enquire.js"></script>
2) Create a load function - to load JS files:
<script type="text/javascript">
// This loads JS files in the head element
function loadJS(url)
{
// adding the script tag to the head
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// fire the loading
head.appendChild(script);
}
</script>
3) Fire enquire.js and listen for media query changes (both on-load and on-resize):
<script type="text/javascript">
enquire.register("screen and (max-width: 599px)", {
match : function() {
// Load a mobile JS file
loadJS('mobile.js');
}
}).listen();
enquire.register("screen and (min-width: 600px) and (max-width: 899px)", {
match : function() {
// Load a tablet JS file
loadJS('tablet.js');
//console.log('tablet loaded');
}
}).listen();
enquire.register("screen and (min-width: 900px)", {
match : function() {
// Load a desktop JS file
loadJS('desktop.js');
//console.log('desktop loaded');
}
}).listen();
</script>
Putting it all together
Using a simple HTML page with enquire.js loaded from an external file:
<html>
<head>
<script type="text/javascript" src="/enquire.js"></script>
<script type="text/javascript">
// This loads JS files in the head element
function loadJS(url)
{
// adding the script tag to the head
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// fire the loading
head.appendChild(script);
}
</script>
<style>
body {
font-family: arial;
}
h1 {
font-size: 50pt;
}
#mobile {
display: none;
}
#tablet {
display: none;
}
#desktop {
display: none;
}
@media screen and (max-width: 599px) {
#mobile {
display: block;
}
}
@media screen and (min-width: 600px) and (max-width: 899px) {
#tablet {
display: block;
}
}
@media screen and (min-width: 900px) {
#desktop {
display: block;
}
}
</style>
</head>
<body>
<div id="desktop">
<h1>Desktop</h1>
</div>
<div id="tablet">
<h1>Tablet</h1>
</div>
<div id="mobile">
<h1>Mobile</h1>
</div>
<script type="text/javascript">
enquire.register("screen and (max-width: 599px)", {
match : function() {
// Load a JS file
loadJS('mobile.js');
}
}).listen();
enquire.register("screen and (min-width: 600px) and (max-width: 899px)", {
match : function() {
loadJS('tablet.js');
//console.log('tablet loaded');
}
}).listen();
enquire.register("screen and (min-width: 900px)", {
match : function() {
loadJS('desktop.js');
//console.log('desktop loaded');
}
}).listen();
</script>
</body>
</html>
In addition to loading JS files, you could create a CSS loader too, which would work in the same way (conditionally), but that defeats the object of using @media
in CSS. It's worth reading the usage explanations for enquire.js, as it can do a lot more than I've illustrated here.
Caveat: Nothing above uses jQuery, but you could take advantage of some of the functions it offers; loading scripts for example - or executing other functions that you need to.
Why not just load in a script conditionally?
(function() {
if( window.innerWidth > 600 ) {
var theScript = document.createElement('script');
theScript.type = 'text/javascript';
theScript.src = 'js/menu-collapser.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(theScript, s);
}
})();
Or better yet, only execute the code if the window.innerWidth > 600 ? Anyway, there are a lot of solutions you can use.
media
is not a valid attribute for <script>
, check it here.
So you should detect media types by manually than load the script dynamically.
There is a plug-in for css media detection in javascript, you can use it.
<script type="text/javascript" src="js/mediatypechecker.js"></script>
$(function() {
if(IsMediaType('screen') > 0 && parseInt(screen.width) < 599) {
$.getSscript("js/menu-collapser.js");
}
});