I'm trying to move all the list items from an list to another using only javascript but for some reason only half of them are actually moved.
Heres a working example of what I'm doing:
var results_ul = document.getElementById('results'); var stores_li = document.getElementsByClassName('store-list-item'); for (var x = 0; x < stores_li.length; x++) { document.getElementById('hide').appendChild(stores_li[x]); stores_li[x].className += ' teste'; }
<p>results</p> <ul id="results"> <li class="store-list-item">Teste 1</li> <li class="store-list-item">Teste 2</li> <li class="store-list-item">Teste 3</li> <li class="store-list-item">Teste 4</li> </ul> <p>Hide:</p> <ul id="hide"></ul>
What seems to be the problem?
getElementsByClassName
returns a live list.
When you append the element to a different element, you change its position in the list.
So it starts off as:
1 2 3 4
Then you move the first one:
2 3 4 1
Then you access the second one … but the second one is now 3
because everything has shuffled down the list.
You could copy each element into an array (which will not be a live list) and then iterate over that array to move them (so they won't change positions as you go).
Alternatively, you could use querySelectorAll
which returns a non-live list.
You should better use querySelectorAll
than getElementsByClassName
var results_ul = document.getElementById('results'); var stores_li = document.querySelectorAll('.store-list-item'); stores_li.forEach((item)=>{ document.getElementById('hide').appendChild(item); item.className += ' teste'; });
<p>results</p> <ul id="results"> <li class="store-list-item">Teste 1</li> <li class="store-list-item">Teste 2</li> <li class="store-list-item">Teste 3</li> <li class="store-list-item">Teste 4</li> </ul> <p>Hide:</p> <ul id="hide"></ul>
Try use querySelectorAll . It'll returns a non-live list. That's what you need.
var stores_li = document.querySelectorAll('.store-list-item');
To increase more information:
Live : when the changes in the DOM are reflected in the collection. The content suffers the change when a node is modified.
Non-Live : when any change in the DOM does not affect the content of the collection.
document.getElementsByClassName() is an HTMLCollection, and is live.
document.querySelectorAll() is a NodeList and is not live.
In your code you are removing each element from the first list and inserting into the new list. After you remove 2 elements it will have only 2 elements in the first list but now you are searching the 3 rd index in the loop which is not there. So to make it work i have prepended each element from the last.
var results_ul = document.getElementById('results'); var stores_li = document.getElementsByClassName('store-list-item'); var hide_ul = document.getElementById('hide'); for (var x = 0, y = stores_li.length; x < y; x++) { hide_ul.insertBefore(stores_li[yx-1],hide_ul.firstChild); stores_li[x].className += ' teste'; }
<p>results</p> <ul id="results"> <li class="store-list-item">Teste 1</li> <li class="store-list-item">Teste 2</li> <li class="store-list-item">Teste 3</li> <li class="store-list-item">Teste 4</li> </ul> <p>Hide:</p> <ul id="hide"></ul>
Or you may want to clone the element with Jquery and you can push into the clonned ones then delete the orginals from top. I could not find any equivalent of clone() for js but if you want to check link is here
var results_ul = document.getElementById('results');
var stores_li = document.getElementsByClassName('store-list-item');
while(stores_li.length>0) {
document.getElementById('hide').appendChild(stores_li[0]);
stores_li[x].className += ' teste';
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.