JS Live(라이브) Collection vs Static(정적) Collection
NodeList: element.childNodes와 같은 속성이나 document.querySelectorAll()과 같은 메소드에 의해 반환되는 Node Collection이다. 배열과 비슷하게 생긴 유사 배열이라고 부른다. 그래서 배열에 사용가능한 메소드 사용불가.
-NodeList는 Live 콜렉션으로 dom의 변경 사항을 실시간으로 반환한다. document.querySelectorAll()메소드에 의해 반환되는 NodeList는 정적 콜렉션으로 실시간 반영하지 않는다.
HTMLCollection
-인터페이스는 요소의 문서 내 순서대로 정렬된 일반 컬렉션을 나타내고 유사배열이다. element.children, document.getElementsByClassName(), document.getElementByTagName()과 같은메소드에 의해 반환된다.
-Live 콜렉션이다.
txt-red로 변경하면 색상이 다 변해야 하지만 위와같이 변하지 않는 것이 있다.
dom을 가져 올때 사용한 getElementByClassName()메소드가 반환하는 HTMLCollectiondl DOM의 변경사항을 시시간으로 반영하는 live collection이기 때문이다.
최초로 .txt-blue 클래스를 가진 요소들을 가져왔을 때, HTMLCollection의 길이는 3이다.
i의 초기값을 0으로 설정하여 3보다 작을때까지 루프를 돈다.
첫번째 요소의 클래스명을 txt-.red로 변경하는 순간
더 이상 txt-blue 클래스를 가지고 있지 않기때문에 htmlcollection이 삭제된다.
리스트의 길이가 의도치 않게 2로 변경되어 요소들이 한칸씩 앞으로 땡겨져 밀리게 된다.
해결방안
1.루프를 돌릴 때, class명을 txt-red로 바꾼 후 i 변수를 1감소시킨다.
for(let i = 0; i< li.length; i++){ li[i].className = 'txt-red'; i --}
그대신 반복후 출력하면 모든 요소가 제거된 빈 html이 출력된다.
2. 뒤에서부터 반복을 시작한다. 노드 컬렉션의 맨 마지막 요소부터 처리하기 때문에 마지막 요소가 제거 되더라도 영향없어.
for(let i =li.length -1; i>=0; i--){
li[i].className ='txt-red';}
그대신 반복후 출력하면 모든 요소가 제거된 빈 html이 출력된다.
3. 정적인 컬렉션 으로 반복을 실행한다.
const li = document.querySelecotAll('.txt-blue');
for(let i =0; i<li.length; i++){
li[i].className = 'txt-red';}
document.querySelectorAll()메소드로 반환되는 NodeList는 정적 컬렉션으로 변경 사항이 실시간으로 반영되지 않기 때문에 원하는대로 동작한다.
반복문이 종료된 후에도 li에는 요소가 그대로 존재하면 클래스 명만 바뀐 상태로 그대로 저장된다.