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

2024-03-02

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

示例问题包括:

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

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

最常见的形式是:

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


您试图查找的元素不在DOM https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model当你的脚本运行时。

依赖 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:移动脚本

鉴于我们在上面的示例中看到的情况,一个直观的解决方案可能是简单地将脚本沿着标记向下移动,越过您想要访问的元素。事实上,很长一段时间,将脚本放在页面底部被认为是一种最佳实践 https://developer.yahoo.com/performance/rules.html#js_bottom由于各种原因。以这种方式组织,在执行脚本之前将解析文档的其余部分:

<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 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer属性。

[defer,一个布尔属性,] 设置为向浏览器指示该脚本应在解析文档之后但在触发之前执行DOMContentLoaded https://developer.mozilla.org/en-US/docs/web/api/window/domcontentloaded_event.

这意味着您可以放置​​一个标记为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. 意识到浏览器支持 https://caniuse.com/script-defer,即: IE

选项 3:模块

根据您的要求,您也许可以使用JavaScript 模块 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#applying_the_module_to_your_html。与标准脚本的其他重要区别包括(此处注明 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#other_differences_between_modules_and_standard_scripts),模块会自动延迟,并且不限于外部源。

设置你的脚本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 https://developer.mozilla.org/en-US/docs/web/api/window/domcontentloaded_event在 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 https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event事件在之后触发DOMContentLoaded并且已加载样式表和图像等其他资源。因此,它的触发时间比我们预期的要晚。不过,如果您考虑使用 IE8 等较旧的浏览器,那么支持几乎是普遍的。当然,您可能想要一个填充剂用于addEventListener() https://vanillajstoolkit.com/polyfills/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() https://api.jquery.com/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 https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-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() https://api.jquery.com/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 方法找不到该元素? 的相关文章

  • 确定用户是否在shadow dom之外单击

    我正在尝试实现一个下拉菜单 您可以单击外部将其关闭 下拉列表是自定义日期输入的一部分 并且封装在输入的影子 DOM 内 我想写一些类似的东西 window addEventListener mousedown function evt if
  • Bootstrap shown.bs.tab 事件不起作用

    我正在使用灵活的模板 http the8guild com themes html flexy v1 7 stylesPage html 使用引导程序 并且我无法让选项卡上的 shown bs tab 事件正常工作 我已经成功让它发挥作用J
  • 如何将多个文件上传到Firebase?

    有没有办法将多个文件上传到 Firebase 存储 它可以在一次尝试内上传单个文件 如下所示 fileButton addEventListener change function e Get file var file e target
  • Node.js 循环发送 http 请求

    我实际上遇到了使用 node js 执行的 javascript 代码的问题 我需要循环发送http请求到远程服务器 我在代码中设置了www google ca 这是我的代码 var http require http var option
  • 如何使用 Selenium webdriver 测试对 SVG 对象的点击?

    我正在尝试编写代码来检查单击 SVG 对象的功能 例如此 URL 上的美国州 http www amcharts com svg maps map usa 这可行 但是有更好的方法吗 不需要物理移动鼠标的东西 robert new Robo
  • 如何在正则表达式中区分数字和ip地址?

    例如 如果我们查看 5 56 和 183 55 0 144 基本上 当你做这样的事情时 d d 它匹配 5 56 189 55 和 0 144 有没有办法通过正则表达式仅匹配数字而不匹配 ip 地址的部分 我尝试使用前瞻 但我不知道它应该是
  • Java:从 ScriptEngine javascript 返回一个对象

    我正在尝试使用 Java 来评估 javascript脚本引擎 https docs oracle com javase 7 docs api javax script ScriptEngine html班级 这是我正在尝试做的事情的一个简
  • 如何使用 ui-router 中的 ui-sref 将参数传递给控制器

    我需要传递和接收两个参数到我想要转换到的状态ui srefui router 的 例如使用下面的链接将状态转换为home with foo and bar参数 a Go to home state with foo and bar para
  • Puppeteer 无法在 VPS (DigitalOcean) 上工作

    我在水滴中数字海洋 https www digitalocean com 我收到这个错误 node 5549 UnhandledPromiseRejectionWarning TimeoutError Navigation Timeout
  • 输入和文本区域可以拖动吗?

    MDN 规范以及我能通过 Google 找到的每个网站都说所有 HTML 元素都可以拖动 然而 在实践中 我发现我无法拖动文本输入或文本区域 即使它们已被禁用 例如 使用以下代码 img src http www placehold it
  • Chrome:window.print() 打印对话框仅在页面重新加载后打开 (javascript)

    我面临着一个非常奇怪的问题 我正在从 javascript 文件调用 window print 这在 Safari IE Firefox 中运行良好 直到两小时前 它在 Chrome 中也运行良好 版本29 0 1547 57 我没有更改我
  • 通过ajax POST提交两次表单

    插入到mysql using php通过文件调用AJAX 前insert语句php代码执行select查询到查找重复记录并继续insert statement Issue 从ajax调用php文件时 它执行了两次并得到作为重复记录的响应 好
  • 字母数字验证在 jquery 中不起作用

    我的代码如下 包含所有必需的js文件 当我提交表单而不为 UserDetailAliasName 提供任何值时 表单不会提交并显示验证错误消息 此字段是必需的 但是如果我提交像 等值 表单会提交数据 我使用此表单从数据库搜索用户名 docu
  • 使用 Lodash 循环 JavaScript 对象中的属性

    是否可以循环访问 JavaScript 对象中的属性 例如 我有一个 JavaScript 对象定义如下 myObject options property1 value 1 property2 value 2 属性将动态添加到该对象 有没
  • 关于 Node.js Promise then 和 return?

    我对承诺感到困惑 I use 那么就答应没有返回像这样 new Promise resolve reject gt resolve 1 then v1 gt console log v1 new Promise resolve reject
  • 如何使用正则表达式解析 OCC 选项符号?

    OCC 选项符号由 4 部分组成 标的股票或 ETF 的根代码 用空格填充至 6 个字符 到期日期 6 位数字 格式为 yymmdd 期权类型 P 或 C 用于看跌或看涨期权 执行价格 为价格 x 1000 前面填充 0 至 8 位数字 举
  • 如何设置 .eslintrc 来识别“require”?

    我是新来的ESLint http eslint org 并且我已经成功地将 ESLint 与IntelliJ https www jetbrains com idea 开箱即用 我的 ESLint 集成无法识别node 但对文档的基本审查表
  • 为什么 JavaScript 默认导出不可用?

    为什么默认导出不像命名导出那样实时 lib js export let counter 0 export function incCounter counter export default counter main1 js import
  • 在第一页加载时触发 jquery 脚本,然后不再为该用户触发?

    我在我的网站上使用这个 jQuery 模态窗口脚本 http www zurb com playground reveal modal plugin http www zurb com playground reveal modal plu
  • 限制在三角形内

    我正在寻找一段通用代码 javascript 它可以与 jquery UI 一起使用来限制三角形内 div 的移动 拖动 与此类似 http stackoverflow com questions 8515900 how to constr

