I'm using JavaScript to handle breakpoints in a single page, non-scrollable application. I want to do various things when changing viewports, such as fire off animations with a JavaScript animation library.
I've assigned the viewports like so:
HTML:
<div class='box'></div>
CSS:
.box {
width: 300px;
height: 300px;
background-color: red;
}
JS:
var winWidth = '';
var newWinWidth = '';
var winHeight = '';
var newWinHeight = '';
function setWidthBreakpoints(windowWidth) { //matches bootstrap's breakpoints
if (windowWidth >= 1200) {
newWinWidth = 'lg';
} else if (windowWidth >= 992) {
newWinWidth = 'md';
} else if (windowWidth >= 768) {
newWinWidth = 'sm';
} else {
newWinWidth = 'xs';
}
}
function setHeightBreakpoints(windowHeight) {
if (windowHeight >= 1024) { //more or less arbitrary, may add or remove
newWinHeight = 'lg';
} else if (windowHeight >= 480) {
newWinHeight = 'md';
} else {
newWinHeight = 'sm';
}
}
window.onresize = function () {
'use strict';
setWidthBreakpoints($(this).width());
setHeightBreakpoints($(this).height());
if (newWinWidth !== winWidth || newWinHeight !== winHeight) {
onSizeChange();
winWidth = newWinWidth;
winHeight = newWinHeight;
}
};
function onSizeChange() {
switch(newWinWidth + '|' + newWinHeight) {
case 'xs|sm':
$('.box').css('background-color', 'yellow')
case 'xs|md':
case 'xs|lg':
$('.box').css('background-color', 'purple')
case 'sm|sm':
$('.box').css('background-color', 'orange')
case 'sm|md':
case 'sm|lg':
$('.box').css('background-color', 'purple')
case 'md|sm':
$('.box').css('background-color', 'green')
case 'md|md':
case 'md|lg':
$('.box').css('background-color', 'purple')
case 'lg|sm':
$('.box').css('background-color', 'blue')
case 'lg|md':
case 'lg|lg':
$('.box').css('background-color', 'purple')
}
}
In the above code, we want anything above a small height to be purple. But we have to repeat ourselves to set it four different times.
I will be supporting IE9 with this application so I chose to use JS animation library GSAP for performance and fallback reasons. This is why I am handling my media query breakpoints in Javascript.
How can I build such a scheme to minimize code repetition? Is there a more elegant way to handle combined height and width breakpoints? Am I doing it wrong? I don't foresee many more height viewports being added to this application, and the width ones are tied to Bootstrap so they won't be changing at all.
-
\$\begingroup\$ What exactly do you mean with "breakpoints"? What code repition do you mean? There is hardly anything there. Also your code isn't runable like this, which is a requirment for codereview. Finally: This is something that may be more appropriate for CSS than JS. \$\endgroup\$RoToRa– RoToRa2015年03月06日 11:20:24 +00:00Commented Mar 6, 2015 at 11:20
-
\$\begingroup\$ @RoToRa I have added information in question that answers these questions. Hope this helps. \$\endgroup\$Conor– Conor2015年03月08日 17:16:10 +00:00Commented Mar 8, 2015 at 17:16
-
\$\begingroup\$ I've never heard of this referred to as "breakpoints," which usually refers to lines of code that you want to automatically pause (break) in a debugger. Perhaps a better term is in order? (I usually hear "snap point" or the like.) \$\endgroup\$fluffy– fluffy2015年03月08日 17:44:06 +00:00Commented Mar 8, 2015 at 17:44
-
\$\begingroup\$ @fluffy it is a term used by Twitter's Bootstrap front end framework to refer to a set point at which viewport display changes (getbootstrap.com/css), see the section called "Media Queries" under the section called "Grid System" \$\endgroup\$Conor– Conor2015年03月08日 17:54:00 +00:00Commented Mar 8, 2015 at 17:54
-
\$\begingroup\$ @fluffy but fair point, there is some ambiguity in the question title. Unfortunately because of Bootstrap's widespread popularity the term "breakpoint" is probably now a bit too ubiquitous for us to change it to "snap point", but I've edited the title to make it a bit clearer what is meant when the term "breakpoint" is used. \$\endgroup\$Conor– Conor2015年03月08日 18:05:36 +00:00Commented Mar 8, 2015 at 18:05
1 Answer 1
Here is one way to get rid of if
chaines (if that is the repition you mean):
var WIDTHS = [
{name: 'xs', max: 768},
{name: 'sm', max: 992},
{name: 'md', max: 1200},
{name: 'lg'}
];
function getRangeName(value, ranges) {
for (var i = 0, len = ranges.length; i < len; i++) {
var range = ranges[i];
if (typeof range.max === "undefined" || value < range.max) {
return range.name;
}
}
}
function setWidthBreakpoints(windowWidth) {
return getRangeName(windowWidth, WIDTHS);
}
-
\$\begingroup\$ thank you for your answer. I will add code to make it runnable and refine the question based on your feedback \$\endgroup\$Conor– Conor2015年03月06日 15:02:53 +00:00Commented Mar 6, 2015 at 15:02
-
\$\begingroup\$ @Conor Keep in mind not to modify the code in the original question (although extending it to make it runnable should be ok). \$\endgroup\$RoToRa– RoToRa2015年03月07日 07:51:56 +00:00Commented Mar 7, 2015 at 7:51
-
\$\begingroup\$ I added the necessary fixes to make the code runnable and a CodePen. Will also add some more details to the question. Thanks again for your feedback. \$\endgroup\$Conor– Conor2015年03月08日 17:10:24 +00:00Commented Mar 8, 2015 at 17:10
-
\$\begingroup\$ @Conor A nice way to say thanks for feedback is to upvote \$\endgroup\$janos– janos2015年06月08日 18:20:35 +00:00Commented Jun 8, 2015 at 18:20
Explore related questions
See similar questions with these tags.