Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to call different jquery actions in responsive design

I'm at the point to convert my project into an responsive design.

What is the most handy and universal solution do you suggest to implement different jQuery-blocks for each breakpoint?

I want to keep all scripts in one file cause of number of http-requests.

That's what I've found:

  • breakpoint.js -> define all breakpoints doubled in CSS & JS
  • http://responsejs.com/ -> define breakpoints in body data-attr
  • OnMediaQuery -> define human-readable names for the breakpoints (IMHO better, cause you're not bound to pixels)

My problem is, they all define callbacks, but I don't know how to bind or cancel any jQuery event-listeners in these cases.

e.g. I have:

$('#selector').click( function() {
    alert('selector clicked');
});

but that should only happen if in max-width of 320px. In screen-sizes above that the click should return false or perform any other action

at the moment, I don't have a clue how to accomplish this.

like image 311
felixaburg Avatar asked Jul 08 '12 22:07

felixaburg


People also ask

What is $this in jQuery?

The this Keyword is a reference to DOM elements of invocation. We can call all DOM methods on it. $() is a jQuery constructor and in $(this), we are just passing this as a parameter so that we can use the jQuery function and methods.

What does .on do in Javascript?

The on() method attaches one or more event handlers for the selected elements and child elements. As of jQuery version 1.7, the on() method is the new replacement for the bind(), live() and delegate() methods.

Which is not jQuery method?

jQuery not() MethodThe not() method returns elements that do not match a certain criteria. This method lets you specify a criteria. Elements that do not match the criteria are returned from the selection, and those that match will be removed.


4 Answers

You can just create your own breakpoints in JS. Something like this. Adjust to your needs.

var isBreakPoint = function (bp) {
    var bps = [320, 480, 768, 1024],
        w = $(window).width(),
        min, max
    for (var i = 0, l = bps.length; i < l; i++) {
      if (bps[i] === bp) {
        min = bps[i-1] || 0
        max = bps[i]
        break
      }
    }
    return w > min && w <= max
}

// Usage
if (isBreakPoint(480)) { ... } // Breakpoint between 320 and 480
like image 133
elclanrs Avatar answered Nov 14 '22 05:11

elclanrs


$('#selector').click(function() {
    if (parseInt($(window).width()) < 320) {
        ...
    }
});
like image 24
casraf Avatar answered Nov 14 '22 05:11

casraf


If you are targeting modern browsers (IE10 upwards, and not IE mobile), then you should use the new window.matchMedia() method, as discrepancies between all the various browsers as to how they measure scrollbar width means that if you use for example window.width(), there will be a small range of pixels where the CSS behaves differently to the JS (I found this out the hard way).

This article goes in to further details: https://www.fourfront.us/blog/jquery-window-width-and-media-queries

Use something like the following so that your JS and CSS work on exactly the same breakpoints:

if (window.matchMedia("(min-width: 400px)").matches) {
  /* the viewport is at least 400 pixels wide, write code specific for that */
} else {
  /* the viewport is less than 400 pixels wide, write code specific for that */
}

The Mozilla Developer Network has documented this here: https://developer.mozilla.org/en/docs/Web/API/Window/matchMedia

like image 41
Matty J Avatar answered Nov 14 '22 04:11

Matty J


I messed around with some libraries and stuff and ended up using this kind of responsive listener. It uses CSS media queries for breakpoints and UnderscoreJS for a throttler. The advantage I see is that the breakpoints are all defined in CSS instead of fragmented around various scripts.

Example CSS @media breakpoints using :after on the body:

body:after {
    content: 'widescreen';
    display: none;
}
@media screen and (max-width: 1024px){
    body:after {
        content: "extra-large";
    }
}
@media screen and (max-width: 768px){
    body:after {
        content: "large";
    }
}
@media screen and (max-width: 640px){
    body:after {
        content: "medium";
    }
}
@media screen and (max-width: 480px){
    body:after {
        content: "small";
    }
}
@media screen and (max-width: 320px){
    body:after {
        content: "tiny";
    }
}

Example listener script waiting to fire based on content of body:after. As you can see it's defined as 2 ranges in this example for show/hide/move/create widgets based on device generality:

<script type ="text/javascript">
$(window).resize(_.debounce(function(e){
    var size = window.getComputedStyle(document.body,':after').content.replace(/"|'/g, ''),
        mobile = ["tiny", "small", "medium", "large"].indexOf(size),
        desktop = ["extra-large", "widescreen"].indexOf(size);

    $('.placehold').html('computed breakpoint: ' + size + '<br />mobile index = ' + mobile + '<br />desktop index = ' + desktop);

    if (mobile != -1) {
        $('.placehold2').html('mobile range');
    } else if (desktop != -1) {
        $('.placehold2').html('desktop range');
    }
}, 100)).trigger('resize');
</script>

http://jsfiddle.net/Dhaupin/nw7qbdzx/ - Just resize the output pane in jsfiddle to test it out.

EDIT: Apparently browsers render the :after contents via window.getComputedStyle(document.body,':after').content differently and insert either single or double quotes. Added a replace to scrub them out.

like image 44
dhaupin Avatar answered Nov 14 '22 06:11

dhaupin