1
\$\begingroup\$

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:

CodePen

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.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 4, 2015 at 21:03
\$\endgroup\$
6
  • \$\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\$ Commented Mar 6, 2015 at 11:20
  • \$\begingroup\$ @RoToRa I have added information in question that answers these questions. Hope this helps. \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Mar 8, 2015 at 18:05

1 Answer 1

1
\$\begingroup\$

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);
}
answered Mar 6, 2015 at 12:59
\$\endgroup\$
4
  • \$\begingroup\$ thank you for your answer. I will add code to make it runnable and refine the question based on your feedback \$\endgroup\$ Commented 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\$ Commented 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\$ Commented Mar 8, 2015 at 17:10
  • \$\begingroup\$ @Conor A nice way to say thanks for feedback is to upvote \$\endgroup\$ Commented Jun 8, 2015 at 18:20

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.