【问题标题】:Javascript: My setTimeout function not working because of 3rd partyJavascript:由于第 3 方,我的 setTimeout 函数无法正常工作
【发布时间】:2014-12-12 11:26:38
【问题描述】:

我已将第三方代码集成到我的网站中,突然 setTimeout 和 setInterval 停止工作:在加载第三方之前,一切正常。预定在第三方加载后运行的 setTimeout 和 setInterval,根本不拖欠。 删除他们提供的第 3 方代码 sn-p 后,一切正常。

我的问题是 - 怎么可能?第三方可以做什么来阻止我的日程安排? 我重命名了任何指向 setTimeout 函数返回值的指针;我尝试使用放置 sn-p 和/或 setTimeout 代码的地方。 没有任何效果。

这没有任何意义。我不知道如何开始调试它。

这是一个简化的 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>

感谢任何帮助和指导!

【问题讨论】:

  • 我看不到任何代码周围的$(document).ready({});...
  • 您是否尝试过从 alert() 更改为 console.log() ?您是否也尝试过设置断点并通过 firebug 进行调试以检查功能是否被覆盖?
  • 附注:&lt;script&gt; 中的 HTML 注释无效。在&lt;script&gt; 环境中使用JS cmets。
  • @Tomanow 在这种情况下不需要。
  • @Tomanow - 我为什么需要这个?无论如何。我在未简化的代码中有它。

标签: javascript html


【解决方案1】:

你确定吗?它在 liveweave 中运行良好:http://liveweave.com/OKMyjs 实际上,您应该将代码包装在:

 window.onload = function() {

//your stuff

}

【讨论】:

  • 您知道thethirdpartyIuse.com/functions.js 只是对真正的第三方组件的掩饰吧?
  • @A1rPun 是对的。我不能暴露真正的第三方,因为这似乎是他们的一个主要错误,我们与他们有业务关系。
  • 为什么我需要 window.onload?
  • window.onload 将等待窗口完全加载,然后执行您的脚本。当您像这样写下来时,它将在浏览器到达时执行。另见这篇文章:stackoverflow.com/questions/20180251/when-to-use-window-onload
【解决方案2】:

可能是外部代码将alert 重新定义为其他内容。要查看这是否是问题,请尝试将您的代码更改为:

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

如果这不起作用,我能想到的唯一原因是外部脚本进入了无限循环。使用setTimeout 注册的函数将在页面中的script 标签同步执行后开始执行Javascript 事件循环,如果任何顶级stript 挂起,这可能永远不会发生。

但是,在这种情况下,您应该会看到加载过程会持续很长时间(在浏览器中加载动画),并且在足够长的时间后,浏览器应该会发出信号表明加载页面存在问题。

【讨论】:

    【解决方案3】:

    某些东西重新定义了您的 alert 功能。

    可能的解决方案:

    • 将您的代码包装在(function(alert) { /* your code */ }(alert))
    • Object.defineProperty(window, 'alert', { configurable: false, enumerable: true, value: alert, writable: false }); 保护您的 alert 不被重新定义。
    • 不要依赖 alert(在 99% 的情况下,modal 或 console.log 是更好的解决方案 - alertpromptconfirm 是阻止 JavaScript 代码执行的三个函数)。

    【讨论】:

    • 警报只是一个例子。甚至 console.log 也不起作用。问题是 setTimeout 被第三方以某种方式覆盖/取消,我试图了解如何。
    • 同样可以阻止setTimeout的重新定义。
    【解决方案4】:

    经过大量调试,我找到了problem: 第 3 方出于某种原因做了setTimeout(true)(我猜错了)。 在 chrome 中,它会取消所有计划 (setTimeout & setInterva)。

    我报告了这个问题。

    【讨论】:

      猜你喜欢
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多