javascript to check if element visible and set “setInterval” accordingly

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.

Answers:

Answer

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.

Answer

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
  }
});

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.