views:

62

answers:

2

Hi,

LE2. Any other ideas on how to fix this?

I have this code and can't figure why is not working properly:

$(function autorun() {

if ($("#contactForm").is(":visible")){
setInterval( "refreshAjax();", 150000000000 );
 }
 else {
setInterval( "refreshAjax();", 15000 );
 }
setTimeout("autorun();", 2000)
});

...

<body onLoad="autorun()">

Right now it keep refreshing the page every 2 secs, even if the "contactForm" is visible.

My logic is: if the "contactForm" is visible, delay the refresh or stop it, keep checking that, but in the mean time refresh the page accordingly to the other statement.

LE.

$(function() {
refreshAjax = function(){$("#flex1").flexReload();
}
 });

LE2. Final solution provided here by @Nick Craver

$(function () {
  var ajaxTimeout;
  function autorun() {
    if ($("#contactForm").is(":visible")){
      if(ajaxTimeout) {
        clearInterval(ajaxTimeout);
        ajaxTimeout = false;
      }
    }
    else if(!ajaxTimeout) {
      ajaxTimeout = setInterval(refreshAjax, 15000);
    }
  }
  setInterval(autorun, 2000);
});

Thanks, Cristian.

+1  A: 

Currently you are creating a lot of interval timers which is not good. I don't know if this fixes your problem, because apart from that, your code looks ok.

Give it a try:

var ajaxTimeout;

function autorun() {
    if ($("#contactForm").is(":visible")){
        if(ajaxTimeout) {
            clearInterval(ajaxTimeout);
            ajaxTimeout = false;
        }
    }
    else if(!ajaxTimeout) {
        ajaxTimeout = setInterval("refreshAjax();", 15000);
    }
}


$(function() {
    setInterval("autorun();", 2000)
});

Remember that the time is in milliseconds.

Update: @tec has another interesting solution. So it depends on what you actually want to achieve with your code.

Felix Kling
I added more info as comment on @tec answers. Thanks.
Chris19
Interesting solution using setInterval(). But I guess you should set ajaxTimeout to 0 or false when you do the clearInterval(). Otherwise refreshAjax will not be called again when the contactForm is not visible anymore.
tec
Okay, so this works but only the first time the "contactForm" is visible. If I 'open' the "contactForm" one more time without refreshing the page, it doesn't check if is visible or hidden anymore, it keeps refreshing after 15 secs. Any Thoughts? Thanks,C.
Chris19
@tec: You are right, I missed that.
Felix Kling
@Chris19: I'm not sure if I can follow... does it work with @tec's addition?
Felix Kling
@Felix King it works with @tec addition perfectly, but only in FF 3.6.12 and Chrome, but in IE 8.0 doesn't refresh the grid. I tried the debugger but it doesn't give out any errors or anything. THe page loads but doesn't refreshes. Weird. Thx.
Chris19
More interesting, if I open the IE debugger before I load the page, load my page and then clear the cache the IE crashes. If I reverse to the old code it works "fine".
Chris19
On my Iphone everything works great as well ... WTH?
Chris19
@Felix - naming that function used in the `ready` handler will give you some issues, especially since it's the same name as the function you're trying to queue. See this question for details: http://stackoverflow.com/questions/4062466/javascript-script-not-working-and-crashing-ie
Nick Craver
@Nick: Thanks for pointing this out. Actually, this is a copy and paste mistake, I did not want to give the function a name. Fixed.
Felix Kling
+1  A: 

It look like you did not yet fully understand how setTimeout/setInterval work. The first thing you need to know is, that these methods always work asynchronously. Javascript code never stops and waits or something. Instead first your method (and the calling stack) finishes; after that the delayed method calls are executed. I recommend reading a good explanation of "threading" in javascript like: http://ejohn.org/blog/how-javascript-timers-work/

So in your code autorun() is called every two seconds. Every two seconds the if is evaluated. If the contact form is visible, nothing happens, as I guess you don't wait 15 Mio seconds. If it's not visible you start to call refreshAjax() in an Interval of 15 seconds. But remember: this is done every two seconds. so after 15 seconds the first time refreshAjax() is called. After 17 seconds again and after 19,21, and so on. After 30 seconds it starts being called twice each two seconds.

A simple solution would be this:

$(function autorun() {
  if ($("#contactForm").is(":visible")){
    // It's visible, so don't do anything. 
    // But check again in two seconds if it is still visible.
    setTimeout( "autorun();", 2000 );
  }
  else {
    // it's not visible, yay! 
    // Let's refresh and check again in 15 seconds
    setTimeout( "autorun();", 15000 );
    refreshAjax(); // note that refreshAjax is called instantly, _not_ after 15 seconds
  }
});
tec
I use flexigrid to display data from a database and I want to use a slide down "contactForm" where to save other settings to use with other code. My problem is that when the "contactForm" is visible and the flexigrid refreshes it overlaps the "contactForm" and it looks really bad. If I try to add an overlay to overlap the flexigrid overlay I end up overlapping the "contactFom" so I am trying to use the script above to stop refreshing the flexigrid while the "contactForm" is active. Initially the "contactForm" is hidden so I'll need to adapt the code a bit. Thanks.
Chris19