admin管理员组

文章数量:1426202

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>

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?

Share Improve this question edited Oct 3, 2017 at 12:29 Rob 15.2k30 gold badges48 silver badges73 bronze badges asked Oct 3, 2017 at 12:25 Cátia RodriguesCátia Rodrigues 1502 silver badges10 bronze badges 0
Add a ment  | 

6 Answers 6

Reset to default 8

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[y-x-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';
}

本文标签: javascriptappendappendChild not working on all itemsStack Overflow