WonkasWilly
WonkasWilly

Reputation: 573

Can't figure out where this #text is coming from when using node.firstChild()

I am trying to get the node.firstChild of the #root element, after generating content within the container. I expect it to be the first div, because when I look at the elements in the dev console, that's the first child that I see. I am not sure where this #text is coming from, or what it means even.

Please help me understand:

  1. What #text is (obviously it's some type of text, but I don't see it)
  2. Why it's showing up instead of the firstChild of my container which should actually be div.each-result
  3. It should be noted that I am running this code in CodePen
  4. I am also aware I can also use Node.firstElementChild, but I want to understand what's going wrong currently.

const leftArrow = document.querySelector('#left-arrow');
const rightArrow = document.querySelector('#right-arrow');
const rootDiv = document.querySelector('#root');
const generateButton = document.querySelector("#button-generate");
//This code basically generates the content within the div
generateButton.addEventListener("click", () => {
  for (let i = 0; i < 10; i++) {
    const newDiv = document.createElement("div");
    newDiv.classList.add("each-result");
    newDiv.appendChild(addImg("https://uk.usembassy.gov/wp-content/uploads/sites/16/please_read_icon_150x150.jpg"));
    rootDiv.appendChild(newDiv);  
  }
  console.log(rootDiv.firstChild);
});

//These enable the arrow to scroll through the dynamically generated content
leftArrow.addEventListener('click', () => {
 //use
});
rightArrow.addEventListener('click', () => {
  alert("right arrow works");
});




//Simple function to create and image element with the src attribute set in one line
function addImg(url) {
  const newImg = document.createElement("img");
  newImg.setAttribute("src", url);
  return newImg;
}
html, body {
  height: 100%;
}

button {
  position: relative;
  z-index: 1
  width: auto;
  height: 50px;
}

.container {
  display: flex;
  justify-content: center;
  position: relative;
  top: 15%;
  z-index: 0
}

.result-container {
  display: flex;
  align-items: center;
  border: 1px solid black;
  width: 80%;
  height: 200px;
  position: relative;
  flex-flow: row no-wrap;
  overflow: hidden;
  
}

.each-result {
  height: 150px;
  width: 150px;
  border: 3px dotted red;
  margin: 1%;
}
img {
  height: 100%;
  width: auto;
}
.nav-arrows {
  display: flex;
  justify-content: space-between;
  width: 100%;
  height: auto;
  position: absolute;
  background: clear;
  pointer-events: none;
}
#left-arrow, #right-arrow {
  pointer-events: auto;
}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="container">
  <div class="nav-arrows">
      <button id="left-arrow"><i class="fas fa-arrow-alt-circle-left"></i>
      </button>
        <button id="right-arrow"> <i class="fas fa-arrow-alt-circle-right"></i>
      </button>
    </div>
  <div id="root" class="result-container">
  </div>
</div>
<button id="button-generate">Generate Content</button>

Upvotes: 1

Views: 417

Answers (1)

JoGr
JoGr

Reputation: 173

Look at the first example here: Node.firstChild

In the above, the console will show '#text' because a text node is inserted to maintain the whitespace between the end of the opening <p> and <span> tags. Any whitespace will create a #text node, from a single space to multiple spaces, returns, tabs, and so on.

Another #text node is inserted between the closing </span> and </p> tags.

If this whitespace is removed from the source, the #text nodes are not inserted and the span element becomes the paragraph's first child.

As you suggested yourself, ParentNode.firstElementChild is the best way to go in this case.

Upvotes: 1

Related Questions