为什么 jQuery 或诸如 getElementById 之类的 DOM 方法找不到该元素?
技术问答
267 人阅读
|
0 人回复
|
2023-09-12
|
可能的原因是什么?document.getElementById,$("#id")或任何其他DOM方法/ jQuery选择未找到的元素?1 m2 a6 O# y( D) V: q' @' p/ e
示例问题包括:! A' u0 O/ U: L& ` }& b) U
jQuery 无声无法绑定事件处理程序* V- B7 @1 b1 k' A6 S: W
jQuery吸气方法(.val(),.html(),.text())返回undefined
; Y4 g- V3 c2 V+ S V: I返回标准 DOM 方法会null导致以下任何错误:遗漏类型错误:无效不能设置属性…”
$ [( b0 D0 B; S5 _遗漏类型错误:不能设置为空属性(设置…‘)
y' ]" ^; U3 E% A% M7 a9 J遗漏类型错误:不能读取空财产’…”
7 l, z1 E+ _( G1 S) p0 e4 p9 V遗漏类型错误:空的不能读取性能(阅读 ‘…’)
( l' _7 F2 ?% b" k7 ?& v& d最常见的形式是:3 ?7 D4 T! ?, v& h/ K) _7 u) V. U
未捕获的类型错误无法设置 null 的属性“onclick”; h+ j* u) b; z
未捕获的类型错误无法读取 null 的属性“addEventListener”
# {8 R# u# N, ~ W未捕获的类型错误无法读取 null 属性风格
: U) ^, y: p- V4 O 1 K+ a6 n4 M& p+ ]
解决方案:
6 j) o0 k& N7 p% l* N8 R4 _9 r- M 当你的脚本运行时,你试图找到的元素不在DOM 中。* \: q, N O( D
依赖 DOM 脚本的位置会对其行为产生深远的影响。浏览器从上到下分析 HTML 文档。在 文档中添加元素。DOM 脚本(通常)在遇到它们时执行。这意味着顺序很重要。通常,脚本找不到标记后面的元素,因为这些元素还没有添加到 DOM 中。' Q& d# o, w5 `7 C3 \
考虑以下标记, 脚本#1 无法找到而脚本 #2 成功:
( g& h: T4 H( x" G& a* y6 jtest div& d! M# S$ z8 x& c& X/ u8 @# X
那你该怎么办?你有几个选择:
. N3 r$ D* o0 r( y; w选项 1:移动脚本鉴于我们在上面的例子中看到的内容,一个直观的解决方案可能是简单地标记你的脚本向下移动,超过你想要访问的元素。事实上,长期以来,由于各种原因,将脚本放在页面底部被认为是最好的实践。这样,文档的其他部分将在执行脚本之前进行分析:
7 R% R+ ~! U8 ^, m click me
0 V0 Q9 x8 a/ a6 @3 T( \8 f 虽然这是合理的,也是旧浏览器的可靠选择,但它有限,有更灵活、更现代的方法。# d- H% u% B$ T( g
选项 2:defer属性虽然我们确实说过脚本(通常)在遇到它们时执行现代浏览器允许您指定不同的行为。如果要链接外部脚本,可以使用defer属性。
) |# w/ B7 T; m0 q4 h3 m: Q/ y* P+ o. P[ defer,一个布尔属性, 设置为向浏览器指示脚本,将在文档分析但触发前执行DOMContentLoaded。" s) U; W5 q4 m/ K
这意味着你可以把带标记的脚本放在上面defer任何地方,甚至是,它应该能够访问完全实现的 DOM。( a8 w& J# h7 l. D4 T) [# i
click me
6 n, h7 I) _+ s" ] 只要记住…) q' C# k5 s6 ^- V5 T* U8 h
[ol]defer只能用于外部脚本,即:有src属性脚本。, d* O( Z: Z* N( o3 C6 Z
注意浏览器支持,即:IE [/ol]3:模块可根据您的要求使用JavaScript 模块。模块自动延迟,不限于外部源,除了与标准脚本(此处指出)的其他重要区别。
$ s2 V1 L G5 O设置你的脚本type为module,例如:
5 p1 ]4 S- N2 h) l3 L, t3 nclick me& G' {6 r v, }0 B
选项 4:延迟事件处理将侦听器添加到解析文档后触发的事件中。
# o! X) J' h* V- a7 @8 }DOMContentLoaded 事件DOMContentLoaded DOM 触发后,无需等待加载样式表或图像。
1 j; f) E, ~ D8 B窗口:加载事件该load事件在DOMContentLoaded加载样式表、图像等其他资源后触发。因此,它比我们的目的触发得晚。尽管如此,如果你正在考虑使用 IE8 等旧浏览器,支持几乎很常见。当然,你可能需要一个polyfill foraddEventListener() .! G, x5 y2 T+ F6 s- x& H
click me, f3 {4 C$ p8 ^ K$ h
jQuery的 ready()DOMContentLoaded并且window:load各有各的注意事项。jQueryready()提供了一种混合解决方案,DOMContentLoaded在可能的情况下使用,window:load如果 DOM 已完成,立即触发其回调。
8 ~$ V9 d( L9 z1 l( h- h( D8 r0 `您可以直接将准备好的处理程序传递给 jQuery ,例如:$(*handler*)' T$ ~" v! s( G1 _2 ]
click me
; z( }" V8 l( P/ t1 b# z 选项 5:事件委托将事件处理委托给目标元素的祖先。* \3 v/ T+ K: F* `
当一个元素引发一个事件(假设是冒泡事件,没有什么能阻止它的传播)时,这个元素祖先中的每一个父元素,直到window,这个事件也会收到。这允许我们将处理程序添加到现有元素中,并在事件从后代冒泡时采样事件。......即使是在附加处理程序之后添加的后代。我们所要做的就是检查事件是否是由所需元素引起的,如果是,则操作我们的代码。
5 T' p+ h1 F$ M) a5 }3 a通常,该模型是为了保留加载过程中不存在的元素,或避免添加大量重复的处理程序。为了提高效率,选择最近可靠的祖先,而不是添加到目标元素中document。* D K. h) t7 N2 ]
原生 JavaScript click me
' k$ H! |. a6 W2 O: O jQuery的 on()jQuery 通过on(). 给出事件名称、所需后代的选择器和事件处理程序,它将分析您委托的事件处理并管理您this上下文:" m" U6 v8 H' t
click me. X" @5 m6 ~" v+ Y! _* z
|
|
|
|
|
|