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

你的js脚本位置可以对页面行为产生深远的影响。浏览器从上到下解析HTML文档。这意味着顺序很重要。通常,由于某些元素尚未添加到DOM中,脚本无法在html中找到稍后出现的元素。

参考下面示例:脚本1无法找到class为test的<div>,所以执行失败,返回null,脚本2成功找到class为test的<div>

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

通常有以下几种方法解决jQuery $("#id")或者getElementById没有找到元素:

 

1.移动脚本

将你的js脚本移动到页面底部</body>标签之前。以这种方式组织,文档的其余部分在您的脚本执行之前被解析:

<body>
  <button id=\"test\">click me</button>
  < >
    document.getElementById(\"test\").addEventListener(\"click\", function() {
      console.log(\"clicked: %o\", this);
    });
  </ >
</body><!-- closing body tag -->

 

2.使用jquery的ready()

使用ready()延迟脚本执行直到DOM完全解析:

<  src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"></ >
< >
  $(document).ready(function() {
    $(\"#test\").click(function() {
      console.log(\"clicked: %o\", this);
    });
  });
</ >
<button id=\"test\">click me</button>

 

3.事件委托

委托事件的优点在于,它们可以处理后来添加到文档中的后代元素的事件。

当一个元素引发事件(前提是它是一个冒泡事件,并且没有停止其传播),该元素的祖先中的每个父进程也接收该事件。这允许我们将一个处理程序附加到一个现有的元素,并且在它们从后代中冒出来的样本事件时,甚至在处理程序被附加后添加的事件。我们所要做的就是检查事件是否被所需的元素引发,如果是,请运行我们的代码。

jQuery on()为我们执行这个逻辑。我们只提供一个事件名称,一个选择器为所需的后代和一个事件处理程序:

<  src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"></ >
< >
  $(document).on(\"click\", \"#test\", function(e) {
    console.log(\"clicked: %o\",  this);
  });
</ >
<button id=\"test\">click me</button>

注意:通常,此模式是为加载时不存在的元素保留的,或者避免附加大量处理程序。还有一点值得指出的是,当我们附加一个处理程序document(为了说明的目的),你应该选择最近的可靠的祖先。

 

4.defer属性

使用js的defer属性。

defer,一个布尔属性]被设置为向浏览器指示在解析文档之后该脚本将被执行。

<  src=\"https://gh-canon.github.io/misc-demos/log-test-click.js\" defer></ >
<button id=\"test\">click me</button>

以上 是来自外部脚本。

document.getElementById(\"test\").addEventListener(\"click\", function(e){
   console.log(\"clicked: %o\", this); 
});

注意:该defer属性当然看起来像一个魔法子弹,但重要的是要注意注意以下两点
1. defer只能用于外部脚本,即具有src属性的脚本。
2.注意浏览器支持,即IE <10中会出现错误

收藏 打印