为什么jQuery或像getElementById这样的DOM方法找不到元素? JavaScript闭包如何工作? 客户端和服务器端编程有什么区别? 为什么jQuery或像getElementById这样的DOM方法找不到元素? 当您的脚本运行时,您尝试查找的元素不在DOM中。 DOM依赖脚本的位置会对其行为产生深远影响。浏览器从上到下解析HTML文档。元素被添加到DOM中,脚本(通常)会在遇到它们时执行。这意味着订单很重要。通常,脚本无法找到稍后出现在标记中的元素,因为这些元素尚未添加到DOM中。 考虑以下标记; 脚本#1无法找到<div>而脚本#2成功: <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> 那你该怎么办?你有几个选择: 选项1:移动脚本 将您的脚本向下移动到页面上,就在关闭正文标记之前。以这种方式组织,在脚本执行之前解析文档的其余部分: <body> <button id="test">click me</button> <script> document.getElementById("test").addEventListener("click", function() { console.log("clicked: %o", this); }); </script> </body><!-- closing body tag --> 选项2:jQuery ready() 推迟脚本,直到完全解析DOM,使用ready(): <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script> $(document).ready(function() { $("#test").click(function() { console.log("clicked: %o", this); }); }); </script> <button id="test">click me</button> 选项3:事件委派 当一个元素引发一个事件时(假设它是一个冒泡事件并且没有任何东西停止它的传播),该元素的祖先中的每个父元素也会接收该事件。这允许我们将一个处理程序附加到现有元素,并在事件从其后代冒泡时对它们进行冒泡...甚至是在附加处理程序之后添加的事件。我们所要做的就是检查事件以查看它是否由所需元素引发,如果是,则运行我们的代码。 jQuery on()为我们执行逻辑。我们只提供一个事件名称,所需后代的选择器和一个事件处理程序: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script> $(document).on("click", "#test", function(e) { console.log("clicked: %o", this); }); </script> <button id="test">click me</button> 选项4:defer属性 使用<script>的defer属性。 <script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script> <button id="test">click me</button> JavaScript闭包如何工作? 客户端和服务器端编程有什么区别?