简体   繁体   English

为什么在遍历 DOM 时使用节点列表或 HTML 集合中的元素时会出现未定义?

[英]Why do I get undefined when I use elements from a node-list or HTML-Collection when traversing the DOM?

While traversing the DOM there are sometimes many child elements under one parent.在遍历 DOM 时,有时在一个父元素下有许多子元素。

I can get these children as either node-lists using a querySelectorAll or I can get them as HTML-Collections by using element.children .我可以使用querySelectorAll将这些子节点作为节点列表获取,也可以使用element.children将它们作为 HTML-Collections 获取。

But when I select one to use to put in my DOM tree traversal I get undefined .但是当我选择一个用于放入我的 DOM 树遍历时,我得到undefined

I have tried turning the node-lists and HTML-Collections into arrays and using them that way with no success.我尝试将节点列表和 HTML-Collections 转换为数组并以这种方式使用它们,但没有成功。 I have tried using for-of loops regular for loops and foreach loops for selecting a single element, yet always with failure undefined .我尝试使用 for-of 循​​环,常规 for 循环和 foreach 循环来选择单个元素,但总是失败undefined

I have created a made up situation that shows this situation, although the problem is solvable without having to Traverse the DOM, you have to image that it is necessary.我已经创建了一个显示这种情况的虚构情况,尽管无需遍历 DOM 即可解决问题,但您必须想象这是必要的。

  • HTML HTML
<!DOCTYPE html>
<html lang="en">
   <head>
      <title>Testing</title>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link rel="stylesheet" href="eric_meyer_reset_2.css" />
      <link rel="stylesheet" href="styles.css" />
   </head>
   <body>
      <div id="wrapper">
         <div id="topOfPage">
            <header>
               <h1>Random Number Generator</h1>
            </header>
            <div id="simulated RNG">
               <p>Your number is: <span id="theRandomNumber">2</span></p>
               <button type="button" id="prizeOpenButton">Press for Prize</button>
            </div>
         </div>
         <div id="bottomOfPage">
            <!-- These sections are added dynamically during the script operation -->
            <section class="joy" data-id="0">Hurray</section>
            <section class="joy" data-id="1">Hurrah</section>
            <section class="joy" data-id="2">Yay</section>
            <section class="joy" data-id="3">Congrats</section>
         </div>
      </div>
      <script src="main.js"></script>
   </body>
</html>
  • CSS CSS
.joy {
   display: none
}
  • JavaScript JavaScript
const randomNumber = document.getElementById("theRandomNumber");
const prizeButton = document.getElementById("prizeOpenButton")

let matchNumberToPrizeSection = function (event) {
   let prizeSections = document.querySelectorAll(".joy");

   let theSection = null;

   for (let i = 0; i < prizeSections.length; i++) {
      if (prizeSections[i].dataset.id === randomNumber) {
         theSection = prizeSections[i];
      }
   }

   // lets say for some reason we have to traverse the DOM
   // starting with the button going to the "theSection" above
   let winningSection = event.target.parentElement.parentElement.nextElementSibling.theSection;

   console.log(winningSection.innerHTML);
}
prizeButton.addEventListener("click", matchNumberToPrizeSection);

I saw a number of issues, but the below code works.我看到了许多问题,但下面的代码有效。

For one, you were comparing elements instead of the text of the element, or the data-id.一方面,您正在比较元素而不是元素的文本或数据 ID。 I went through and cleaned up the inconsistencies there.我通过并清理了那里的不一致之处。

  1. this is returning an element这是返回一个元素
const randomNumber = document.getElementById("theRandomNumber");
  • but your are comparing it with a number dataset.id .但是您正在将其与数字dataset.id进行比较。 They will never match他们永远不会匹配
if (prizeSections[i].dataset.id === randomNumber)
let winningSection = event.target.parentElement.parentElement.nextElementSibling.theSection
  • the variable theSection is pointing to an element, and that is not a property of nextElementSibling .变量theSection指向一个元素,这不是nextElementSibling的属性。 I you want to do the element chaining and search for an element that is a child of nextElementSibling , then call querySelector on it and pass in an id or class, or whatever我想进行元素链接并搜索作为nextElementSibling子元素的元素,然后在其上调用querySelector并传入 id 或类或其他
