sjannette
sjannette

Reputation: 75

Javascript extra tag when performing appendChild

I am trying to achieve the following output:

  <ul class="deck">
      <li class="card">
          <i class="fa fa-diamond"></i>
      </li>
      <li class="card">
          <i class="fa fa-paper-plane-o"></i>
      </li>

         ...
   </ul>

But instead, when I run my code, I am getting:

  <ul class="deck">

      <li>
          <li class="card">
              <i class="fa fa-diamond"></i>
          </li>
      <li>
          <li class="card">
              <i class="fa fa-paper-plane-o"></i>
          </li>
      </li>
         ...
   </ul>

So as you can see I am getting an extra enclosing <li> tag. I have tried several approaches, to no avail. The JS generating this html is:

const gameDeck = document.querySelector(".deck");
const fragment = document.createDocumentFragment();

for (i = 0; i < cardArray.length; i++) {
    const newElement = document.createElement('LI');
    newElement.innerHTML = "<li class=\"card\"><i 
    class="+cardArray[i]+"></i></li>"

    fragment.appendChild(newElement);
}

gameDeck.appendChild(fragment);

Upvotes: 0

Views: 99

Answers (5)

kingdaro
kingdaro

Reputation: 12008

const newElement = document.createElement('LI');

This creates an <li></li>.

The innerHTML property sets the content inside of the element So if you put <li> inside the <li>, you'll end up with <li><li></li></li>

Instead, set the innerHTML to what you actually want to be inside the <li>, excluding the <li> that's already there. Template string used here for readability.

newElement.innerHTML = `<i class=${cardArray[i]}></i>`

Then, attach the class to the li as well. Two different ways of doing so. I prefer the second, especially if you want to add a bunch of classes later.

newElement.className = 'card'
newElement.classList.add('card')

However, you can circumvent all of the above using outerHTML instead, which does what I believe you expected innerHTML to do.

const newElement = document.createElement('LI');
newElement.outerHTML = "<li class=\"card\"><i class="+cardArray[i]+"></i></li>"

See this page on MDN for more details on outerHTML.

Upvotes: 1

Katherine R
Katherine R

Reputation: 1158

You are creating an li and then adding the inner html of "li" -- try removing the li inside of the innerHTML

const gameDeck = document.querySelector(".deck");
const fragment = document.createDocumentFragment();

for (i = 0; i < cardArray.length; i++) {
    const newElement = document.createElement("li");
    newElement.className = "card";
    newElement.innerHTML = "<i class="+cardArray[i]+"></i>"

    fragment.appendChild(newElement);
}

gameDeck.appendChild(fragment);

Upvotes: 0

geoidesic
geoidesic

Reputation: 5053

You are creating an LI element and then putting an <li> element into it. Just do this:

const gameDeck = document.querySelector(".deck");
  const fragment = document.createDocumentFragment();

  for (i = 0; i < cardArray.length; i++) {
      const newElement = document.createElement('LI');
      newElement.innerHTML = "<i class="+cardArray[i]+"></i>"

      fragment.appendChild(newElement);
  }

  gameDeck.appendChild(fragment);

Upvotes: 0

Javier S
Javier S

Reputation: 396

When you create a LI element, it has already the <li> and </li> tags. Don't add them again.

const gameDeck = document.querySelector(".deck");
const fragment = document.createDocumentFragment();

for (i = 0; i < cardArray.length; i++) {
    const newElement = document.createElement('LI');
    newElement.setAttribute('class', 'card');
    newElement.innerHTML = "<i class="+cardArray[i]+"></i>"

    fragment.appendChild(newElement);
}

gameDeck.appendChild(fragment);

Upvotes: 0

Nick
Nick

Reputation: 147156

Basically you are inserting an li into newElement, which is already an li. Try this instead:

const gameDeck = document.querySelector(".deck");
const fragment = document.createDocumentFragment();

for (i = 0; i < cardArray.length; i++) {
    const newElement = document.createElement('LI');
    newElement.className = 'card';
    newElement.innerHTML = "<i class="+cardArray[i]+"></i>"
    fragment.appendChild(newElement);
}

gameDeck.appendChild(fragment);

Upvotes: 0

Related Questions