我从书签中加载这个JS代码:
function in_array(a, b)
{
for (i in b)
if (b[i] == a)
return true;
return false;
}
function include_dom(script_filename) {
var html_doc = document.getElementsByTagName('head').item(0);
var js = document.createElement('script');
js.setAttribute('language', 'javascript');
js.setAttribute('type', 'text/javascript');
js.setAttribute('src', script_filename);
html_doc.appendChild(js);
return false;
}
var itemname = '';
var currency = '';
var price = '';
var supported = new Array('www.amazon.com');
var domain = document.domain;
if (in_array(domain, supported))
{
include_dom('http://localhost/bklts/parse/'+domain+'.js');
alert(getName());
}
[...]
请注意,'getName()'函数位于http://localhost/bklts/parse/www.amazon.com/js。这段代码只在我点击书签的第二时间起作用(该函数似乎在alert()之后才加载。)
奇怪的是,如果我将代码更改为:
if (in_array(domain, supported))
{
include_dom('http://localhost/bklts/parse/'+domain+'.js');
alert('hello there');
alert(getName());
}
我在第一次点击时获得两个警报,其余的脚本功能。如何在没有虚假警报的情况下首次单击书签时使脚本工作?
谢谢! -Mala
答案 0 :(得分:2)
添加<脚本>标签通过DHTML使脚本加载异常,这意味着浏览器将开始加载它,但不会等待它运行其余的脚本。
您可以处理标记对象上的事件,以找出加载脚本的时间。这是我使用的一段示例代码似乎在所有浏览器中都能正常工作,虽然我确信这是实现这一目标的更好方法,但我希望这应该指向正确的方向:
不要忘记将标记更改为包含< script>的对象element,fnLoader为加载脚本时调用的函数,fnError为函数,如果加载脚本失败则调用。
请记住,这些函数将在以后调用,因此它们(如tag)必须可用(闭包通常会处理)。
tag.onload = fnLoader;
tag.onerror = fnError;
tag.onreadystatechange = function() {
if (!window.opera && typeof tag.readyState == "string"){
/* Disgusting IE fix */
if (tag.readyState == "complete" || tag.readyState == "loaded") {
fnLoader();
} else if (tag.readyState != "loading") {
fnError();
};
} else if (tag.readyState == 4) {
if (tag.status != 200) {
fnLoader();
}
else {
fnError();
};
};
});
答案 1 :(得分:0)
听起来外部脚本(http://localhost/bklts/parse/www.amazon.com/js)的加载在加载之前不会阻止执行。简单的超时可能足以让浏览器有机会更新DOM,然后立即排队执行下一个逻辑块:
//...
if (in_array(domain, supported))
{
include_dom('http://localhost/bklts/parse/'+domain+'.js');
setTimeout(function() {
alert(getName());
}, 0);
}
//...
根据我的经验,如果零对超时量不起作用,那么你就有了真正的竞争条件。延长时间(例如10-100)可能会在某些情况下修复它,但是如果你需要它可以始终工作,你会遇到危险的情况。如果零对你有效,那么它应该是非常可靠的。如果没有,那么您可能需要将更多(全部?)剩余的代码推送到外部脚本中。
答案 2 :(得分:0)
我能开展工作的最佳方式:不要。
因为无论如何我从一个小的装载程序书签中调用JS(它只是将脚本固定到你正在查看的页面上)我修改了bookmarklet以将src指向一个输出JS代码的php脚本, document.domain作为参数。因此,我只使用php来包含外部代码。
希望有人帮助。由于这不是我的问题的答案,我不会将此标记为已接受的答案。如果有人有更好的方法,我很想知道,但我会按原样离开我的代码:
书签:
javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://localhost/bklts/div.php?d='+escape(document.domain);})();
本地主机/ bklts / div.php:
<?php
print("
// JS code
");
$supported = array("www.amazon.com", "www.amazon.co.uk");
$domain = @$_GET['d']
if (in_array($domain, $supported))
include("parse/$domain.js");
print("
// more JS code
");
?>