let winningSection = event.target.parentElement.parentElement.nextElementSibling.querySelector([`data-id="${theSection.dataset.id}"`])

The above is redundant in this example, and I saw no reason to traverse the DOM like you did.以上在这个例子中是多余的,我认为没有理由像你一样遍历 DOM。 That's an easy way to create bugs, especially if you move around or add items to your markup.这是一种创建错误的简单方法,尤其是在您四处移动或向标记添加项目时。

Since you have the data-id , you can query the entire document for that id.由于您拥有data-id ,因此您可以在整个文档中查询该 ID。 This will be hardened to changes to the DOM in the future.这将在未来对 DOM 的更改进行强化。

 const randomNumber = document.getElementById("theRandomNumber").innerText; const prizeButton = document.getElementById("prizeOpenButton") let matchNumberToPrizeSection = function (event) { let prizeSections = document.querySelectorAll(".joy"); let theSection = null; for (let i = 0; i < prizeSections.length; i++) { if (prizeSections[i].dataset.id === randomNumber) { theSection = prizeSections[i].dataset.id; } } let winningSection = document.querySelector(`[data-id="${theSection}"]`); console.log(winningSection.innerHTML); } prizeButton.addEventListener("click", matchNumberToPrizeSection);
 .joy { display: none }
 <div id="wrapper"> <div id="topOfPage"> <header> <h1>Random Number Generator</h1> </header> <div id="simulated RNG"> <p>Your number is: <span id="theRandomNumber">2</span></p> <button type="button" id="prizeOpenButton">Press for Prize</button> </div> </div> <div id="bottomOfPage"> <!-- These sections are added dynamically during the script operation --> <section class="joy" data-id="0">Hurray</section> <section class="joy" data-id="1">Hurrah</section> <section class="joy" data-id="2">Yay</section> <section class="joy" data-id="3">Congrats</section> </div> </div>

While you cannot use node-list or HTML-Collection elements directly or indirectly when you are building up a DOM traversal.虽然在构建 DOM 遍历时不能直接或间接使用节点列表或 HTML-Collection 元素。 What I finally found was that I can use the element before the many child elements, in my original question that was a div with id of bottomOfPage.我最终发现,我可以在许多子元素之前使用该元素,在我原来的问题中是一个 id 为 bottomOfPage 的div What I had to do was find the index of the child element that I needed using the node-list elements and use that index in the parent div like this.我必须做的是使用节点列表元素找到我需要的子元素的索引,并像这样在父div中使用该索引。 event.target.parentElement.parentElement.nextElementSibling.children(index)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我尝试使用HTML和Xpath在DOM中使用两个get元素时,结果未定义 - When I try two get elements in DOM with HTML and Xpath results undefined 使用window.open将数据从父级传递到子级时,为什么会显示“无法读取未定义的属性”元素”? - When passing data from parent to child with window.open, why do I get 'Cannot read property 'elements' of undefined'? 在流星中遍历数组时如何获取模板详细信息 - How do I get template details when traversing an array in Meteor JavaScript:为什么在使用带有分解的赋值时会得到“ undefined”? - JavaScript: Why I get `undefined` when I use an assignment with destructuring? 为什么我从html doc收到函数未定义错误? - Why do I get function undefined error from html doc? 为什么我得到未定义,即使使用承诺? - Why do i get undefined, even when using a promise? 明确定义后,为什么会得到未定义的“ toUpperCase”? - Why do I get 'toUpperCase' of undefined when it's clearly defined? 为什么使用此功能时未定义? - Why do I get undefined when using this function? 尝试从URL读取JSON时为什么会出现“未定义”错误 - Why do I get an 'undefined' error when trying to read a JSON from an URL 当我尝试使用map()时,为什么我的GET响应未定义 - Why is my GET response undefined when I try to use map()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM