Could someone explain the issue with this function chain? Not getting intended functionality

Viewed 54

I am trying to understand JS and jQuery and have some code to append an element to the DOM. I try and create a text node and append it to the element node and then append that to the first div tag, all in one statement. I understand this is probably bad practice but I just wanted to see if it were possible. It seems like it should work because createElement() returns the new element object and I call the appendChild() on that object which appends the returned object from createTextNode(). Yet what actually occurs is the text node gets appended, but not as a div. It seems it bypasses the createElement function for some reason. Could someone explain why please? I even put it in brackets to make sure it executes first to no avail.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
  'use strict';
  window.onload = () => {
    let dir = console.dir;
    let log = console.log;
    $('h1').hide();
    $('body').click(() => $('h1').show('slow', () => log('called')));
  };

  function appendDiv() {
    document.getElementsByTagName('div')[0]
      .appendChild((document.createElement('div'))
        .appendChild(document.createTextNode('AppendedDiv')));
  }
</script>
</head>

<body>
  <h1 id="heading1" onclick="appendDiv();">JavaScript and jQuery Practice</h1>
  <p>Practice using JavaScript and jQuery here!</p>
  <div>DIV</div>
  <div>DIV</div>
  <div>DIV</div>
  <div>DIV</div>

3 Answers

You have an extra () in the first append call

appendChild returns the appended child--so calling elem.appendChild(div.appendChild(text)) would actually append text to elem and not a div with child text like you intended. You should just separate it out:

function appendDiv() {
  const child = document.createElement('div');
  child.appendChild(document.createTextNode('AppendedDiv'));

  document.getElementsByTagName('div')[0]
    .appendChild(child);
}

Your parentheses are mismatched. Instead of appending the div and then appending the AppendedDiv text to it, you're appending the AppendedDiv text to the original div. See comment in this code:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
  'use strict';
  window.onload = () => {
    let dir = console.dir;
    let log = console.log;
    $('h1').hide();
    $('body').click(() => $('h1').show('slow', () => log('called')));
  };

  function appendDiv() {
    document.getElementsByTagName('div')[0]
      .appendChild(document.createElement('div')) // <-- Match parentheses like this
        .appendChild(document.createTextNode('AppendedDiv')); // <- Match
  }
</script>
</head>

<body>
  <h1 id="heading1" onclick="appendDiv();">JavaScript and jQuery Practice</h1>
  <p>Practice using JavaScript and jQuery here!</p>
  <div>DIV</div>
  <div>DIV</div>
  <div>DIV</div>
  <div>DIV</div>

This is a great reason to break these things down into multiple steps instead of doing it all in one go, which you are correct in thinking is "probably bad practice"! It's easy for subtle bugs like this to creep in.

Best practice would be to break it up into a few steps, something like this:

const wrapper = document.getElementsByTagName('div')[0];
const childDiv = document.createElement('div');
wrapper.appendChild(childDiv);
childDiv.appendChild(document.createTextNode('AppendedDiv'));

So much more readable!

Related