1

I'm adjusting the width of a div using media queries. I need the page to react when that div changes width.

I've used .resize, however, that triggers twice and causes an issue when the user interacts with the div further. I can't use .live() since that requires the user to interact to achieve the desired effect. Finally, Ive looked into DOMSubtreeModified but that has been depreciated.

In simple terms this is what I want to do:

$('#element').watchForChange(function(){
     *...do stuff here when the change happens...*
});

Thanks for your assistance.

----- EDIT -------

Let me clarify a common issue I see with resize with this example:

<div id="box"></div>
<span id="button">Open</span>

In the above example assume the #box is 400x400 and in the "open" state (display:block). When the window resizes to 800px I want the box to close (display:none). The "open" button will use jquery to open the box again ($('#button').click(function(){...});)

The issue I keep sing is when I would click "open" the box opens then closes. The second click works fine.

Jquery is retaining the second call in the event handler. I can't unbind it since I'll need to check the size again.

I'm not using an open close function. Rather I'm using a next button on a slider. I need the items to reset back to the beginning on that resize. I can get them to reset, no problem. The issue is: the second click of "next" resets it.

dcp3450
  • 10,959
  • 23
  • 58
  • 110
  • 1
    Go fix your code in `.resize`. It's exactly what you want. From the jQuery documentation: "Code in a resize handler should never rely on the number of times the handler is called. Depending on implementation, resize events can be sent continuously as the resizing is in progress (the typical behavior in Internet Explorer and WebKit-based browsers such as Safari and Chrome), or only once at the end of the resize operation (the typical behavior in some other browsers such as Opera)." – Brad Nov 01 '12 at 03:37
  • Can you set up a jsfiddle? I think that would make it much easier to track down the issue. – Clay Garrett Nov 01 '12 at 04:31
  • very quick example using jsfiddle. I'm using kleezy's example from below. http://jsfiddle.net/SVy6m/ – dcp3450 Nov 01 '12 at 05:11

2 Answers2

4

Using a technique found here:

JQuery: How to call RESIZE event only once it's FINISHED resizing?

http://jsfiddle.net/Zevan/c9UE5/1/

var id;
$('#element').resize(function() {
    clearTimeout(id);
    id = setTimeout(doneResizing, 500);

});

function doneResizing(){
    // do something
    console.log("done resizing");
}​

The event will still fire multiple times but the doneResizing function will only be called 500 milliseconds after the last one fires. Of course, you can adjust that number to suit your needs.

Community
  • 1
  • 1
Clay Garrett
  • 1,023
  • 8
  • 11
  • I edited the question with more detail. I tried using your suggestion but got the same result as explained in the edit. It still calls the second resize call but only on the second user interaction. – dcp3450 Nov 01 '12 at 04:27
  • this is what I mean by it still reads the second resize event. You have to click twice to get it to reopen after you window is less that 800px: http://jsfiddle.net/SVy6m/ – dcp3450 Nov 01 '12 at 05:11
0

OK - based on your edited question, here's the issue. The toggle function is keeping track of which function it ran for last click and will always run the other function for the next click. So, when you click it once, it runs the first function, click again, it runs the second function, and then back to the first and so on.

But, your window resize event is collapsing the window, so if the last time you clicked your h1 was to expand it, then the next click, toggle will attempt to close it. So, your window resize event closed it and then the button is closing it again. That's why you don't see any results the first time you click the button after a window resize.

I modified your code to not use toggle -- and to use a state variable instead:

http://jsfiddle.net/SVy6m/1/

var target;
var isCollapsed = true;

$('h1').click(function() {
    if(isCollapsed) {
        $('.box-1').slideDown();
    } else {
        $('.box-1').slideUp();   
    }
    isCollapsed = !isCollapsed;
});   


var id;
$(window).resize(function() {
    clearTimeout(id);
    id = setTimeout(doneResizing, 10);

});

function doneResizing(){
    // do something
    $('.box-1').slideUp();
    isCollapsed = true;
}    ​

You'll still need to add some code to check if the window size is less than 800. Hope this helps!

Clay Garrett
  • 1,023
  • 8
  • 11
  • In my real life code I'm not using toggle. I did the quick jsfiddle to show what I'm seeing. I removed the toggle to illuminate that as the issue. Now it just checks for an "active" class. If it's active then close else open it. The same issue is still seen. – dcp3450 Nov 01 '12 at 05:52
  • In the fiddle you provided, the toggle was the issue. So can you provide another fiddle that acts as you're describing with your "active" class? Maybe I'm not getting the root of the issue. I'm not seeing any strange behavior with the resize event. It seems to be working as it should in this answer's fiddle. The box hides on window resized and can be opened with a single click. – Clay Garrett Nov 01 '12 at 06:01
  • I'm working on getting your suggestion in line with my real life code. There are more factors there, of course, such as multiple click boxes and dropdowns. – dcp3450 Nov 01 '12 at 06:10
  • I found a few extra collapsing triggers that were causing issues as well (for the record I'm correcting code from someone else). I still have some testing and fixing to do but it looks like this did the trick – dcp3450 Nov 01 '12 at 06:26