Interested to know if anyone can help describe the internals for the behaviour I am seeing.
Essentially, when creating a new dom element (then storing in a const) this element cannot be appened and prepended to the same parent element.
Example:
const ul = document.querySelector('ul');
const button = document.querySelector('button');
button.addEventListener('click', () => {
const li = document.createElement('li');
li.textContent = 'new li';
ul.prepend(li);
ul.append(li);
});
It seems the last call to either append or prepend, note if you call prepend last the new element is only added to start of the ul.
Digging into this it seems the cloning the node works prior to the subsequent append/prepend call.
const li = document.createElement('li');
li.textContent = 'something new to do';
ul.prepend(li);
const newLi = li.cloneNode(true);
ul.append(newLi);
However I'm interested to know the inner workings of this and why you can't seem to call against the same element? Can anyone shed any light on this as the mozilla docs don't seem to shed any light on this.
Fiddle: https://jsfiddle.net/gf7b0pom
Thanks everyone!
I think the confusion here is perhaps your understanding of what is stored created and stored in the line const li = document.createElement('li');. In this case, li doesn't contain a template that can be used over and over- when you use document.createElement() you are creating a single instance of an element of your choice. That single instance can only be in one place at a time.
As an analogy, I believe you are imagining li to be something like a rubber stamp, that can be used anywhere on a sheet of paper to make a list item. In reality, li is more like a sticker -- it can only be in one place on the paper at a time. When you run:
ul.prepend(li);
ul.append(li);
...it is like you stick your list item sticker to the front of the list, then you peel it off and stick it to the back of the list. This is why you need to call .cloneNode(true)-- it is essentially giving you a duplicate sticker to use elsewhere.
The reason is actually simple. When you create a new element, you create only one element. In your event listener, you first prepend that element then you append the same element.
ul.prepend(li);
ul.append(li);
So code is doing what you ask. It is moving the element but it is using the same element because you don't have a 2nd element.
On the other hand you want to append and prepend total of 2 elements which contains the same shape/data. So you need 2 DOM elements for that. If you also clone an element, you can also use it once. So if you want to append that element to multiple places, then every-time you need to clone then append.