简单地说:因为您要查找的元素(目前)还不存在于文档中。
对于这个答案的其余部分,我将使用getElementById作为示例,但同样适用于getElementsByTagName、querySelector和任何其他选择元素的DOM方法。
可能的原因
一个元素不存在的原因有三个:
An element with the passed ID really does not exist in the document. You should double check that the ID you pass to getElementById really matches an ID of an existing element in the (generated) HTML and that you have not misspelled the ID (IDs are case-sensitive!).
If you're using getElementById, be sure you're only giving the ID of the element (e.g., document.getElemntById("the-id")). If you're using a method that accepts a CSS selector (like querySelector), be sure you're including the # before the ID to indicate you're looking for an ID (e.g., document.querySelector("#the-id")). You must not use the # with getElementById, and must use it with querySelector and similar. Also note that if the ID has characters in it that aren't valid in CSS identifiers (such as a .; id attributes containing . characters are poor practice, but valid), you have to escape those when using querySelector (document.querySelector("#the\\.id"))) but not when using getElementById (document.getElementById("the.id")).
The element does not exist at the moment you call getElementById.
The element isn't in the document you're querying even though you can see it on the page, because it's in an iframe (which is its own document). Elements in iframes aren't searched when you search the document that contains them.
如果问题是原因3(它在iframe或类似文件中),则需要查看iframe中的文档,而不是父文档,方法可能是获取iframe元素并使用其contentDocument属性访问其文档(仅同源)。这个答案的其余部分解决了前两个原因。
第二个原因——目前还没有——很常见。浏览器从上到下解析和处理HTML。这意味着在HTML中出现DOM元素之前对DOM元素的任何调用都将失败。
考虑下面的例子:
<script>
var element = document.getElementById('my_element');
</script>
<div id="my_element"></div>
div出现在脚本之后。在脚本执行时,元素还不存在,getElementById将返回null。
jQuery
这同样适用于jQuery的所有选择器。如果你的选择器拼写错误,或者你试图在元素实际存在之前选择它们,jQuery将无法找到它们。
一个额外的扭曲是,当你没有找到jQuery,因为你已经加载了脚本没有协议,并从文件系统运行:
<script src="//somecdn.somewhere.com/jquery.min.js"></script>
此语法用于允许脚本在协议为https://的页面上通过HTTPS加载,并在协议为http://的页面上加载HTTP版本
它有一个不幸的副作用,试图加载文件失败://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() {
// 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准备好,我们就开始添加事件等。
为此,我们为文档注册一个就绪事件。
$(文档)时函数(){
// do stuff when DOM is ready
});
或者你也可以使用简写语法:
$(function() {
// do stuff when DOM is ready
});
两者是等价的。