9

I'm curious is there an event listener or perhaps a way to construct a method that will trigger when a CSS change happens?

My stylesheet uses media queries and I want to know if there's a way to attach a listener to see when those media queries kick in and out. For example I have a media query that hides a button at certain screen widths

@media screen and (max-width: 480px) {
  #search-button {
    display: none;
  }
}

What event listener would I use to detect when that display changes? I'm currently doing this:

$(window).resize(function() {
  if($('#search-button').css("display") == "none") {
    //do something
  } else {
    //do something else
  }
});

Which works fine, but it calls the listener every time the user changes the screen and I'd rather just have it fire only when the css of the button changes. I hope that makes sense.

for example this is what I'd like

$('#search-button').cssEventListenerOfSomeKind(function() {
  alert('the display changed');
});
Brodie
  • 8,399
  • 8
  • 35
  • 55

3 Answers3

4

Binding to the window.resize is your best option (I believe). There isn't any event fired when you change an element's CSS. You can however optimize a bit by caching the selector used:

var $searcButton = $('#search-button');
$(window).resize(function() {
    if($searcButton.css("display") == "none") {
        //do something
    } else {
        //do something else
    }
});

Or you can use $(window).width() to check the width of the viewport:

var $window = $(window);
$window.resize(function() {
    if($window.width() <= 480) {
        //do something
    } else {
        //do something else
    }
});

UPDATE

You can always throttle your own event handler:

var $window   = $(window),
    resize_ok = true,
    timer;

timer = setInterval(function () {
    resize_ok = true;
}, 250);

$window.resize(function() {
    if (resize_ok === true) {
        resize_ok = false;
        if($window.width() <= 480) {
            //do something
        } else {
            //do something else
        }
    }
});

This will prevent the code in your resize event handler from running more than once every quarter second.

Jasper
  • 75,717
  • 14
  • 151
  • 146
  • I think so too... I guess I don't like the idea of the resize function getting fired so many times. However, if it's the best/only way to accomplish this than cest la vi right? I'll accept this as the answer if no one has an alternative soon. – Brodie Dec 29 '11 at 17:32
  • @Brodie Check-out my **update**, if you throttle the `resize` event handler you can reduce the CPU overhead when the user is resizing their browser. – Jasper Dec 29 '11 at 17:34
  • @Ajinkya You deleted your post but I thought this was a useful link (it may not be well supported in browsers but it's still good information): http://stackoverflow.com/questions/1397251/event-detect-when-css-property-changed-using-jquery – Jasper Dec 29 '11 at 17:41
0

I know this is old but I managed to solve it with this logic

    // set width and height of element that is controlled by the media query
    var page_width = $page.width();
    var page_height = $page.height();


    $window = $(window).resize(function(){
        if( $page.width() != page_width ) {
            // update page_width and height so it only executes your 
            // function when a change occurs
            page_width = $page.width();
            page_height = $page.height();
            // do something
            // ...
        }
    });
lemonSkip
  • 54
  • 5
0

If it is only a one time event you could try to unbind the event.

http://api.jquery.com/unbind/

khollenbeck
  • 16,028
  • 18
  • 66
  • 101
  • How does this apply to the question? – Jasper Dec 29 '11 at 17:35
  • From this "Which works fine, but it calls the listener every time the user changes the screen and I'd rather just have it fire only when the css of the button changes". It sounded like your problem was that the event was reoccurring. Maybe I miss understood, but if you don't want the event to keep firing it you could try unbinding the event and rebinding it. – khollenbeck Dec 29 '11 at 18:17