定位DOM节点并不是很有效

时间:2017-07-10 12:18:24

标签: javascript html dom

以下HTML标记和脚本有问题,但我没有理解:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>More Ways To Target Elements</title>
</head>
<body>

  <div id="div1">
    <div id div="div2">
      <p id="p1">Chicago</p>
      <p>Kansas City</p>
      <p>St. Louis</p>
    </div>
  </div>

  <script>
    var div = document.getElementById('div2');

    for (var i = 0; i < div.childNodes.length; i++) {
      if (div.childNodes[i].childNodes[0].nodeType === 3) {
        alert(div.childNodes[i].childNodes[0].innerHTML);
      }
    }

  </script>

</body>
</html>

我尝试缩小整个事情,但我从控制台得到了相同的结果,其中说:

Uncaught TypeError: Cannot read property 'childNodes' of null

任何建议,任何人?

1 个答案:

答案 0 :(得分:0)

那里有一些问题:

  1. 您的HTML无效且您没有id div2的元素(<div id div="div2">应为<div id="div2">)。这就是导致您开始使用的错误的原因。

    但是一旦你修好了,你就会遇到更多的错误:

  2. 并非所有节点都有childNodes,只有Element个节点。具体来说,Text节点没有。但是您假设#div2的所有子节点都是Element个节点。它们不是,有些是Text个节点。

    如果您只想查看Element中的#div2个节点,请使用div.children而不是div.childNodeschildren仅包含Element个,而不包含其他类型的节点。

  3. 您假设#div2的所有孩子至少有一个子节点,因为(如果您在上面执行#2),您正在执行div.children[i].childNodes[0].nodeType。如果没有子节点,那将抛出异常,因为childNodes[0]将为您提供undefined,而您无法从.nodeType读取undefined。你需要一名警卫。

  4. Text个节点没有innerHTML。如果您需要Text节点的文字,请使用nodeValue

  5. 随着这些变化:

    &#13;
    &#13;
    var div = document.getElementById('div2');
    
    for (var i = 0; i < div.children.length; i++) {
      if (div.children[i].childNodes[0]) {
        alert(div.children[i].childNodes[0].nodeValue);
      }
    }
    &#13;
    <div id="div1">
      <div id="div2">
        <p id="p1">Chicago</p>
        <p>Kansas City</p>
        <p>St. Louis</p>
      </div>
    </div>
    &#13;
    &#13;
    &#13;

    但是 ,如果目标是显示#div2子女的文字内容,我可能会使用querySelectorAll并且使用textContent(旧版IE不支持)或innerText元素(这些不是相同的东西,但差异并不重要),因为它会更简单:

    &#13;
    &#13;
    // Get the name to use (textContent isn't supported on older IE)
    var propName = "textContent" in document.body ? "textContent" : "innerText";
    // Get the immediate children of #div2,
    // alert their contents
    var list = document.querySelectorAll('#div2 > *');
    for (var i = 0; i < list.length; i++) {
        alert(list[i][propName]);
    }
    &#13;
    <div id="div1">
      <div id="div2">
        <p id="p1">Chicago</p>
        <p>Kansas City</p>
        <p>St. Louis</p>
      </div>
    </div>
    &#13;
    &#13;
    &#13;