简短明了:因为你正在寻找的元素尚未存在于文档中。
在接下来的回答中,我将使用getElementById
作为示例,但同样适用于getElementsByTagName
, querySelector
和任何其他选择元素的DOM方法。
可能的原因
一个元素不存在可能有三个原因:
- 传递的 ID 在文档中不存在。您应该仔细检查传递给
getElementById
的 ID 是否确实与 (生成的) HTML 中现有元素的 ID 匹配,并且您未拼写错误 (ID 区分大小写!)。
如果您使用 getElementById
,请确保您只提供元素的 ID (例如,document.getElemntById("the-id")
)。如果您使用接受 CSS 选择器的方法 (例如 querySelector
),请确保在 ID 前包含 #
,以表示您正在查找 ID (例如,document.querySelector("#the-id")
)。您不得在 getElementById
中使用 #
,必须在 querySelector
等方法中使用它。此外,请注意,如果 ID 中有 CSS 标识符 中不合法的字符(例如 .
;包含 .
字符的 id 属性是不好的做法,但是合法的),则必须在使用 querySelector
时对其进行转义(例如,document.querySelector("#the\\.id")
)但是在使用 getElementById
时不需要转义(例如,document.getElementById("the.id")
)。
在调用 getElementById
时,该元素此时不存在。
尽管您在页面上可以看到该元素,但它不在您正在查询的文档中,因为它位于一个 iframe
中(它有自己的文档)。当您搜索包含它们的文档时,iframes
中的元素不会被搜索。
如果问题是第三个原因(它在一个
iframe
或类似的地方),您需要查看
iframe
中的文档,而不是父文档,可能通过获取
iframe
元素并使用其
contentDocument
属性来访问其文档(仅限同源)。本答案的其余部分解决了前两个原因。
第二个原因——它还没有出现——非常普遍。浏览器从上到下解析和处理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...。
解决方案
在调用getElementById
(或任何DOM方法)之前,请确保您要访问的元素存在,即DOM已加载。
这可以通过将JavaScript放置在相应的DOM元素之后来确保。
<div id="my_element"></div>
<script>
var element = document.getElementById('my_element');
</script>
如果这样,您还可以将代码放在关闭body标签(</body>
)之前(所有DOM元素都将在执行脚本时可用)。
其他解决方案包括侦听load
[MDN]或DOMContentLoaded
[MDN]事件。在这些情况下,您放置JavaScript代码的位置并不重要,您只需要记住将所有DOM处理代码放在事件处理程序中。
例如:
window.onload = function() {
};
document.addEventListener('DOMContentLoaded', function() {
});
请参阅
quirksmode.org的文章,了解有关事件处理和浏览器差异的更多信息。
jQuery
首先确保正确加载jQuery。
使用浏览器的开发者工具查找jQuery文件是否被找到,如果没有,请纠正URL(例如,在开头添加
http:
或
https:
方案,调整路径等)。
监听
load
/
DOMContentLoaded
事件正是jQuery使用
.ready()
[docs]所做的。所有影响DOM元素的jQuery代码都应该在该事件处理程序内部。
事实上,
jQuery教程明确表示:
几乎我们在使用jQuery时所做的一切都是读取或操作文档对象模型(DOM),因此我们需要确保尽早在DOM准备就绪时开始添加事件等。
To do this, we register a ready event for the document.
$(document).ready(function() {
// do stuff when DOM is ready
});
或者您也可以使用简写语法:
$(function() {
});
两者等效。
$("your_id")
。 - Post Malone