0

I have intergrated a third party code into my website, and suddenly the setTimeout and setInterval stopped working: Before the third party is loaded, everything works fine. setTimeout and setInterval that were scheduled to run after the third party is loaded, do not dun at all. After removing the 3rd party code snippet they supplied, everything work.

My question is - how can it be? what can the third pary do that can stop my schedules? I renamed any pointers to the returned value of the setTimeout function; I tried to play with the place where I put the snippet and / or the setTimeout code. Nothing work.

It doesn't make any sense. and I don't know how to start debugging it.

Here is a simplified html:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>My Demo</title>
<link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico"/>
<!--<link href="css/style.css" rel="stylesheet" type="text/css">-->
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
</head>
<body>
<script>
<!-- the alert pops up only when I remove the 3rd party snippet -->
    setTimeout(function(){      
        alert("done");
    }, 5000);   
</script>

<!-- This is the 3rd party code -->
<script type="text/javascript">
    var $P; var prefix = ('https:' == document.location.protocol ? 'https://' : 'http://'); var         _P = _P || [];
    _P.push(['setId', '123']);
    var PPP = document.createElement('script');
    PPP.type = 'text/javascript'; PPP.src = prefix +     'thethirdpartyIuse.com/functions.js';
    var s = document.getElementsByTagName('script');
    var lastScriptTag = s[s.length - 1];
    lastScriptTag.parentNode.insertBefore(PPP, lastScriptTag);
</script>
</body>
</html>

Any help & guideness is appriciated!

yonatan
  • 177
  • 1
  • 2
  • 14
  • 1
    I see no `$(document).ready({});` around any code... – Tomanow Dec 12 '14 at 11:27
  • 1
    Have you tried to change from alert() to console.log() ? Also have you tried to put the break point and debug through may be with firebug to check if the functions are being overwritten ? – Sariq Shaikh Dec 12 '14 at 11:30
  • 3
    Just a side note: A HTML comment inside the ` – Sirko Dec 12 '14 at 11:33
  • @Tomanow That is not needed in this case. – A1rPun Dec 12 '14 at 11:37
  • @Tomanow - Why do I need this? and anyway. I have it in the not simplified code. – yonatan Dec 12 '14 at 11:39
  • @ShaikhMohammedShariq I tried also log, same results. I tried to debug the code (also the 3rd party code), but I didn't see any "override". BTY, how does "override" of setTimeout looks like? – yonatan Dec 12 '14 at 11:41
  • @Sirko - thx, in the original code there is no comments. But thx for point it up. – yonatan Dec 12 '14 at 11:42
  • Are there any errors in console? – Ginden Dec 12 '14 at 15:58

4 Answers4

0

Are you sure? It works fine in liveweave: http://liveweave.com/OKMyjs And indeed you should wrap your code in:

 window.onload = function() {

//your stuff

}
Michelangelo
  • 5,888
  • 5
  • 31
  • 50
  • 1
    You know that `thethirdpartyIuse.com/functions.js` is just a cover up for the real thirdparty component right? – A1rPun Dec 12 '14 at 11:34
  • @A1rPun is right. I can't expose the real third party as it seems like a major bug of them, and we have business relationship with them. – yonatan Dec 12 '14 at 11:45
  • and why do I need window.onload? – yonatan Dec 12 '14 at 11:46
  • window.onload will wait for the window to be fully loaded and then execute your script. When you just write it down like this it will be executed when the browser gets to it. See also this post: http://stackoverflow.com/questions/20180251/when-to-use-window-onload – Michelangelo Dec 12 '14 at 11:53
0

May be the external code redefines alert as something else. To see if this is the issue try changing your code to:

(function(myalert){
  setTimeout(function(){      
      myalert("done");
  }, 5000);
})(alert);

If this doesn't work the only reason I can think to is that the external script goes into an infinite loop. Functions registered with setTimeout will be executed once the Javascript event loop starts after the synchronous execution of script tags in the page and this may never happen if any toplevel stript hangs.

You should however see in this case the loading is taking forever (loading animation in the browser) and after long enough the browser should signal that there is a problem loading the page.

6502
  • 112,025
  • 15
  • 165
  • 265
0

Something redefines your alert function.

Possible solutions:

  • wrap your code in (function(alert) { /* your code */ }(alert))
  • Object.defineProperty(window, 'alert', { configurable: false, enumerable: true, value: alert, writable: false }); to protect your alert from redefining.
  • do not rely on alert (in 99% of cases modal or console.log are superior solutions - alert, prompt and confirm are three functions blocking code execution in JavaScript).
Ginden
  • 5,149
  • 34
  • 68
  • The alert is just an example. even console.log doesn't work. The thing is that the setTimeout is overriden / canceled somehow by the third party, and I am trying to understand how. – yonatan Dec 13 '14 at 17:33
  • You can block redefinition of setTimeout in the same way. – Ginden Dec 13 '14 at 17:35
0

After a lot of debugging, I found the probelm: The 3rd party did setTimeout(true)for some reason (I assume by mistake). In chrome, it cancel all schedules (setTimeout & setInterva).

I report the problem.

Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
yonatan
  • 177
  • 1
  • 2
  • 14