随机推荐

  • 抓取文本然后将该文本提交到特定路径

    我想做的是抓取文本 然后将该文本提交到接受表单输入 name mykeyword 的特定应用程序路径 并且我也希望在浏览器的新选项卡中打开它 我做了一些练习 但没有运气 任何想法 ScanTitle click function var m
  • 拦截html按钮点击

    当用户点击 html 按钮时是否有可能拦截 我有一个 webviewclient 它加载带有两个按钮的登录页面 允许和拒绝 我希望您在按下拒绝按钮时进行拦截 拒绝和允许具有相同的 basUrl 和 js 执行正确的重定向 提前致谢 您可能不
  • 在 javascript 中的对象数组中搜索深度嵌套的值

    我基本上试图实现对任何给定值的搜索应该在对象键值数组中查找 也可以是嵌套对象 这是一个例子 下面的函数将采用一个对象和一个查询来搜索数组对象键值 因此 如果找到匹配项 它应该从该数组中进行过滤 function searchObj obj
  • 如何用圆圈替换光标,而不是在 p5.js 中将其绘制到画布上?

    问题 我正在尝试使用 p5 js 创建一个简单的绘图应用程序 我想在光标位置显示一个代表画笔大小的圆圈 而不是标准光标图像 可能的解决方案1 使用替换光标cursor p5 的原生函数 为什么它不起作用 The p5光标功能 https p
  • 使用 JavaScript 提交具有新值的表单。 (MVC)

    给定一个包含以下元素的表单
  • MacOS:ModuleNotFoundError:没有名为“_ctypes”的模块

    我在 pyenv 环境中使用 python 和 pip 但是当我尝试使用 pip 安装 numpy 时 pip install numpy 我收到以下错误 有人知道我哪里出错了吗 使用缓存的 numpy 1 21 0 zip 收集 nump
  • 获取共享缓存的逻辑 CPU 核心数(L1、L2、L3)

    下面是一些 C 代码 它使用以下命令检测 Windows 上 L1 L2 和 L3 CPU 缓存的大小 typedef BOOL WINAPI LPFN GLPI PSYSTEM LOGICAL PROCESSOR INFORMATION
  • 错误:使用未分配的局部变量(对于字符串数组)

    我正在从 App config 文件中读取连接字符串 为此我有以下代码 try string dbnames int counter 0 foreach ConnectionStringSettings connSettings in Co
  • 三.JSL:加载Blender模型需要本地服务器吗?

    我正在使用 Three js 开发基于 Web 的 3D WebGL 应用程序 我正在尝试使用以下代码加载 Blender 模型 JS 文件 var loader new THREE JSONLoader var jsonLoader ne
  • SQLAlchemy 在同一事务中删除和插入

    我正在使用 SQLAlchemy 并在一个事务中 我想要执行以下操作 删除满足特定条件的所有记录 假设这是Cars color red 现在 我想插入满足特定条件的所有汽车 例如Cars type Honda 现在假设我的数据库只是一个包含
  • 如何调试 SwiftUI AttributeGraph 循环警告?

    我在使用 SwiftUI 的应用程序中收到很多 AttributeGraph 循环警告 有什么方法可以调试导致它的原因吗 这是控制台中显示的内容 AttributeGraph cycle detected through attribute
  • 创建一个通用 Swift 函数以返回 Core Data 实体数组

    警告 我对 Swift 和 Core Data 还很陌生 我的代码中有几个函数返回特定实体类型的数组 func fetchStores gt Store var stores Store let fetchRequest NSFetchRe
  • TypeScript:导入的模块类不可见

    我正在使用多个模块测试打字稿编译器 这些模块将被编译为 AMD 模块 我有一个模块 测试 和一个将使用它的单独文件 test ts export module test use strict export class Person age
  • 相交的矩形

    这是一个分析几何类型的问题 我不确定我可以将其发布在这里 但是我必须想出一个 Java 函数来执行此功能 我在页面 swing 容器中有多个矩形 我知道现在我需要找到哪些矩形彼此相交 这里的一件好事是相交的矩形将始终具有相同的 y 分量 并
  • SQL 选择一列中具有重复值的所有行

    我有一个users中包含重复值的表employee id柱子 我需要列出具有重复的employee ids 的所有行及其姓名 我需要查看所有具有重复项的用户employee id这样我就可以消除哪些值是有效的冲突 SELECT name e
  • Windows Phone Silverlight 8.1 不支持 Windows.UI.Notifications.ToastNotification API?

    我正在尝试验证我的应用程序 但出现以下错误 发现错误 支持的 API 测试检测到以下错误 This API is not supported for this application type Api Windows UI Notifica
  • 需要帮助以更有效的方式设计搜索算法

    我有一个涉及生物领域的问题 现在我有4个非常大的文件 每个有1亿行 但结构相当简单 这些文件的每一行只有2个字段 都代表一种基因 我的目标是 设计一种有效的算法 可以实现以下目标 在这 4 个文件的内容中找到一个圆圈 圆定义为 field
  • 解读 C++ 模板错误消息

    当人们说 C 的错误消息对于模板来说非常糟糕时 我真的开始理解他们的意思了 对于像函数与其原型不匹配这样简单的事情 我见过可怕的长错误 有什么技巧可以破译这些错误吗 编辑 我同时使用 gcc 和 MSVC 他们俩看起来都非常可怕 您可以尝试
  • 如何从闭包内部修改在闭包外部定义的变量?

    如何从闭包内部修改在闭包外部定义的变量 Code fn main let mut t foo to string println t let mut closure t clear closure println t 编译错误 cannot
  • 为什么 jQuery 或 getElementById 等 DOM 方法找不到该元素?

    可能的原因有哪些document getElementById id 或者任何其他 DOM 方法 jQuery 选择器找不到元素 示例问题包括 jQuery 默默地无法绑定事件处理程序 jQuery getter 方法 val html t