Forum Moderators: open

Message Too Old, No Replies

clearInterval not working in Internet Explorer

         

JAB Creations

6:06 pm on Aug 22, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I've been working on an on-demand JavaScript loader which great in all browsers except for Internet Explorer, even IE8.

The problem is that it's clear that IE is not executing clearInterval correctly. I assigned the interval to what I'm pretty sure is a global scope object property so IE should be able to see the the object and remove the interval right? I've even tried removing the object property and that didn't work.

Right now while this works great in all the other browsers IE will at the end of the attempt to poll the function (s = source file, f = function to poll) IE will endlessly loop the alert (hence clearInterval not working).

Thoughts please?

- John

var option = new function() {this.name = '';}

function power_keys() {ondemand('power_keys','power_keys_init');}

function ondemand(s,f,p1,p2)
{//alert(s+'\n'+f+'\n'+p1+'\n'+p2);
if (typeof f=='string' && eval('typeof ' + f)!='function')
{
var js=document.createElement('script');
js.src='scripts/'+s+'.js';
js.type='application/javascript';
var newtext = document.createTextNode('\n');

if (document.body.style.scrollbar3dLightColor==undefined && document.body.style.textOverflow==undefined)
{
document.getElementsByTagName('head')[0].insertBefore(js,document.getElementsByTagName('script')[1]);
document.getElementsByTagName('head')[0].insertBefore(newtext,document.getElementsByTagName('script')[2]);
}
else {document.getElementsByTagName('head')[0].appendChild(js);}

option.f = f;
option.poll = 0;
option.interval = setInterval(ondemand_poll,200);
}
else {eval(f+'(\''+p1+'\',\''+p2+'\')');}
}


function ondemand_poll()
{//alert(option.f+'\n'+option.poll+'\n'+option.interval);
var f = option.f;

if (typeof f=='string' && eval('typeof ' + f)=='function')
{
clearInterval(option.interval);
eval(f+'()');var b = 1;
}
else
{
if (option.poll>=50)
{
window.clearInterval(option.interval);
}
}
option.poll++;
}

Fotiman

2:32 pm on Aug 26, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



A couple of things I notice:

document.getElementsByTagName('head')[0].insertBefore(js, document.getElementsByTagName('script')[1]);

Assumes that there are at least 2 script elements already in the head.

Also, this code looks like it could be subject to conflicts if ondemand is called multiple times. For example:

ondemand('foo', 'foo_init');
// option.interval = 1
// foo.js begins loading...
ondemand('bar', 'bar_init');
// option.interval = 2
// foo.js finishes loading
// clearInterval is called for interval 2, and 1 will continue repeating
// bar.js begins loading...
// bar.js finishes loading
// clearInterval is called for interval 2 again (no effect)

So you might try logging what intervals are being set and which ones are being cleared.

JAB Creations

2:45 pm on Aug 26, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks Fotiman, I actually refined this a lot and got it working in Internet Explorer too. In version 2.9 of my site I have split scripts in to a cached index.js file and an non-cached onload.js file.

I was not able to get clearInterval to work so I did the next best thing, I used setTimeout with an increasing integer. I've encountered a few instances where a loop would only apply to the same item versus each item in the array so I occasionally use paired functions like this and it works quite nicely.

I've got about half a dozen features I've moved in to on-demand scripting (reduced the 34KB index.js file down to under 16KB, both figures are compressed and I don't use frameworks). I've also made sure that none of the functions are loaded more then once and where applicable are not applied more then once.

Here is what I came up with...

- John

function ondemand(url,f)
{//alert(url+'\n\n'+f);
if (typeof f=='function') {eval(f+'();');}
else
{
var js=document.createElement('script')
js.setAttribute("type","text/javascript")
js.setAttribute("src",'scripts/'+url+'.js')
document.getElementsByTagName('head')[0].appendChild(js);
setTimeout(function() {ondemand_poll(f,0);},'100');
}
}


function ondemand_poll(f,i)
{//alert(url+'\n\n'+f);
if (i<100) {setTimeout(function() {if (eval('typeof ' + f)=='function') {eval(f+'();');} else {i++; ondemand_poll(f,i);}},'100');}
else {alert('Error: could not load \''+f+'\', please check your internet connection.');}
}