为什么这个 Javascript 不适用于 Opera 或 Chrome?

Why doesn't this Javascript work with Opera or Chrome?

提问人:Eli 提问时间:6/8/2009 最后编辑:CommunityEli 更新时间:6/28/2009 访问量:3993

问:

感谢您的阅读。

我有几个脚本,其构建类似于以下内容:

scriptone.js

function FunctionOne(){

    // Do a bit of work...

    // Include a second javascript file, scripttwo.js
    // that contains a function called FunctionTwo.js
    var scrb = document.createElement('script');
    scrb.type = 'text/javascript';
    scrb.src = 'http://www.example.com/scripttwo.js?bunchofargs=varied';

    // Append it to the head.
    document.getElementsByTagName('head')[0].appendChild(scrb);

    // Can't run the second function directly, because it may not be loaded quite yet,
    // So use the Waiter function.
    Interval = setInterval("Waiter()", 10);

    // All done.
    return;

}

function Waiter(){
    if(window.FunctionTwo) {
        clearInterval(Interval);
        FunctionTwo();
    }
}

脚本二.js

function FunctionTwo(){
    document.write('something based on calling page');
}

这适用于 FF 和 IE,但不适用于 Opera 或 Chrome。在 Chrome/Opera 中,脚本一中一切似乎都正常。但是,脚本two.js中应该发生的任何事情实际上都没有发生。就好像scripttwo.js没有被包括在内。

任何想法为什么这不适用于 Opera 或 Chrome?

也许我使用的是不兼容的东西,或者是否有我不知道的安全功能?所有文件都位于同一域中。


注意很棒的回复 - 非常感谢!

FuncionOne 在这里只是一个错别字,在实际代码中,我使用了更好的函数名称,但为了可读性,我在这里更改了它们。这可能是范围,尽管我同意乔·怀特(Joe White)的观点,这不应该是一个问题。对于JavaScript(我的弱语言之一),谁知道呢?FunctionOne 是从 HTML 文档的头部或正文调用的。

我也喜欢在脚本二的末尾添加 FuncTwo 的想法,以完全避免计时器。更干净,一旦有人向你指出来,就很明显......

我将在下次处理此内容后进行更新。

再次更新:

大家好

我现在让它在 FF、IE 和 Chrome 中工作,但 Opera 现在似乎拒绝加载任何 .js 文件。我认为这只是某种 Opera 问题(Opera:.js 文件不会加载),并且将继续其他三个。让你知道结果如何。

JavaScript 跨浏览器

评论


答:

1赞 Oli 6/8/2009 #1

一些问题/意见可能会给你答案:

  • 什么叫(注意你的拼写)?FuncionOne

  • 计时器很混乱,并不总是递归(除非停止,否则会再次触发)。我会重构以检查是否仍然存在,如果没有,请创建一个递归.Waiter()Intervalwindow.setInterval

  • 在这一点上,您可能需要明确指定 ,而不是省略window.setIntervalwindow.

  • 工作范围是吗?您可以在函数中定义它。传统逻辑会说,在不会有访问权限......但是JS那样有点乱。Opera 和 Chrome 可能比您希望的要麻烦一些。仅仅在任何函数范围之外定义它就可以解决这个问题。IntervalclearInterval(Interval);Waiter()

评论

0赞 Joe White 6/8/2009
Interval 不会在本地声明为 var;因此,它是隐式的 Window.Interval(我讨厌 JavaScript 的原因之一)。范围不应该成为问题。
0赞 Oli 6/8/2009
如果你确定你的代码应该可以工作,但它在某些平台上不能正常运行,那么不必要的隐含应该是你的首要目标。每个主流浏览器都运行自己的 Javascript 实现,因此有很大的空间可以弥补这些差距。
2赞 SpliFF 6/8/2009 #2

你可以将 FunctionTwo() 添加到 scripttwo.js 的末尾。然后,它将在加载时运行,而不会增加间隔的复杂性。

3赞 Thorarin 6/8/2009 #3

它在 Opera 中对我有用。

您可以使用事件来代替使用 Waiter 脚本:

scrb.onload = function() { FunctionTwo() }
scrb.onreadystatechange = function() { FunctionTwo() }

第二行是 Internet Explorer 的工作。一个问题是 Opera 似乎对这两个事件都进行了处理,因此 FunctionTwo() 将被执行两次。有多种方法可以解决这个问题。浏览器检测、一些全局变量等。

1赞 Thevs 6/8/2009 #4

我认为问题出在范围上。它在 FunctionOne 内部定义,但不在全局范围内定义。所以,我怀疑在执行时,Opera 和 Chrome 会遇到这种情况,并且只是默默地退出 FunctionTwo(也许停止脚本?FF 和 IE 可能会忽略这一点。IntervalWaiterIntervalundefined

(顺便说一句,当它收到未定义的参数值时,规范应该怎么做?clearInterval

评论

0赞 Nosredna 6/9/2009
问得好。w3schools.com/js/tryit.asp?filename=tryjs_setinterval刚刚在Chrome和Firefox中尝试过,它悄无声息地失败了。