Trigger events when CSS breakpoints are reached

有些话、适合烂在心里 提交于 2019-12-22 07:52:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!