为什么 jQuery 或 getElementById 等 DOM 方法找不到该元素?

2023-11-25

可能的原因有哪些document.getElementById, $("#id")或者任何其他 DOM 方法/jQuery 选择器找不到元素?

示例问题包括:

  • jQuery 默默地无法绑定事件处理程序
  • jQuery“getter”方法(.val(), .html(), .text())返回undefined
  • 标准 DOM 方法返回null导致以下几个错误之一:

未捕获的类型错误:无法设置 null 的属性“...”
未捕获的类型错误:无法设置 null 的属性(设置“...”)
未捕获的类型错误:无法读取 null 的属性“...”
未捕获的类型错误:无法读取 null 的属性(读取“...”)

最常见的形式是:

未捕获的类型错误:无法将属性“onclick”设置为 null
未捕获的类型错误:无法读取 null 的属性“addEventListener”
未捕获的类型错误:无法读取 null 的属性“样式”


您试图查找的元素不在DOM当你的脚本运行时。

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

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

<script>
  console.log("script #1:", document.getElementById("test")); // null
</script>
<div id="test">test div</div>
<script>
  console.log("script #2:", 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:", this);
    });
  </script>
</body><!-- closing body tag -->

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


选项 2:defer属性

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

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

这意味着您可以放置​​一个标记为defer任何地方,甚至<head>,并且它应该能够访问完全实现的 DOM。

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

请记住...

  1. defer只能用于外部脚本,即:那些具有src属性。
  2. 意识到浏览器支持,即: IE

选项 3:模块

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

设置你的脚本type to module, e.g.:

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

选项 4:通过事件处理推迟

向解析文档后触发的事件添加侦听器。

DOMContentLoaded 事件

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

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

窗口:加载事件

The load事件在之后触发DOMContentLoaded并且已加载样式表和图像等其他资源。因此,它的触发时间比我们预期的要晚。不过,如果您考虑使用 IE8 等较旧的浏览器,那么支持几乎是普遍的。当然,您可能想要一个填充剂用于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>

jQuery 的ready()

DOMContentLoaded and window:load每个人都有自己的警告。 jQuery 的ready()提供混合解决方案,使用DOMContentLoaded如果可能的话,故障转移到window:load必要时,如果 DOM 已经完成,则立即触发回调。

您可以将准备好的处理程序直接传递给 jQuery,如下所示$(handler), e.g.:

<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script>
  $(function() {
    $("#test").click(function() {
      console.log("clicked:", this);
    });
  });
</script>
<button id="test">click me</button>

选项 5:活动委托

将事件处理委托给目标元素的祖先。

当一个元素引发一个事件时(假设它是一个bubbling事件并且没有任何东西阻止其传播),该元素祖先中的每个父代,一直到window,也接收该事件。这允许我们将处理程序附加到现有元素,并在事件从其后代中冒出时对事件进行采样...甚至是在附加处理程序后添加的后代中。我们所要做的就是检查事件以查看它是否是由所需元素引发的,如果是,则运行我们的代码。

通常,此模式是为加载时不存在的元素保留的,或者是为了避免附加大量重复的处理程序。为了提高效率,选择目标元素最近的可靠祖先,而不是将其附加到document.

原生 JavaScript

<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 的on()

jQuery 通过以下方式提供此功能on()。给定事件名称、所需后代的选择器和事件处理程序,它将解析您委托的事件处理并管理您的this语境:

