I'm trying to figure out how I can optionally run a block of javascript based on the current device/media query. I'm using Twitter Bootstrap and have essentially two versions of media queries:
#media (min-width: 980px) { ... } <!-- Desktops -->
#media (max-width: 979px) { ... } <!-- Smaller screens/tablets/phones -->
I have a map that I generate, but am not showing it in the mobile/small screen version forb andwidth reasons. Yet, the javascript still executes in the background even though you can't see it on the mobile screen. So, I'm trying to find a way in javascript where I can do something like:
// Imaginary function
var screenType = getScreenType();
if(screenType == 1) {
// Load map
}
I've read about people setting CSS properties to specific values in their media queries and then trying to find that element in the DOM based on the CSS property, but there has got to be a better way. Any ideas?
The current accepted answer is not good enough, you should check window.matchMedia
You can detect viewport dimension changes, but you must calculate factors such as orientation and aspect ratios and there is no guarantee our calculation will match our browser assumptions when it applies media query rules.
I mean, you can calculate X, but your browser assumption can be Y.
So i think is better to use same browser rules, and window.matchMedia does it
var jmediaquery = window.matchMedia( "(min-width: 480px)" )
if (jmediaquery.matches) {
// window width is at least 480px
}
else {
// window width is less than 480px
}
You can even receive query notification using a listener
var jmediaquery = window.matchMedia("(orientation: portrait)");
jmediaquery.addListener(handleOrientationChange);
handleOrientationChange(jmediaquery);
function handleOrientationChange(jmediaquery) {
if (jmediaquery.matches) {
// orientation changed
}
}
If you no longer need to receive notifications about changes simply call removeListener()
jmediaquery.removeListener(handleOrientationChange);
You might find the Enquire.js library helpful:
http://wickynilliams.github.com/enquire.js/
CSS-Tricks article: http://css-tricks.com/enquire-js-media-query-callbacks-in-javascript/
How about using javascript for that?
<script type="text/javascript">
if (screen.width < 980) {
document.write('<link href="UrLowRes.css" type="text/css" rel="stylesheet"/>');
} else {
document.write('<link href="UrlHighRes.css" type="text/css" rel="stylesheet"/>');
}
</script>
You can also using a plugin called minwidth:
minwidth(940, function () {
//do whatever you need
});
But it only works when the page loads not when resizing..
http://edenspiekermann.com/en/blog/responsive-javascript-helpers
Related
Trying to append a css file when my navbar increases in height beyond 54px (When the text falls to a second line) and remove it when the height goes below 54px. I've been trying bits of code, but nothing seems to works:
My failed attempt
var $navscript = '<link rel="stylesheet" href="/css/edt/nav-bar.css" type="text/css"/>';
if ($("#navbar").height() > 54) {
alert("Activate Code Here");
$("body").append('navscript');
}
Any idea on where i am going wrong?
$("body").append('navscript');
With this, you are appending the String navscript to your body, maybe you should try appending the variable $navscript to the head.
var $navscript = '<link rel="stylesheet" href="/css/edt/nav-bar.css"
type="text/css"/>';
if ($("#navbar").height() > 54) {
alert("Activate Code Here");
$("head").append($navscript);
}
Though, keep in mind, that adding content dynamically is generally considered a bad practice. Maybe move all of your CSS in one file and append classes to the objects that should be changed by this.
I really don't recommend doing this as it is pretty much bloating the DOM with a lot of link tags (especially if you'll do this when device dimensions changes) and it is overall bad practice.
What I advice you to do is instead using CSS media queries to detect device width and height and then apply CSS properties according to that.
I guess this should work:
if ($("#navbar").height() > 54) {
alert("Activate Code Here");
$("body").append($navscript);
}
But seems like you want change navbar style depend on height. In this case you should add event listener (for event which cause height increasing) and place your code there. My opinion that better include your css file in DOM and operate with some css-classes. For example:
$(window).resize(function(){
var $navbar = $("#navbar");
if ($navbar.height() > 54) {
$navbar.toggleClass('class');
}
});
To attach a secondary CSS file only at certain screen sizes, you can put media query rules on the <link> tag:
<link rel="stylesheet" media="screen and (max-width: 500px)" href="smallscreens.css" />
It's rarely necessary to do this however; most often it's simpler to include whatever #media rules you need inside a single CSS file:
/* default rules here */
.foo {font-size: 1000px}
#media screen and (max-width: 500px) {
/* rules for small screens go here */
.foo {font-size: 10px}
}
You can set any number of size breakpoints, using max-width, min-width, or any combination of many other conditions, within the same CSS file.
https://www.w3.org/TR/css3-mediaqueries/
(This doesn't exactly meet your requirement of attaching/detaching the css based on the height of a specific div, but I'm guessing that the change in your navbar height is actually due to a change in screen size, and you've dug yourself into an XY problem trying to solve this the hard way.)
Ended up fixing this in the end, the code I used was a mix of reloading the segment of code upon window resizing and some else statements depending on a DIV's height or width:
var $navscript = '<link rel="stylesheet" href="/css/edt/nav-bar.css" type="text/css" data-dynamic />';
var changeSize = 0;
$(window).resize(function () {
if ($(".links").height() > 16) {
if ($('link[data-dynamic]').length === 0) {
changeSize = window.outerWidth;
$("head").append($navscript);
}
}
else {
}
if (changeSize < window.outerWidth) {
$('link[data-dynamic]').remove()
}
});
I have been having an issue with resizing web pages to fit on mobile devices using JavaScript. Is there a certain width that most programmers use to start changing the resize for mobile devices? Can anyone recommend any guidelines that I should or need to follow when working with mobile devices? I am now being instructed to make sure all web pages are "mobile friendly".
function adjustStyle() {
var width = 0;
// get the width.. more cross-browser issues
if (window.innerHeight) {
width = window.innerWidth;
} else if (document.documentElement && document.documentElement.clientHeight) {
width = document.documentElement.clientWidth;
} else if (document.body) {
width = document.body.clientWidth;
}
// now we should have it
if (width < 650) {
document.getElementById("myCSS").setAttribute("href", "css/narrow.css");
} else {
document.getElementById("myCSS").setAttribute("href", "css/main.css");
}
}
// now call it when the window is resized.
window.onresize = function () {
adjustStyle();
};
For starters, you shouldn't rely on Javascript to make your pages responsive to different resolutions or screens sizes, CSS can handle that for you using media-queries.
Javascript should be used in responsive design only under these circumstances:
You have an extreme design feature that is impossible to pull off correctly in CSS
You want to enhance your web page by adding in some interactions, animations or custom behaviors.
You have an experimental website where users are expecting something out of the ordinary
You are willing to warn your users if javascript is required to display/run your page properly.
It is best practice to only use javascript to enhance your page after you have written your responsive layouts in CSS, that way, your site is still functional if javascript is turned off in the browser.
"Progressive enhancement" is a popular technique for web developers who want to get the page looking nicely while assuming Javascript is turned off, so that users without javascript will still get a nice experience, then, progressive-enhancement in javascript means that the user can be ensured an even better experience if they have javascript turned on, because they might see some nice animations, and cool parallax scrolling, etc.
With that said, your question was directly asking about using javascript for responsive design, so from there, the advice is simple:
Use jQuery's bind() or resize()functions to listen for browser resize events:
$(window).resize(function() {
// handle layout here
// change widths, heights, positions, etc
});
$(window).bind("resize", function(){
// handle layout here
// change widths, heights, positions, etc
});
And from there, you can effect the width's height's and positions of your elements, or assign CSS properties to them, depending on your design.
As for good "breakpoints" (screen sizes to watch for in your responsive layouts), you can refer to this guide: Media Queries for Common Device Breakpoints.
I tend to start somewhere around here, and then tweak as I go:
Mobile: width: 320px - 750px
Tablets: width: > 750px - 1024px
Laptops/Desktops: width: > 1024px
And then I test on multiple devices, and make changes accordingly, your final design will dictate the final numbers you choose as your breakpoints.
Hope this helps.
I typically use a width of 600 to adjust for mobile devices.
Make sure to add this meta tag inside the <head> tag:
<meta name="viewport" content="width=device-width">
This should make the page render at a reasonable size.
Add this <style> tag inside the <head> tag:
<style>
img {
max-width: 100%;
}
</style>
I think this will make sure all images don't render any wider than the app's webview's viewport.
(If that doesn't work, try width: 100%; instead. That'll definitely make all images be as wide as the viewport, and therefore no wider.)
You can also try the #media tags in your css, they allow you to completely reprogram it depending on the resolution:
#media screen and (max-width: 600px) {
.button {
width:300px;
}
}
then for different resolutions above mobile
#media screen (min-width: 600px) and (max-width: 1200px) {
.button {
width:500px;
}
}
But you can always use jquery's
$(window).resize(...) which binds a callback for the resize event or triggers this event.
Bind a callback function, if the users resizes the browser window:
$(window).resize(function() {
alert('resize handler called');
});
If you want to call all listeners manually (without any parameters):
$(window).resize();
I have this statement in my webpage that formats a page especially so they can view it better with a small netbook screen:
<link rel="stylesheet" media="only screen and (max-height: 750px)" href="netbook.css" />
My question is, can I do the same with javascript?
I have an array of jquery functions that also change depending on screen size. I'm looking for something like this, I suppose:
<link rel="javascript" media="only screen and (max-height: 750px)" href="scripts_netbook.css" />
Any ideas out there?
Many thanks as always,
Dan
What I would do is something like:
$(function() {
var script_path = $(window).height() > 750 ? '/path/to/file.js' : '/path/to/otherfile.js';
$.getScript(script_path, function() { $(window).trigger('script_loaded'); });
$(window).on('script_loaded', function() {
//run other code requiring those scripts here
});
});
Edit: From your comments, it seems like you want to do:
$(function() {
if ($(window).height() < 750;) {
$('#footer_index').delay(800).transition({y:-155 }, 1000, 'snap');
}
});
This won't work like a media-query as far as resizing, but just on page load. If you want it to work for resizing, you could do something like
$(window).on('resize', function() { //do stuff });
According to Link Types Reference, JavaScript is not a Link Type, so your answer is no.
You can simply use the following for your needs:
screen.onresize = function() {
if (screen.height <= 750) {
//Your scripts
}
};
Note: According to Media Queries 'Height' Spec,
The ‘height’ media feature describes the height of the targeted
display area of the output device. For continuous media, this is the
height of the viewport including the size of a rendered scroll bar (if
any). For paged media, this is the height of the page box.
So to have proper pairing of CSS Media Queries and JavaScript, always use screen.width and screen.height
If you want to follow the style of CSS media queries, you have to use the .resize() function, this is the code:
var resizeBool = ($(this).height() < 750);
$(window).resize(function() {
var resizeBoolTmp = ($(this).height() < 750);
if (resizeBool === resizeBoolTmp) return;
resizeBool = resizeBoolTmp;
//your code that must be updated when the size changes
//from previous comments/answer, maybe this?
//$('#footer_index').delay(800).transition({y: -155}, 1000, 'snap');
});
This code updates the action only when the height limit passed by one or the other side.
Here is a snippet that shows how it works(check console to see what happens when width limit is reached).
Hi I wanted to know using jQuery or javascript can I remove a certain div tag so that its not displayed at all when the screen gets to a certain size lets say 500px.
You should use the matchMedia Javascript API, which has a very good support across browsers nowadays.
For instance:
var width = window.matchMedia('screen and (width: 500px)');
matchMedia will return a MediaQueryList object, which among other things contains a matches boolean that indicates if the passed in media query currently matches or not.
The great thing about those MediaQueryList objects is, that they provide methods to add and remove listeners, when this state changes.
For instance:
width.addListener(function( mql ) {
if( mql.matches ) {
// yes, the device screen width is now 500 pixels
} else {
// no, the width is below 500 pixels
}
});
You can write something like this in jQuery
$(document).ready(function(){
$(window).resize(function(){
if($(window).width()==500)
$('div').hide();
else
$('div').show();
});
});
You can do this using CSS media queries:
#media screen and (min-width: 500px) {
div.whatever { display: none; }
}
In Javascript is there a direct way (not involving parsing the css code) to determine which media query is active?
For instance I have two queries:
#media screen and (max-width:800px)
#media screen and (min-width:801px)
without parsing and looking at the clientWidth, how can I tell which one of these has evaluated to true.
Though this is an old question it ranks highly when googling for this problem.
Window.matchMedia is official and is supported by all major browsers (IE10+) and will allow you to query if a certain media query currently matches.
From the original question:
if (window.matchMedia('screen and (max-width:800px)').matches) {
// it matches
} else {
// does not match
}
You can also listen for when the query match result changes by attaching an event listener to the MediaQueryList that window.matchMedia returns:
var mql = window.matchMedia('screen and (max-width:800px)');
mql.addEventListener(
function(mq) {
if (mq.matches) {
// it matches
} else {
// does not match
}
}
);
Paul Irish's MatchMedia may do the trick:
https://github.com/paulirish/matchMedia.js
Would that suit what you are trying to do?
To see how different media queries react on resize or orientation change, try the demo on this page:
http://www.jensbits.com/2011/04/20/media-query-playground-rotate-resize-rinse-repeat/
You can adjust the media query attributes to get a feel for how they affect a page.
Hi and i hope this helps, am actually adding a class to a selector and i am working with this tool: https://hacks.mozilla.org/2012/06/using-window-matchmedia-to-do-media-queries-in-javascript/
in fact, they have a clear example of what is turn on within the resized window here
http://robnyman.github.io/matchmedia/
in my case am just doing specific task when am on a specific size that you can get using the function.
I'm not sure how would you know which media-query is active, but...
...can't you just check the screen width with javascript?
if ( window.innerWidth >= 801 ) {
// #media screen and (min-width:801px)
} else {
// #media screen and (max-width:800px
}
or, what am i missing here?