【发布时间】:2010-08-29 08:33:37
【问题描述】:
我有一个类似小部件的 HTML+JavaScript 块,人们可以将它复制/粘贴到他们的 HTML 页面中一次或多次。该块检查外部 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)
}
})();
外部 JavaScript 文件检查 HTML 页面中的小部件实例(使用 getElementsByClassName)并处理这些实例,有点像这样;
for (var i=0;i<document.getElementsByClassName('target').length;i++) {
document.getElementsByClassName('target')[i].style.borderStyle="solid";
}
可以在 http://futtta.be/opera_enigma.html 上找到一个工作示例。
这在 Firefox (3.6 & 4b)、Chrome (5 & 6) 和 Safari 中完美运行,但在 Opera 中无法正常运行(使用最新版本 10.61 进行测试):无论有多少“小部件”(div class='target') 存在,Opera 只作用于第一个,因为显然 nodeList 只包含 1 个条目(长度是 1 而不是 2 或 3 或 ...)。
如果在小部件的 javascript 中我调用函数以使用 window.onload 加载外部脚本,问题就会消失,但我希望我的小部件尽快激活(不干扰页面的其余部分,因此异步的东西)。
所以我的问题;我的代码中是否存在 Firefox、Safari 和 Chrome 忽略的错误?这是Opera中的错误吗?如何让 Opera 正常运行?
【问题讨论】:
-
嗯,首先应该是
var d = document!请减少全局命名空间污染! :) 另外,请记住,每次访问document.getElementsByClassName("target")时,它都必须重新生成该列表。所以你应该做类似for (var i = 0, a = Array.prototype.slice.call(document.getElementsByClassName("target")), len = a.length; i < len; i++) { a[i].style.borderStyle = "solid"; } -
谢谢,中肯的建议,我会记住的。
标签: javascript opera