解决方案:我将排队机制调用到window.onload的方式似乎存在问题。
序言 - 我很高兴看到我被标记为副本,解决方案是使用window.onload,这是我已经在这里使用的东西。一些评论表明我从另一个stackoverflow解决方案中获得的队列可能存在问题,但由于缺乏详细说明而让我陷入困境。
问题:如果我在头部进行函数调用,则会失败。如果我在体内进行函数调用,它就会成功。为什么呢?
扩展:为什么在失败调用之上的global.js中对同一函数的调用成功?
我有一些javascript可以创建一个onload" queue"排序(global.js中的函数addLoadEvent)。对此函数的调用会在调用onload时添加到队列中。
除此之外,我发现如果特定的脚本函数调用位于头部和体内,则会失败。我无法弄清楚为什么,因为所需的一切(其他js函数)都被加载到函数调用本身之上,并且在onload之前不会触发对函数的实际调用,从而确保存在必要的html元素。
装载顺序:
出于这个问题的目的,基于它的位置失败或成功的函数调用如下。
addLoadEvent(initialFighter());
这里是精简的HTML,请注意标记的2个位置。如果我将上述函数调用复制粘贴到位置1,则失败。如果我将上述函数调用复制粘贴到位置二,则成功。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="global.js"></script>
<script type="text/javascript">
function showFighter(id) {
var pic = document.getElementById("picture");
var picPath = 'url(images/' + id + '.png)';
pic.style.backgroundImage = (picPath);
}
function initialFighter() {
var fighter = getURLParameter('fighter');
if (typeof(fighter) != "undefined" && fighter != null) {
showFighter(fighter);
} else {
showFighter('Foobar');
}
}
***** LOCATION ONE *****
</script>
</head>
<body>
<header></header>
<nav id="nav"></nav>
<section id="fighters">
<div id="picture"></div>
<div id="text"></div>
<script type="text/javascript">
***** LOCATION TWO *****
</script>
</section>
<footer id="footer"></footer>
</body>
</html>
下面是global.js,这是第一个加载的脚本文件:
请注意,这里有2个addLoadEvent(func)调用,并且它们成功(直到html元素存在之后才会运行),尽管几乎所有其他内容都是如此。
function addLoadEvent(func) {
var prevOnLoad = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (prevOnLoad) {
prevOnLoad();
}
func();
}
}
}
function loadFile(id, filename) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById(id).innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open('GET', filename, true);
xmlhttp.send();
}
addLoadEvent(loadFile('nav', 'nav.txt'));
addLoadEvent(loadFile('footer', 'footer.txt'));
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
答案 0 :(得分:1)
addLoadEvent
的参数应该是一个函数,它将在onload
回调期间调用。您立即调用该函数并传递其返回值,因此该函数不会等待onload
事件,并且您会收到错误,因为DOM中的元素尚未生效。它应该是:
addLoadEvent(function() { loadFile('nav', 'nav.txt'); });
addLoadEvent(function() { loadFile('footer', 'footer.txt'); });
addLoadEvent(initialFighter);
您不需要initialFighter
的匿名包装函数,因为它不会接受任何参数。你只需要省略()
,所以你传递了对函数的引用,而不是立即调用函数。
此外,通过保存旧值并在新函数中调用它来代替链接onload
事件处理程序,您可以简单地使用addEventListener
,因为它们会自动添加到侦听器列表而不是替换它:
function addLoadEvent(func) {
window.addEventListener("load", func);
}