简体   繁体   English

Opera中的JavaScript范围问题?

[英]JavaScript scope issue in Opera?

I have a widget-like block of HTML+JavaScript that people can copy/paste into their HTML-page one or multiple times. 我有一个类似于小部件的HTML + JavaScript块,人们可以一次或多次复制/粘贴到他们的HTML页面中。 That block checks if an external JavaScript file is already in the DOM, and loads it if not, something like this: 该块检查外部JavaScript文件是否已经存在于DOM中,如果没有,则加载它,如下所示:

(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)
  }
})();

The external JavaScript-file checks the HTML-page for instances of the widget (using getElementsByClassName) and does stuff with those instances, kind of like this; 外部JavaScript文件检查HTML页面中的窗口小部件实例(使用getElementsByClassName)并对这些实例进行处理,类似于此;

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

A working example of this can be found on http://futtta.be/opera_enigma.html . 可以在http://futtta.be/opera_enigma.html上找到这方面的工作示例。

This works perfectly in Firefox (3.6 & 4b), Chrome (5 & 6) and Safari, but does not work as expected in Opera (tested with most recent version, 10.61): no matter how many 'widgets' (divs with class='target' ) are present, Opera only acts on the first one because apparently the nodeList only contains 1 entry (length is 1 instead of 2 or 3 or ...). 这在Firefox(3.6和4b),Chrome(5和6)和Safari中完美运行,但在Opera中没有预期的效果(使用最新版本10.61测试):无论有多少'小部件'(div class='target' )存在,Opera只作用于第一个,因为显然nodeList只包含1个条目(长度为1而不是2或3或......)。

The problem goes away if in the widget's javascript I call the function to load the external script with window.onload, but I'd like my widget to activate as soon as possible (without interfering with the rest of the page, hence the asynchronous stuff). 如果在小部件的javascript中调用函数来加载带有window.onload的外部脚本,问题就会消失,但我希望我的小部件能够尽快激活(不会干扰页面的其余部分,因此异步的东西)。

So my questions; 所以我的问题; is there a bug in my code which Firefox, Safari and Chrome ignore? 我的代码中是否存在Firefox,Safari和Chrome忽略的错误? Is this a bug in Opera? 这是Opera中的一个错误吗? How can I get Opera to behave? 我怎样才能让Opera表现出来?

The problem goes away if in the widget's javascript I call the function to load the external script with window.onload 如果在小部件的javascript中我调用函数来加载带有window.onload的外部脚本,问题就消失了

I think that's your problem right there. 我认为这就是你的问题。 When the getElementsByClassName is executed in your script file, the DOM is not yet guaranteed to be completely present. 在脚本文件中执行getElementsByClassName ,尚未保证DOM完全存在。 You won't be able to create reliable behaviour here without waiting until the DOMready or loaded event. 如果不等到DOMready或已loaded事件,您将无法在此处创建可靠的行为。

You are probably running into a small timing difference between browsers: if you through DOM add a SCRIPT to the head of a document, Opera will currently wait until the script is executed before parsing the rest of the document. 您可能在浏览器之间遇到了一个小的时间差异:如果您通过DOM将SCRIPT添加到文档的头部,Opera将在解析文档的其余部分之前等待脚本执行。 This is the third issue I wrote about here: http://my.opera.com/hallvors/blog/2009/03/07/websites-playing-timing-roulette 这是我在这里写的第三个问题: http//my.opera.com/hallvors/blog/2009/03/07/websites-playing-timing-roulette

The other major browsers will keep parsing while waiting for the external script. 其他主流浏览器将在等待外部脚本时继续解析。 They will run the external script when it comes in, which randomly (depending on caching, size of document, speed of connection etc.) might make it run when all the elements you want to act on are in the DOM. 它们将在它进入时运行外部脚本, 随机 (取决于缓存,文档大小,连接速度等)可能使它在您想要操作的所有元素都在DOM中时运行。 However, I can pretty much promise that trying to look up all elements of a certain type in the DOM before you know the full markup is parsed will cause problems for some users in any browser - what you are doing is way too sensitive to small network hiccups, connection speed differences, CPU power and all the other minor differences that affect timing while loading and parsing a web page. 但是,我几乎可以承诺,在您知道解析完整标记之前尝试查找DOM中某种类型的所有元素会导致任何浏览器中的某些用户出现问题 - 您所做的是对小型网络过于敏感打嗝,连接速度差异,CPU功率以及在加载和解析网页时影响计时的所有其他细微差别。

Browsers give you two signals the page is ready for scripting: DOMContentLoaded event and onload. 浏览器为您提供两个信号,表明页面已准备好编写脚本:DOMContentLoaded事件和onload。 If you need to read dimensions from the document or its elements, you probably need to wait until all images and CSS are loaded (ie wait for the onload event), if not you can use DOMContentLoaded. 如果您需要从文档或其元素中读取维度,您可能需要等到所有图像和CSS都被加载(即等待onload事件),否则您可以使用DOMContentLoaded。 jQuery gives you $(document).ready() to abstract away the differences in what "DOM is ready now" signals browsers support, other frameworks probably have equivalents. jQuery为你提供$(document).ready()来消除浏览器支持的“DOM现在就绪”信号的差异,其他框架可能具有等价物。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM