为什么jQuery或像getElementById这样的DOM方法找不到元素?

document.getElementById$("#id")或任何其他DOM方法/ jQuery选择器未找到元素的可能原因是什么?

示例问题包括:

jQuery默默无法绑定事件处理程序,并且返回null的标准DOM方法导致错误:

Uncaught TypeError:无法设置null的属性'...'


当您的脚本运行时,您尝试查找的元素不在DOM中。

您的DOM依赖脚本的位置可能会对其行为产生深远影响。 浏览器从上到下解析HTML文档。 元素被添加到DOM并且脚本(通常)在遇到时执行。 这意味着订单很重要。 通常,脚本无法找到标记后面出现的元素,因为这些元素尚未添加到DOM中。

考虑以下标记; 脚本#1在脚本#2成功时未能找到<div>

<script>
  console.log("script #1: %o", document.getElementById("test")); // null
</script>
<div id="test">test div</div>
<script>
  console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
</script>

简而言之:因为您正在查找的元素在文档中尚不存在(尚)。


对于这个答案的其余部分,我将使用getElementById作为示例,但同样适用于getElementsByTagNamequerySelector和任何其他选择元素的DOM方法。

可能的原因

元素可能不存在有两个原因:

  • 具有传递的ID的元素实际上不存在于文档中。 您应该仔细检查您传递给getElementById的ID是否与(生成的)HTML中现有元素的ID真正匹配,并且您没有拼错ID(ID区分大小写!)。

    顺便提一下,在大多数实现querySelector()querySelectorAll()方法的当代浏览器中,CSS样式表示法用于通过其id检索元素,例如: document.querySelector('#elementID') ,而不是在document.getElementById('elementID')下通过id获取元素的方法; 在第一个#字符是必不可少的,在第二个它会导致该元素不被检索。

  • 您调用getElementById时,该元素不存在。

  • 后一种情况很常见。 浏览器从上到下分析和处理HTML。 这意味着在DOM元素出现在HTML之前发生的对DOM元素的任何调用都将失败。

    考虑下面的例子:

    <script>
        var element = document.getElementById('my_element');
    </script>
    
    <div id="my_element"></div>
    

    div出现在script 。 在脚本执行的那一刻,元素还不存在, getElementById将返回null

    jQuery的

    这同样适用于所有使用jQuery的选择器。 如果拼写错误,或者您试图在实际存在之前选择它们,jQuery将无法找到元素。

    另外一个转折点是当jQuery没有找到,因为你已经加载了没有协议的脚本并且正在从文件系统运行:

    <script src="//somecdn.somewhere.com/jquery.min.js"></script>
    

    此语法用于允许脚本通过HTTPS在协议https://的页面上加载,并使用协议http://在页面上加载HTTP版本

    它具有尝试和未能加载file://somecdn.somewhere.com...的不幸副作用file://somecdn.somewhere.com...


    解决方案

    在调用getElementById (或任何DOM方法)之前,请确保您要访问的元素存在,即DOM已加载。

    这可以通过简单地将JavaScript放在相应的DOM元素之后来保证

    <div id="my_element"></div>
    
    <script>
        var element = document.getElementById('my_element');
    </script>
    

    在这种情况下,您还可以将代码放在关闭主体标记( </body> )之前(所有DOM元素在脚本执行时都可用)。

    其他解决方案包括监听load [MDN]或DOMContentLoaded [MDN]事件。 在这些情况下,放置JavaScript代码的文档中的哪个位置并不重要,您只需记住将所有DOM处理代码放入事件处理程序。

    例:

    window.onload = function() {
        // process DOM elements here
    };
    
    // or
    
    // does not work IE 8 and below
    document.addEventListener('DOMContentLoaded', function() {
        // process DOM elements here
    });
    

    有关事件处理和浏览器差异的更多信息,请参见quirksmode.org上的文章。

    jQuery的

    首先确保jQuery已正确加载。 使用浏览器的开发人员工具来查找是否找到了jQuery文件,如果不是,请更正URL(例如,在开头添加http:https:方案,调整路径等)

    监听load / DOMContentLoaded事件正是jQuery对.ready() [docs]所做的事情。 所有影响DOM元素的jQuery代码都应该放在该事件处理程序中。

    实际上,jQuery教程明确指出:

    正如我们在使用jQuery时所做的几乎所有事情都是读取或操作文档对象模型(DOM)一样,我们需要确保在DOM准备好后立即开始添加事件等。

    为此,我们为文档注册一个准备好的事件。

    $(document).ready(function() {
       // do stuff when DOM is ready
    });
    

    或者,您也可以使用简写语法:

    $(function() {
        // do stuff when DOM is ready
    });
    

    两者都是相同的。


    基于ID的选择器不起作用的原因

  • 指定了id的元素/ DOM尚不存在。
  • 元素存在,但它没有在DOM中注册[在从Ajax响应中动态添加HTML节点的情况下]。
  • 存在多个具有相同ID的元素,这会导致冲突。
  • 解决方案

  • 尝试在声明后访问元素,或者使用像$(document).ready();这样的东西$(document).ready();

  • 对于来自Ajax响应的元素,请使用jQuery的.bind()方法。 老版本的jQuery具有.live()

  • 使用工具[例如浏览器的webdeveloper插件]查找重复的ID并将其删除。

  • 链接地址: http://www.djcxy.com/p/55787.html

    上一篇: Why does jQuery or a DOM method such as getElementById not find the element?

    下一篇: How to open a Bootstrap modal window using jQuery?