Opera中的JavaScript范围问题?

Opera中的JavaScript范围问题?,javascript,opera,Javascript,Opera,我有一个类似HTML+JavaScript的小部件,人们可以将它复制/粘贴到HTML页面中一次或多次。该块检查DOM中是否已有外部JavaScript文件,如果没有,则加载该文件,如下所示: (function(){ d = document; if (!d.getElementById('ex-scr')) { scr = d.createElement('script'); scr.async = true; scr.id = 'ex-scr'; sc

我有一个类似HTML+JavaScript的小部件,人们可以将它复制/粘贴到HTML页面中一次或多次。该块检查DOM中是否已有外部JavaScript文件,如果没有,则加载该文件,如下所示:

(function(){
  d = document;
  if (!d.getElementById('ex-scr')) {
    scr = d.createElement('script');
    scr.async = true;
    scr.id = 'ex-scr';
    scr.src = 'external.js';
    d.getElementsByTagName('head')[0].appendChild(scr)
  }
})();
外部JavaScript文件检查HTML页面中的小部件实例(使用GetElementsByCassName),并处理这些实例,有点像这样

for (var i=0;i<document.getElementsByClassName('target').length;i++) {
 document.getElementsByClassName('target')[i].style.borderStyle="solid";
}
(变量i=0;i)的

如果在小部件的javascript中调用函数以使用window.onload加载外部脚本,问题就会消失


我认为这就是你的问题所在。当在脚本文件中执行
getElementsByClassName
时,DOM还不能保证完全存在。如果不等到
DOMready
加载
事件,你就无法在这里创建可靠的行为。

你可能遇到了sm浏览器之间的所有时间差异:如果您通过DOM向文档头部添加脚本,Opera当前将等待脚本执行后再解析文档的其余部分。这是我在这里写的第三个问题:

其他主要浏览器将在等待外部脚本时继续解析。当外部脚本进入时,它们将运行该脚本,这是随机的(取决于缓存、文档大小、连接速度等)可能会使它在您想要处理的所有元素都在DOM中时运行。但是,我可以保证,在您知道解析完整标记之前,尝试在DOM中查找特定类型的所有元素会给任何浏览器中的某些用户带来问题-您所做的对小型网络hiccu过于敏感ps、连接速度差异、CPU功率以及加载和解析网页时影响计时的所有其他微小差异


浏览器向您发出两个信号,表明页面已准备好编写脚本:DOMContentLoaded事件和onload。如果需要从文档或其元素中读取维度,则可能需要等待所有图像和CSS加载完毕(即等待onload事件),否则可以使用DOMContentLoaded.jQuery为您提供$(document).ready()为了消除浏览器支持的“DOM现在准备好了”信号之间的差异,其他框架可能也有类似的功能。

对于初学者来说,它应该是
var d=document
!请减少全局名称空间污染!:)另外,请记住每次访问
document.getElementsByClassName(“目标”)
它必须重新生成该列表。因此,您应该为(var i=0,a=Array.prototype.slice.call(document.getElementsByClassName(“target”))执行类似于
的操作,len=a.length;i
谢谢您的建议,我会记住这一点,从这个意义上说,ff/chrome/safari不介意我这么做,这甚至很奇怪:)@futta这可能是由于不同的DOM处理/渲染/优先级/优化方法。是的,我会尝试用domready做一些事情(特定于opera),谢谢@不客气,但我不相信任何浏览器中的这个。你永远不会确切知道你得到了什么结果,例如在速度较慢的机器上。我会在所有浏览器中使用DOMReady(顺便说一句,Opera将尝试在这一点上与其他浏览器保持一致,并警告说“外部脚本加载时间”是一个随机因素,并且将继续是一个随机因素。)基于这一点和pekka的评论,我已经在重新编写脚本以等待domcontentloaded。关于opera处理动态添加脚本的方式;如果它等待脚本加载、解析和执行,这意味着目前无法在opera中进行异步脚本加载(如google使用其分析代码所做的那样)?这并非完全不可能,只要您记住,在解析时,异步脚本可能看不到完整的DOM,就可以正常工作。如果从DOMContentLoaded事件开始或之后将这些脚本添加到DOM中,则从DOM中读取不会有问题。