자바스크립트

JS Live(라이브) Collection vs Static(정적) Collection

KairoYang 2020. 6. 9. 01:53

 

 

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에는 요소가 그대로 존재하면 클래스 명만 바뀐 상태로 그대로 저장된다.

 

https://im-developer.tistory.com/110?category=846746