Why does jQuery or a DOM method such as getElementById not find the element?(为什么jQuery或诸如getElementById之类的DOM方法找不到元素?)

本文介绍了为什么jQuery或诸如getElementById之类的DOM方法找不到元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

示例问题包括:

  • jQuery 静默地绑定事件处理程序失败
  • jQuerygetter"方法(.val().html().text())返回 undefined
  • 返回 null 的标准 DOM 方法会导致以下几种错误:
<块引用>

未捕获的类型错误:无法设置属性 '...' of null
未捕获的 TypeError:无法设置 null 的属性(设置...")
未捕获的类型错误:无法读取 null
的属性..."未捕获的类型错误:无法读取 null 的属性(正在读取 '...')

最常见的形式是:

<块引用>

未捕获的类型错误:无法设置属性 'onclick' of null
未捕获的类型错误:无法读取 null
的属性addEventListener"未捕获的类型错误:无法读取 null 的属性样式"

解决方案

您尝试查找的元素不在 DOM.

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

考虑以下标记;脚本 #1 找不到 <div> 而脚本 #2 成功:

<script>console.log("脚本 #1:", document.getElementById("test"));//空值</脚本><div id="test">测试div</div><脚本>console.log("脚本 #2:", document.getElementById("test"));//<div id="测试" ...</script>

那么,你应该怎么做?你有几个选择:

<小时>

选项 1:移动脚本

鉴于我们在上面的示例中看到的情况,一个直观的解决方案可能是简单地将您的脚本移到标记下方,越过您想要访问的元素.事实上,长期以来,将脚本放在页面底部被认为是 最佳实践 出于各种原因.以这种方式组织,将在执行脚本之前解析文档的其余部分:

<body><button id="test">点我</button><脚本>document.getElementById("test").addEventListener("click", function() {console.log("点击:", this);});</脚本></body><!-- 结束正文标签-->

虽然这是有道理的,并且是旧版浏览器的可靠选择,但它是有限的,并且有更灵活、更现代的方法可用.

<小时>

选项 2:defer 属性

虽然我们确实说过脚本是,(通常)在遇到它们时执行,"现代浏览器允许您指定不同的行为.如果您要链接外部脚本,则可以使用 defer 属性.

<块引用>

[defer,一个布尔属性,] 被设置为向浏览器指示脚本是在文档被解析之后,但在触发 DOMContentLoaded.

这意味着您可以将带有 defer 标记的脚本放置在任何地方,甚至是 <head>,并且它应该可以访问完全实现的 DOM.p>

<script src="https://gh-canon.github.io/misc-demos/log-test-click.js"延迟></脚本><button id="test">点我</button>

请记住...

  1. defer 只能用于外部脚本,即:具有 src 属性的脚本.
  2. 注意浏览器支持,即:IE 中的错误实现 <10

<小时>

选项 3:模块

根据您的要求,您可以使用 JavaScript 模块.与标准脚本的其他重要区别(在此注明),模块会自动延迟,并且不限于外部源.

将脚本的type设置为module,例如:

<script type="module">document.getElementById("test").addEventListener("click", function(e) {console.log("点击:", this);});</脚本><button id="test">点我</button>

<小时>

选项 4:延迟事件处理

为在您的文档被解析后触发的事件添加一个监听器.

DOMContentLoaded事件

DOMContentLoaded在从初始解析完全构建 DOM 后触发,无需等待样式表或图像等内容加载.

<script>document.addEventListener("DOMContentLoaded", function(e){document.getElementById("test").addEventListener("click", function(e) {console.log("点击:", this);});});</脚本><button id="test">点我</button>

窗口:加载事件

加载 事件在 DOMContentLoaded 和其他资源(如样式表和图像)已加载后触发.出于这个原因,它的触发时间比我们预期的要晚.不过,如果您正在考虑使用 IE8 等较旧的浏览器,则支持几乎是普遍的.当然,您可能需要 polyfill 用于 addEventListener().

<script>window.addEventListener("加载", function(e){document.getElementById("test").addEventListener("click", function(e) {console.log("点击:", this);});});</脚本><button id="test">点我</button>

原生JavaScript

<div id="ancestor"><!-- 我们脚本可用的最近祖先 --><脚本>document.getElementById("ancestor").addEventListener("click", function(e) {如果(e.target.id ===后代"){console.log("点击:", e.target);}});</脚本><button id="descendant">点我</button></div>

DOMContentLoadedevent

DOMContentLoaded fires after the DOM has been completely constructed from the initial parse, without waiting for things like stylesheets or images to load.

<script>
  document.addEventListener("DOMContentLoaded", function(e){
    document.getElementById("test").addEventListener("click", function(e) {
      console.log("clicked:", this);
    });
  });
</script>
<button id="test">click me</button>

Window:loadevent

The load event fires after DOMContentLoaded and additional resources like stylesheets and images have been loaded. For that reason, it fires later than desired for our purposes. Still, if you're considering older browsers like IE8, the support is nearly universal. Granted, you may want a polyfill for addEventListener().

<script>
  window.addEventListener("load", function(e){
    document.getElementById("test").addEventListener("click", function(e) {
      console.log("clicked:", this);
    });
  });
</script>
<button id="test">click me</button>

NativeJavaScript

<div id="ancestor"><!-- nearest ancestor available to our script -->
  <script>
    document.getElementById("ancestor").addEventListener("click", function(e) {
      if (e.target.id === "descendant") {
        console.log("clicked:", e.target);
      }
    });
  </script>
  <button id="descendant">click me</button>
</div>

jQuery's on()

jQuery makes this functionality available through on(). Given an event name, a selector for the desired descendant, and an event handler, it will resolve your delegated event handling and manage your this context:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ancestor"><!-- nearest ancestor available to our script -->
  <script>
    $("#ancestor").on("click", "#descendant", function(e) {
      console.log("clicked:", this);
    });
  </script>
  <button id="descendant">click me</button>
</div>

这篇关于为什么jQuery或诸如getElementById之类的DOM方法找不到元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!