【问题标题】:What is a better way to handle document.getElementById throwing nullreference error处理 document.getElementById 抛出 nullreference 错误的更好方法是什么
【发布时间】:2021-08-07 12:32:14
【问题描述】:

我尝试从 html 中获取一些可能存在或不存在的元素。现在,如果我只是尝试

//previous code
document.getElementById("MyElement1").checked = false;
document.getElementById("MyElement2").checked = false;
...
//rest of the code

如果其中一个元素不存在,则其余代码将不会被执行。

我会做的

try {
   document.getElementById("MyElement1").checked = false;
   document.getElementById("MyElement2").checked = false;
   ...
} catch (e) {
   console.log(e);
}

但据说你永远不应该使用 try...catch 来处理非严重错误。

如果其中一个元素不存在,是否有更优雅的方式让 javascript 忽略这行代码?

PS:如果这些元素之一不存在,则以下元素也不存在。因此,如果MyElement1 存在,而MyElement2 不存在,那么MyElement3MyElement4 等也将不存在。

我还尽量避免使用大块代码,例如对这些元素中的每一个都使用 if

【问题讨论】:

  • 你听说过 if 函数吗?只需检查元素是否存在 if(document.getElementById("MyElement1")) { document.getElementById("MyElement1").checked = false; }
  • 这是一种不太优雅的解决方法
  • 确保您的代码仅适用于存在的元素?我不确定你在这里想要什么样的优雅 - 问题是你试图与不存在的 DOM 交互(还没有?),所以......为什么要这样做?如果 DOM 存在,那么试图防止错误只是意味着您的代码中仍然存在问题 - 它不工作。充其量你让它不会抛出错误,但仍然没有做你想做的事。
  • 您似乎根本不需要 ID。只需选中您的复选框并与页面上 的复选框进行交互:document.querySelectorAll("input[type='checkbox']").forEach(input => { /* do stuff */})
  • 首先将所有的日子归为一个类,然后用另一个类标记过去的日子,并使用querySelectorAll收集所有有day类但没有过去类的元素。如果页面上没有特定元素,则根本不会收集它,不需要ids。

标签: javascript


【解决方案1】:

if 语句的种类

document.getElementById("MyElement1") && (document.getElementById("MyElement1").checked = false);

如果元素存在,则document.getElementById("MyElement1")会因为&&条件而为真,只有元素存在时JS才会执行赋值。

【讨论】:

    【解决方案2】:

    使用条件可能会为您解决问题。如果 MyElement 存在,这个 sn-p 会更改它的检查值,如果它不存在,它会更改一个虚拟对象的值。

    (document.getElementById("MyElement") || {}).checked = false

    function check(value)
    {
      (document.getElementById("MyElement") || {}).checked = value;
      (document.getElementById("MyElement2") || {}).checked = value; // Doesn't exist but is OK
    }
    <input type="checkbox" id="MyElement" value="1"></input>
    <input type="button" onclick="check(true)" value="Check it"></input>
    <input type="button" onclick="check(false)" value="Uncheck it"></input>

    【讨论】:

      【解决方案3】:

      如果我是你,我会这样做:

      1. 为所有元素添加一个通用类名(比如 myElement)。
      2. 使用 document.getElementsByClassName 一次性检索所有元素。
      3. 迭代它们以设置返回元素的检查值

      解决方案类似于以下:

      //previous code
      const els = document.getElementByClassName("myElement");
      Array.from(els).forEach((el) => { el.checked = false; });
      ...
      //rest of the code

      【讨论】:

      • Good to know 关于迭代实时集合,我推荐querySelectorAll 而不是getElementsByClassName
      • @Teemu 我不会反对你的!感谢您的评论。虽然两种方式都有效!
      【解决方案4】:

      我不知道这是否是最好的方法。 但是,我会这样处理。

      <div id="example">
       <span>I exist</span>
      </div>
      
      <div id="result">
       No result yet.
      </div>
      <div id="result2">
       No result2 yet.
      </div>
      
      
      function isInPage(node) {
        return (node === document.body) ? false : document.body.contains(node);
      }
      let result = document.getElementById('result')
      let result2 = document.getElementById('result2')
      
      const test = document.getElementById('example')
      const hello = document.getElementById('hello')
      result.innerText = isInPage(test)
      result2.innerText = isInPage(hello)
      console.log(isInPage(test))
      

      在此处阅读有关 API 的更多信息

      【讨论】:

        【解决方案5】:

        我不认为try catch有什么问题,它是标准方法之一,用它来应用逻辑是没有坏处的。

        【讨论】:

        • 你不应该使用try/catch作为流量控制。是为了处理问题。如果你有一个持续的问题,那么try/catch-ing 这不是一个解决方案。如果您无法对错误做出任何反应,请不要try
        • 如果我们需要创建一个接收二维数组作为参数的方法,并打印出它的元素,那么我认为使用 try 和 catch 没有任何害处。在这种方法中可以使用无限循环,当在特定位置没有元素时,尝试打印它会抛出异常,我们可以通过中断循环在 catch 块中处理该异常
        • 因为数组的维度并没有显式地作为参数传入方法,而且无论如何除非有任何性能或效率问题,我不认为使用任何类型的逻辑会令人反感
        • 那...听起来像可怕的实现。二维数组的无限循环?我们可以非常自信地只对现有索引进行迭代。三个简单快速的实现:onetwothree。即使抛开这一点:为了调用break而抛出错误?我们已经可以检查元素是否存在,然后酌情跳过或中断。您引用的两个原因对于在非常简单的循环中使用 try/catch 都不是真正有效的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-02
        • 1970-01-01
        相关资源
        最近更新 更多