2

I'm working on some custom Javascript for a CMS template at work. I want to be able to make a certain <li> element on the page receive the class of "current" for that page only. So in the global page head I have something like this:

<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>

Then in each individual page <head>, I have something like this:

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

On the page I have a nav <ul>, with something like:

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

etc.

When I load the page, the class is not applied. When I look in the Firebug console, it gives the error message:

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

I'm still getting the hang of writing solid, raw javascript (learning backwards after jQuery, you know how it goes), but I want to write it in just JS. What idiotic newbie mistake am I making?

Thanks everyone!

4

5 回答 5

3

如果在 DOM 树完成加载之前执行 javascript,它将返回 null。因此,一个想法是在关闭 body 标记之前一直调用该函数。

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

于 2010-09-29T15:27:32.547 回答
2

The element does not exist yet when that script is being evaluated. Put it in the body's onload handler or something instead, so it executes once the DOM is in place.

An example of how to do this without touching any markup:

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

callWhenLoaded(function() { makeCurrent("undergraduate"); });
于 2010-09-29T15:27:18.990 回答
2

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

您的代码可以优化:您可以class直接使用current.className = 'current';.

于 2010-09-29T15:28:09.383 回答
1

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

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

于 2010-09-29T15:28:56.650 回答
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。

正如其他人所提到的,它可能归结为在您引用它时不等待该元素可用。

于 2010-09-29T15:34:08.020 回答