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

Javascript 当我知道ID存在时,为什么document.getElementById()返回空值?,javascript,getelementbyid,Javascript,Getelementbyid,我正在为CMS模板开发一些自定义Javascript。我希望能够使页面上的某个元素仅接收该页面的“current”类。因此,在全局页面标题中,我有如下内容: <script type="text/javascript"> function makeCurrent(id) { var current = document.getElementById(id); current.setAttribute("class", "current"); // fo

我正在为CMS模板开发一些自定义Javascript。我希望能够使页面上的某个
  • 元素仅接收该页面的“current”类。因此,在全局页面标题中,我有如下内容:

    <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>
    
    <script type="text/javascript">makeCurrent("undergraduate")</script>
    
    我仍然掌握着编写坚实、原始javascript的窍门(在jQuery之后向后学习,你知道它是怎么回事),但我只想用JS编写它。我犯了什么愚蠢的新手错误


    谢谢大家

    在对脚本求值时,元素还不存在。将其放入主体的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"); });
    

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


    这就是为什么大多数JavaScript库都支持dom就绪事件,现代浏览器也支持dom就绪事件(domcontentloaded),但是对于宽浏览器支持来说,为自己实现这一点有点困难(好吧,没那么难,我认为有3到4种不同的方式)

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


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

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


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

    在所有的技术答案都已经给出之后,我将跳过所有可能的答案,并选择一些我遇到的更明显的问题,一旦我意识到这些问题,我就会使用facepalm:

    • 身份中的打字错误
    • 该标识不是您所认为的,因为它是由您正在使用的web框架生成或部分生成的,即在ASP.NET中,您可以将客户端id设置为“MyControl”,但在客户端呈现时,却发现它是“Page_1$Control_0$MyControl$1”
    • 例如,您在一个或多个不正确的位置用#作为前缀,尽管在示例中,如果对象id为MyControl,您没有使用jQuery,但在jQuery和CSS中,您使用#MyControl引用它,但在对象的实际id中,您没有使用#。在document.getElementById()中,不像在jQuery和CSS中那样使用#,但可能是无意中使用了它
    • 您在控件中设置了name元素,而不是id

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

    顺便说一句,我知道在主体上使用类然后使用CSS会更容易访问,但是这个CMS不允许我在主体元素(或者任何元素,真的)上编写动态类。运行脚本时,文档可能未完全加载。尝试将脚本放在文档的最末尾,或者检查文档何时完成加载。可能是重复,愚蠢的错误。虽然我的手被它束缚住了,因为我不能在这个特定的CMS中除了头部以外的任何地方添加每页脚本标记,但如果我在结束正文标记之前添加它们,那么它们是站点范围的。我改变了策略,尝试将导航链接的href属性与window.location.href进行比较,如果它们匹配,则添加一个“当前”类。它起作用了。。。在Firefox和Chrome上,但IE7已经崩溃了@杰森·罗德斯:我添加了一个例子,说明了如何在不触碰身体标签的情况下做到这一点。
    current is null
    (x)  current.setAttribute("class", "current"); 
    
    function callWhenLoaded(func) {
      if (window.addEventListener) {
        window.addEventListener("load", func, false);
      } else if (window.attachEvent) {
        window.attachEvent("onload", func);
      }
    }
    
    callWhenLoaded(function() { makeCurrent("undergraduate"); });