-2

I have a button with an event listener that appends items to the DOM when clicked. I'd like to add a function that clears those appended elements on subsequent button clicks.

Here's what I've tried but keep getting "div is undefined".

function appendStuff(data) {
   for ( let i = 0; i < data.length; i++ ) {
    let body = document.querySelector('body');
    let div = document.createElement('div');
    let id = document.createElement('h1');
    div.appendChild(id)
    body.appendChild(div)
  }
};

button.addEventListener('click', (event) => {
  clearDOM(), appendStuff()
});

function clearDOM() {
if (div.document.body) {
let removeDiv = document.getElementsByTagName("div");
document.body.removeChild(removeDiv);
}
};

I suppose a work-around would be to disable the button after a single click.

I think the catch here is that the first time the button is clicked there will not be a div element in the DOM. That seems to be what is throwing the error. Was hoping the If statement would get around that.

Vidro3
  • 192
  • 2
  • 11
  • can you share the append method – Arun P Johny Nov 10 '16 at 02:48
  • 2
    what is `div.document.body`? – Arun P Johny Nov 10 '16 at 02:48
  • @ArunPJohny it's testing if there is a div in the document.body, isn't it? – Vidro3 Nov 10 '16 at 02:57
  • `getElementsByTagName` returns a list of nodes. You'll have to remove them one by one. –  Nov 10 '16 at 03:01
  • 1
    Dup of http://stackoverflow.com/questions/38576698/getelementsbytagname-does-not-seem-to-work. –  Nov 10 '16 at 03:03
  • It would be slightly better practice to create a `DocumentFragment` and insert all the nodes at once. –  Nov 10 '16 at 03:07
  • Do not pollute your questions with EDIT notations. No-one cares when or how you edited your question, and if they do, they can check the edit history. If you want to respond to a commenter who asked you to add information saying you have done so, then do that in comments. –  Nov 10 '16 at 03:09
  • @torazaburo thanks. would what is described here work? http://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript?rq=1 – Vidro3 Nov 10 '16 at 03:11

2 Answers2

1

Remove all the div elements might not be the best idea, instead try to use a more specific selector like a class.

While creating the div, add a class to that and in the clear method remove all divs with the class

function appendStuff(data) {
  let body = document.querySelector('body');
  let ct = document.createDocumentFragment();
  for (let i = 0; i < data.length; i++) {
    let div = document.createElement('div');
    let id = document.createElement('h1');
    div.className = 'my-class';
    div.appendChild(id)
    ct.appendChild(div)
  }
  body.appendChild(ct)
};


button.addEventListener('click', (event) => {
  clearDOM(), appendStuff([{}, {}, {}, {}])
});

function clearDOM() {
  var divs = document.querySelectorAll('.my-class');
  Array.from(divs).forEach((div) => div.remove())

};
h1 {
  min-height: 20px;
  background-color: red;
}
<button id="button">Add</button>
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • @torazaburo you can try out the demo :) https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove - Need to have a look at browser support(only in edge) - else need to use `div.parentNode.removeChild(div)` – Arun P Johny Nov 10 '16 at 03:22
0

Your code has multiple issues.

function clearDOM() {
  if (div.document.body) {
    let removeDiv = document.getElementsByTagName("div");
    document.body.removeChild(removeDiv);
  }
};

First, indent your code properly. Also, functions do not need a terminating semi-colon.

Anyway, in the above, div.document.body does not mean anything; div is an undefined variable. What are you trying to check for? Remove this if condition.

Second, getElementsByTagName returns a list of nodes, and you can't removeChild that directly. You'll have to loop:

let removeDivs = document.getElementsByTagName("div");
for (let i=0; i<removeDivs.length; i++) document.body.removeChild(removeDivs[i]);

Although it will not affect the way your code works, it is better practice to create all the new elements in advance and insert them all at once, using DocumentFragment.

function appendStuff(data) {
  let frag = document.createDocumentFragment();

  for ( let i = 0; i < data.length; i++ ) {
    let div = document.createElement('div');
    let id = document.createElement('h1');
    div.appendChild(id);
    frag.appendChild(div);
  }

  document.body.appendChild(frag);
}

By the way, you don't need to use querySelector to get the body. It's right there in document.body.