当我知道ID存在时,为什么document.getElementById()返回null值?

时间:2010-09-29 15:24:28

标签: javascript getelementbyid

我正在为工作中的CMS模板开发一些自定义Javascript。我希望能够在页面上创建某个<li>元素,只接收该页面的“当前”类。所以在全局页面中我有这样的东西:

<script type="text/javascript">
    function makeCurrent(id) {
      var current = document.getElementById(id);
      current.setAttribute("class", "current"); // for most browsers
      current.setAttribute("className", "current"); // for ie
    }
</script>

然后在每个页面<head>中,我有这样的事情:

<script type="text/javascript">makeCurrent("undergraduate")</script>

在页面上,我有一个导航<ul>,类似于:

<li id="undergraduate"><a href="...">Undergraduate Program</a></li>
<li id="graduate"><a href="...">Graduate Program</a></li>

etc.

加载页面时,不应用该类。当我查看Firebug控制台时,它会显示错误消息:

current is null
(x)  current.setAttribute("class", "current"); 

我仍然习惯于编写可靠的原始javascript(在jQuery之后向后学习,你知道它是怎么回事),但我想用JS编写它。我在做什么愚蠢的新手错误?

谢谢大家!

5 个答案:

答案 0 :(得分:3)

如果在DOM树加载完成之前执行javascript,它将返回null。所以一个想法是在关闭body标签之前最后调用函数。

这就是为什么大多数JavaScript库都支持dom-ready事件,现代浏览器也支持这种情况(domcontentloaded)但是对于广泛的浏览器支持来说,为自己做这件事有点棘手(好吧,不是那么困难,3或者我认为有4种不同的方式。)

答案 1 :(得分:2)

在评估该脚本时,元素不存在。把它放在body的onload处理程序或其他东西中,所以它在DOM就位后执行。

如何在不触及任何标记的情况下执行此操作的示例:

function callWhenLoaded(func) {
  if (window.addEventListener) {
    window.addEventListener("load", func, false);
  } else if (window.attachEvent) {
    window.attachEvent("onload", func);
  }
}

callWhenLoaded(function() { makeCurrent("undergraduate"); });

答案 2 :(得分:2)

如果您在脑中运行makeCurrent,则DOM未完全加载。您应该在 <li>标记之后将该脚本放入。

您的代码可以进行优化:您可以直接使用class设置current.className = 'current';属性。

答案 3 :(得分:1)

原因是您的脚本在页面加载完成之前运行,因此在填充DOM之前。

您需要确保在页面加载完成后才调用该函数。通过使用document.onload()或body标签上的onload事件触发它来执行此操作。

答案 4 :(得分:1)

在所有的技术答案已经喷出之后,我将跳过所有那些很有可能的东西,然后去找一些我遇到的更明显的问题,这些问题一旦我成功了我意识到了:

  • 身份错字
  • 身份不是您认为的,因为它是由您正在使用的Web框架生成或部分生成的,即在ASP.NET中,您可以将客户端ID设置为“MyControl”,但只能查找到时间它在客户端呈现为“Page_1 $ Control_0 $ MyControl $ 1”
  • 例如,你在一个或多个不正确的地方用#作为前缀,虽然如果对象id是MyControl你没有在你的例子中使用jQuery,在jQuery和CSS中你使用#MyControl引用它,但在对象的实际id中,你没有使用#。在document.getElementById()中,使用#就像你在jQuery和CSS中那样,但你可能无意中使用了它。
  • 您已在控件中设置name元素而不是id。

正如其他人提到的那样,可能是因为在你引用元素时没有等待元素可用。