gpt4 book ai didi

javascript - 为什么jQuery或诸如getElementById之类的DOM方法找不到元素?

转载 作者:行者123 更新时间:2023-12-03 21:42:50 25 4
gpt4 key购买 nike

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

问题示例包括:

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

  • Uncaught TypeError: Cannot set property '...' of null Uncaught TypeError: Cannot read property '...' of null



    最常见的形式是:

    Uncaught TypeError: Cannot set property 'onclick' of null

    Uncaught TypeError: Cannot read property 'addEventListener' of null

    Uncaught TypeError: Cannot read property 'style' of null

    最佳答案

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

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

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

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


    那你该怎么办?您有几种选择:

    选项1:移动脚本

    在关闭body标记之前,将脚本进一步移至页面下方。以这种方式组织的文档的其余部分将在执行脚本之前进行解析:

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


    注意:将脚本放在底部通常被认为是 best practice

    选项2:jQuery的 ready()
    使用 $(handler) 将脚本推迟到完全解析DOM为止:

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


    注意:您可以简单地绑定(bind)到 DOMContentLoaded window.onload,但是每个都有其警告。 jQuery的 ready() 提供了一种混合解决方案。

    选项3:事件委派

    Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.



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

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

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


    注意:通常,此模式是为加载时不存在的元素保留的,或避免附加大量处理程序。值得指出的是,虽然我已经将处理程序附加到 document(出于演示目的),但是您应该选择最近的可靠祖先。

    选项4: defer属性

    使用 defer <script> 属性。

    [defer, a Boolean attribute,] is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.



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


    作为引用,下面是 external script的代码:
    document.getElementById("test").addEventListener("click", function(e){
    console.log("clicked: %o", this);
    });

    注意: defer属性看起来确实像是魔术子弹,但请注意警告很重要...
    1. defer仅可用于外部脚本,即具有 src属性的脚本。
    2.注意 browser support,即:IE <10中的错误实现

    关于javascript - 为什么jQuery或诸如getElementById之类的DOM方法找不到元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8716655/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com