0

I need to call a function when a window is resized below the 400px breakpoint. The obvious solution to handle this would be to watch the window.resize() event like this:

Window.Resize Solution

script:

$(window).resize(function(){
    if($(window).width() < 400)
       console.log("trigger");
});

Window.resize Fiddle

However this triggers continuously as the resize happens, this can result in hundreds of calls on this function, and will trigger at unncessary times like resizing from 300px to 200px;

While trying to find a way to avoid this I came up with a solution using CSS media queries:

CSS Media Query Solution

script:

$(".foo").on('transitionend', function () {
   console.log("trigger")
});

css:

.foo
{
    width: 0;
    height: 0;
    color: white;
    transition: 0.1s;
}
@media screen and (max-width: 400px) {
    .foo {
        color: gray;
    }
}

CSS Media Query Fiddle

The idea here is that the CSS watches for the window to resize to 400px then applies an arbitrary transition to an invisible element. Once done, the transitionend event is fired and the listener calls on my function. This only happens once when the screen goes below 400px and once when it goes back above.

Now of course there are pitfalls to this solution:

  • IE8/IE9 don't support transitionend
  • You must create an unnecessary element for each resize event you want to watch
  • The code is inherently more confusing as it is a "hacky" technique.

But other than those downfalls I was wondering if this method would be more efficient/better use if you want to avoid the continuous calls. Or is the underlying implementation of media queries doing more work than the resize event would anyway.

DasBeasto
  • 2,082
  • 5
  • 25
  • 65
  • Just to add, I don't intend to actually implement this as I prefer readability to shaving a few calls/ms off my runtime (if it even does), this is more out of curiosity. – DasBeasto Aug 24 '15 at 14:12
  • http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing – isherwood Aug 24 '15 at 14:13
  • Or http://stackoverflow.com/a/5490021/1264804 – isherwood Aug 24 '15 at 14:14
  • Take a look at enquire.js, which lets you respond to CSS media queries using js. http://wicky.nillia.ms/enquire.js/ – bumpy Aug 24 '15 at 14:21
  • @isherwood thanks those look better I will use those, I didn't think this was the best route I just thought it was an interesting one. – DasBeasto Aug 24 '15 at 14:31
  • @bumpy for this case I wouldn't really want a plugin as it's only this one call, but I will look into how that is implemented. – DasBeasto Aug 24 '15 at 14:32
  • Also just found this article where roughly the same technique is used but for different reasons: https://www.fourfront.us/blog/jquery-window-width-and-media-queries – DasBeasto Aug 24 '15 at 14:32

1 Answers1

0

I think your main complication is splitting the code over so many places. Yes, CSS is nice and all, but now your code is reliant on two places! The easiest way to sort this is to simply store your value in JS:

var isSmall = false;
$(window).resize(function(){
    if(
        (window.innerWidth < 400 && !isSmall) ||
        (window.innerWidth > 400 && isSmall)
    ){
        console.log('we have passed the treshold!');
        isSmall = !isSmall;
    }
}).resize();

I guess using the CSS transitionend would work, but it seems so cumbersome to keep in sync.

somethinghere
  • 16,311
  • 2
  • 28
  • 42