<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 jQuery 或 getElementById 等 DOM 方法找不到该元素? 的相关文章

  • Javascript正则表达式用于字母字符和空格? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我需要一个
  • 音频 blob 的 URL.createObjectURL 在 Firefox 中给出 TypeError

    我正在尝试从创建的音频 blob 创建对象 URLgetUserMedia 该代码在 Chrome 中可以运行 但在 Firefox 中存在问题 错误 当我打电话时stopAudioRecorder 它停在audio player src
  • 使用 KnockoutJs 映射插件进行递归模板化

    我正在尝试使用以下方法在树上进行递归模板化ko映射 插入 http knockoutjs com documentation plugins mapping html 但我无法渲染它 除非我定义separate每个级别的模板 在以下情况下
  • jquery从变量中删除html元素

    我将 html 保存在变量中 var itinerary events today html 我有很多 html 和一个按钮我想删除 它的 ID 为 myButton 如何从变量中保存的 html 中删除它 我建议这种方法 var itin
  • 表单计算器脚本基本价格未加载 OnLoad

    我的表单中有一个计算器来计算我的下拉选项选择 function select calculate on change calc input type checkbox calculate on click calc function cal
  • 如何在react-native中获取Text组件的onPress值

    我是一名新的 React Native 开发人员 我想使用 onPress 获取 Text 组件的值并将其传递给函数
  • 如何使输入字段和提交按钮变灰

    我想变灰这两件事 http doorsplit heroku com 歌曲输入字段和提交按钮 直到用户输入艺术家 有没有一种简单的方法可以通过 JQuery 来做到这一点 艺术家输入字段的id是 request artist 你可以这样做
  • Firefox 书签探索未超过 Javascript 的第一级

    我已经编写了一些代码来探索我的 Firefox 书签 但我只获得了第一级书签 即我没有获得文件夹中的链接 e g 搜索引擎 雅虎网站 谷歌网站 在此示例中 我只能访问 Search engines 和 google com 不能访问 yah
  • Grails 在 javascript 内的 GSP 站点中使用 grails var

    我有一个在 GSP 文件中的 javascript 代码中使用 grails 变量值的问题 例如 我有一个会话值session getAttribute selectedValue 我想在 javascript 代码部分使用这个值 我现在的
  • 如何使用 JQuery 动态排序

    如果我有一个下拉列表和一个列表框 有没有办法使用 JQuery 根据下拉列表对列表框进行排序 举个例子会很有帮助 这会改变下拉菜单中的顺序 您必须根据自己的标准设置顺序
  • 为什么在 Internet Explorer 中访问 localStorage 对象会引发错误?

    我正在解决一个客户端问题 Modernizr 意外地没有检测到对localStorageInternet Explorer 9 中的对象 我的页面正确使用 HTML 5 文档类型 并且开发人员工具报告该页面具有 IE9 的浏览器模式和 IE
  • FireFox 中的自动滚动

    我的应用程序是实时聊天 我有一个 Div 来包装消息 每条消息都是一个 div 所以 在几条消息之后 我的 DOM 看起来像这样 div div Message number two div div div div
  • 有没有办法阻止 prettier / prettier-now 将函数参数分解为新行

    当使用 prettier prettier now 在保存时进行格式化时 当一个函数包装另一个函数时 它会中断到一个新行 我想知道是否有办法阻止这种行为 例如 期望的输出 app get campgrounds id catchAsync
  • 在 vue.js 中访问数组对象属性

    给定以下数组vue js packageMaps Object packageMap 0 Object Id 16 PackageType flag list ProductCode F BannerBase packageMap 1 Ob
  • Javascript 纪元时间(以天为单位)

    我需要以天为单位的纪元时间 迄今为止 我已经看到过有关如何翻译它的帖子 但几天后就没有了 我对纪元时间很不好 我怎么能得到这个 我需要以天为单位的纪元时间 我将解释为您想要自纪元以来的天数 纪元本身是第 0 天 或第 1 天的开始 无论您如
  • JQuery 图像上传不适用于未来的活动

    我希望我的用户可以通过帖子上传图像 因此 每个回复表单都有一个上传表单 用户可以通过单击上传按钮上传图像 然后单击提交来提交帖子 现在我的上传表单可以上传第一个回复的图像 但第二个回复的上传不起作用 我的提交过程 Ajax 在 php 提交
  • 如何仅在最后一个
  • 处给出透明六边形角度?
  • 我必须制作这样的菜单 替代文本 http shup com Shup 330421 1104422739 My Desktop png http shup com Shup 330421 1104422739 My Desktop png
  • 使用 Ajax 请求作为源数据的 Jquery 自动完成搜索

    我想做的事 我想使用 jquery 自动完成函数创建一个输入文本字段 该函数从跨域curl 请求获取源数据 结果应该与此示例完全相同 CSS 在这里并不重要 http abload de img jquerydblf5 png http a
  • 在 ASP.NET Core MVC 中访问从视图到控制器的隐藏值

    我需要帮助使用 jQuery 从 ASP NET Core razor 视图页面传递隐藏控件值 jQuery 用于获取动态控件选定的值 section scripts
  • Spring Rest 和 Jsonp

    我正在尝试让我的 Spring Rest 控制器返回jsonp但我没有快乐 如果我想返回 json 但我有返回的要求 完全相同的代码可以正常工作jsonp我添加了一个转换器 我在网上找到了用于执行 jsonp 转换的源代码 我正在使用 Sp

随机推荐