问题
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!
回答1:
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.
来源:https://stackoverflow.com/questions/52291224/trigger-events-when-css-breakpoints-are-reached