• document.getElementById -> HTMLElement를 리턴
• document.getElementsByClass -> HTMLCollection을 리턴
=> 실행 결과가 하나의 경우 element, 복수인 경우 HTML Collection을 리턴한다
• 암시적 반복 수행
: 선택된 엘리먼트 전체에 대해 동시에 작업이 처리됨. 암시적 반복은 값을 선택할때만 동작. 값을 가져올 때는 선택된 엘리먼트 중 첫번째에 대한 값만을 반환
• 유사배열의형태로 조회된 엘리먼트를 가짐. 따라서 배열처럼 사용해서 엘리먼트를 가져올 수 있음.
💡DOM(Document Object Model) 객체란?
html이나 xml같이 부분적 요소나 내용이 관련된 것들끼리 묶여서 존재하는 문서인 document에 접근하는 구조적 표현 방식.
각 element를 document의 트리의 node로 표현.
-> element, attribute, text등 모든 요소에 동적으로 접근 가능.
-> javascript나 jquery를 사용해서 해당 요소에 접근
자료출처: https://www.nextree.co.kr/p9747/
예시1)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script>
$(document).ready(function(){
var jQueryObject = $('p');
var DomObject = $('p')[0];
console.log(jQueryObject); // 제이쿼리 객체
console.log(DomObject); // DOM 객체
});
</script>
</head>
<body>
<div>
<p>1번 콘텐츠</p>
</div>
</body>
</html>
->jQuery는 jQuery 객체를 반환하고 DOM 객체는 Object인 html 태그 자체를 반환한다.
예시2)
$(function(){
var a = document.getElementsByTagName("p");
console.log(a)
var b = document.querySelectorAll("p");
console.log(b);
var c = $("p");
console.log(c);
})
-> jquery 선택자를 통해 반환된 객체는 jQuery 객체이고 document.getElementsByTagName을 통해 반환된 객체는 HTMLCollection, document.querySelectorAll을 통해 반환된 객체는 NodeList
예시3)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</head>
<body>
<div>
<p class="test" id="firstP" data-pid="1">1번 콘텐츠</p>
<p class="test" id="secondP" data-pid="2">2번 콘텐츠</p>
</div>
</body>
</html>
<script>
var a = document.getElementsByTagName("div").children[0];
a.classList.add("active");// div 태그들 전체에 active 클래스 추가
console.log(a.className); // test
console.log(a.id); //firstP
console.log(a.getAttribute("pid"));// 1
console.log(a.dataset.pid);// 1
var b = document.querySelectorAll("p");
console.log(b); //Nodelist[0]: p, Nodelist[1]: p
var c = $("div").children(":eq(1)");
// $("div").children().eq(1)으로도 사용가능
console.log(c.attr("id")); // secondP
console.log(c.attr("class"));// test
console.log(c.attr("pid")); // 2
</script>
🤓 공통점: HTMLCollection과 NodeList는 모두 유사 배열 객체이면서 이터러블
-> 따라서 둘 다 length 프로퍼티를 가짐
-> 객체를 배열처럼 접근 가능 (반복문을 돌 수 있음)
->그러나 유사 배열 객체이기 때문에 자바스크립트에서 제공하는 배열 객체의 메소드는 사용할 수 없음 (ex. map, forEach, reduce 등등)
☝️차이점
HTMLCollection 객체는 노드 객체의 상태 변화를 실시간으로 반영하는 살아있는 live DOM 컬렉션 객체.
-> 여기서 '살아있다'라는 의미는 객체가 스스로 실시간 노드 객체의 상태 변경을 반영함을 의미
예시4)
<html lang="kr">
<head>
<meta charset="UTF-8" />
<title>test</title>
</head>
<body>
<div id="app">
<h1>test</h1>
<div class="greeting">Hello</div>
</div>
</body>
<script>
const $app = document.getElementById('app');
const $greeting = document.getElementsByClassName('greeting');
console.log($greeting, $greeting.length); // HTMLCollection [div.greeting] 1
$app.insertAdjacentHTML('beforeend', '<div class="greeting">Hello</div>');
console.log($greeting, $greeting.length); // HTMLCollection(2) [div.greeting, div.greeting] 2
</script>
</html>
NodeList 객체는 노드 객체의 상태 변화를 반영하지 않는 non-live DOM 컬렉션 객체.
-> NodeList는 앞의 HTMLCollection과 다르게 노드가 변경되도 그 상태를 반영하지 않음.
<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8" />
<title>test</title>
</head>
<body>
<div id="app">
<h1>test</h1>
<div class="greeting">Hello</div>
</div>
</body>
<script>
const $app = document.getElementById('app');
const $greeting = document.querySelectorAll('.greeting');
console.log($greeting, $greeting.length); // NodeList [div.greeting] 1
$app.insertAdjacentHTML('beforeend', '<div class="greeting">Hello</div>');
console.log($greeting, $greeting.length); // NodeList [div.greeting] 1
</script>
</html>
자료출처: https://yung-developer.tistory.com/m/79
❗단, childNodes 프로퍼티가 반환하는 NodeList 객체는 HTMLCollection 객체와 같이 실시간으로 노드 객체의 상태 변경을 반영하는 live 객체로 동작
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="index.css" />
<title>Document</title>
</head>
<body id="app">
<ul id="students">
<li class="frontend">Gonnie</li>
<li class="frontend">Poco</li>
</ul>
</body>
<script>
const $students = document.getElementById("students");
const childNodes = $students.childNodes;
console.log(childNodes instanceof NodeList); // true
console.log(childNodes);
// NodeList(5) [text, li.frontend, text, li.frontend, text]
// childNodes는 요소노드 뿐만아니라 공백 텍스트 노드(엔터 키)도 포함
for (let i = 0; i < childNodes.length; i++) {
// removeChild 메서드가 호출될 때마다 NodeList live 객체인 childNodes가 실시간으로 변경됨
// 따라서 첫 번째, 세 번째, 다섯 번째 요소만 삭제됨
//i가 0일때 Nodelist 0번쨰 자식인 text 삭제 후 li.fronted가 0 번째 자식으로 바뀜. 그 후 i가 1일때 Nodelist 1번째 자식인 text를 삭제. 따라서 결과적으로 1,3,5만 남음.
$students.removeChild(childNodes[i]);
}
console.log(childNodes); // NodeList(2) [li.frontend, li.frontend]
</script>
</html>
❗NodeList.prototype.forEach 메서드를 상속받아 사용할 수 있음 (그러나 forEach 외의 Array.prototype에서 제공하는 map, reduce, filter 등의 메서드는 사용할 수 없음)
-> Array.from 사용해서 배열로 반환가능
Array.from($greeting);
[...$greeting];