在<head>标签中执行JavaScript,getElementById返回null

9
我有如下代码
<html>
<head>
<script language="JavaScript">

function foo(q) {
    this.run=function(color){
        var x=document.getElementById("ff");
        alert(x); // <----x=null
    };

}

var q=new foo();
q.run("yellow");
</script>
</head>
<body>

<div id="ff"></div>

</body>
</html>

有人知道为什么x=null吗?


1
参见https://dev59.com/QlbTa4cB1Zd3GeqP9lTG#5703932 顺便提一下,script元素的language属性早已被废弃。 - Marcel Korpel
如果我能从每个关于这个问题的SO问题中得到一分钱... :) - Šime Vidas
2
您应该通过点击空心勾选来接受答案。 - SLaks
3个回答

23

这是因为在DOM加载之前调用了脚本,导致它的值为null

将你的脚本封装在一个函数中,该函数将在onload事件触发时被调用,例如:

window.onload = function() {
    var q = new foo();
    q.run('yellow');
};

1

当脚本被解析时,只有<html><head>标签已经被加载。你可以通过以下几种方式来解决这个问题:

  1. <script>标签放在文档的末尾,而不是开头
  2. 将Javascript代码放在另一个文件中,并使用<script type="text/javascript" src="OtherFile.js"></script>在头部加载它
  3. 将整个函数包装在window.onload = function () { yourCodeHere(); }中,这将暂停执行您的代码,直到窗口加载完成。

1
这并不完全正确:DOM 使用的是元素(elements),而非标签(tags)。这意味着 head 元素尚未完全插入到 DOM 中,您无法可靠地操作 head 元素。此外,(2)无法解决此问题,无论您是将代码内联还是放在外部脚本中,JavaScript 脚本都是按顺序执行的。 - Marcel Korpel
Marcel,感谢您的澄清。就您提到的第二点而言,将脚本加载到另一个文件中不就相当于使用async=false运行它吗? - Zach Rattner

1

这段JS代码将在DOM准备就绪之前运行,因此节点将无法被找到。为了在DOM准备就绪后仅执行一次,您可以使用window.onload事件处理程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接