I have a set of breakpoints and I'd like to fire an event every time one is passed. Currently, I'm using $(document).resize(function(){})
but this doesn't match up with my CSS breakpoints whether I use window
, document
or any other selector.
Is there any way of just detecting when a media query is passed? Here's my current code:
$( window ).resize(
function() {
if( $(window).width() < 500 ) {
$(window).trigger("breakpoint-sm");
}
if( $(window).width() < 900 ) {
$(window).trigger("breakpoint-md");
}
}
);
$(window).on(
"breakpoint-md", function() {
if($(window).width() < 900) {
// this happens when below medium screen size
alert( "breakpoint reached" );
}
}
);
@media screen and (max-width: 500px) {
/* do mobile things */
}
@media screen and (max-width: 900px) {
/* do mobile things */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If there's an easier way to know if the breakpoint has been passed upwards or downwards, I'd be willing to hear it.
Thankyou!
I've got a solution to your exact problem which I use myself.
Basically, you can't directly detect breakpoints using JavaScript but you can detect changes to elements caused by breakpoints. The .css-js_ref-*
divs will become visible when their respective breakpoint is reached.
<div class="css-js_ref">
<div class="css-js_ref-sm" data-bp="sm"></div>
<div class="css-js_ref-md" data-bp="md"></div>
</div>
And you can then use JS to detect what the last visible element is:
function currentBreakpoint() { return $('.css-js_ref > *:visible').first().attr('data-bp') };
This returns the breakpoint name you put into the .css-js_ref
markup, i.e. sm
.
Working Example:
function currentBreakpoint() { return $('.css-js_ref > *:visible').first().attr('data-bp') };
var breakpointLength = $('.css-js_ref > *:visible').length;
$(window).on('resize', function () {
var newBreakpointLength = $('.css-js_ref > *:visible').length;
if (newBreakpointLength < breakpointLength) {
breakpointLength = newBreakpointLength;
$(window).trigger('breakpoint:up', [currentBreakpoint()]);
}
if (newBreakpointLength > breakpointLength) {
breakpointLength = newBreakpointLength;
$(window).trigger('breakpoint:down', [currentBreakpoint()]);
}
});
$(window).on('breakpoint:down', function(event, bp){
console.log(bp);
});
.css-js_ref * {
display: none;
}
@media screen and (max-width: 500px) {
.css-js_ref-sm {
display: block;
max-width: 500px;
}
}
@media screen and (max-width: 900px) {
.css-js_ref-md {
display: block;
max-width: 900px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="css-js_ref">
<div class="css-js_ref-sm" data-bp="sm"></div>
<div class="css-js_ref-md" data-bp="md"></div>
</div>
Usage:
// bp is the breakpoint that was reached
$(window).on('breakpoint:down', function(event, bp){
if(bp === 'md') {
// do stuff on below medium sized devices
}
});
$(window).on('breakpoint:up', function(event, bp){
if(bp === 'md') {
// do stuff on above medium sized devices
}
});
This solution is a bit of work but extremely versatile. It also means you only have to define your breakpoints in one place which is great for DRY compliance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With