document.querySelector()
: 조건에 맞는 가장 첫 노드 하나만 가져옴document.querySelector('h3:nth-of-type(2)')
→이렇게 css의 가상 클래스 선택자와 비슷한 조건도 줄 수 있음document.querySelector()
: 여러 개의 노드 (NodeList 반환)document.getElemenetsByTagName()
: 여러 개의 노드 (HTMLCollection 반환)이름에서도 알 수 있듯이, NodeList는 모든 노드(요소 외에도 텍스트, 줄바꿈, 주석을 포함한 모든 노드) 를, HTMLCollection은 html 요소를 담는다.
const pList1 = document.querySelectorAll('p');
const pList2 = document.getElementsByTagName('p');
console.log(pList1); // NodeList(4) [p#first, p#second, p, p]
console.log(pList2); // HTMLCollection(4) [p#first, p#second, p, p, first: p#first, second: p#second]
// 이 상태에서 p 태그를 추가하면 HTMLCollection에는 변경 사항이 실시간으로 반영됨
const red = document.getElementById('red');
// 2가지 방법
red.parentNode;
red.parentElement;
document.documentElement; // HTML
document.documentElement.parentNode; // #document -> 부모 노드 중 모든 노드
document.documentElement.parentElement; // null -> 부모 노드 중에 *요소* 노드(HTML 태그로 이루어진 것)만 반환
const ul = document.getElementById('color');
ul.childNodes; // 자식 노드 전부
ul.children; // 자식 노드 중에 *요소* 노드만
ul.firstChild; // 첫번째 노드를 가져옴
ul.lastChild;
ul.firstElementChild; // 첫번째 *요소* 노드를 가져옴
ul.lastElementChild;
const blue = doucument.getElementById('blue');
blue.previousSibling; // 이전 노드
blue.nextSibling;
blue.previousElementSibling; // 이전 *요소* 노드
blue.nextElementSibling
// <li id="blue">Blue</li>
const blue = document.getElementById('blue');
blue.firstChild; // "Blue"
const blueTextNode = blue.firstChild;
blueTextNode.nodeName; // '#text'
blueTextNode.nodeType; // 3 (Text Node)
blueTextNode.nodeValue; // 'Blue'
const ul = document.getElementById('color');
ul.nodeValue; // null -> text node에서만 nodeValue를 이용해 수정 가능
ul.textContent; // '\n Red\n \n Blue\n ' -> 가능은 하지만 마크업이 반영 안 됨
ul.innerHTML = '<li>RED</li>'; // -> 마크업까지 적용되지만 요소를 추가, 제거, 삭제할 때마다 String으로 작성해야 함
const newLi = document.createElement('li');
newLi.innerHTML = 'green';
ul.appendChild(newLi)
const newLi2 = document.createElement('li');
const newText = document.createTextNode('pink');
newLi2 .appendChild(newText);
ul.appendChild(newLi); // appendChild는 항상 마지막 위치에 넣음
// insertBefore : 특정 노드 이전에 추가
const newLi3 = document.createElement('li');
const newText3 = document.createTextNode('black');
newLi3 .appendChild(newText3);
ul.insertBefore(newLi3, red); // red 앞에 li를 넣어라
appendChild
, insertChild
에 기존 노드를 전달하면 해당 노드의 위치가 바뀜const newBlack = newLi3.cloneNode(); // false와 같음 -> 노드 자신만 전달
ul.appendChild(newBlack);
const newBlack = newLi3.cloneNode(true); // true 전달 시 깊은 복제 실행 (자식까지 모두 복제)
ul.appendChild(newBlack);
ul.removeChild(newBlack);
ul.removeChild(ul.firstElementChild);
ul.removeChild(ul.firstChild);
: 요소 노드가 아니라 줄바꿈, 주석 등의 노드가 첫 자식이라면 의도와 달리 이런 노드를 삭제하게 됨요소.styled.css프로퍼티 = 값;
의 형태로 작성. 단, 프로퍼티는 camelCase
로 작성
// ex.
const box = document.getElementById('box');
box.style.backgroundColor = 'red';
box.style.color = '#fff';
// 이렇게 하면 케밥 케이스 그대로도 사용 가능
box.style["margin-left"] = '30px';
.className
: 여러 개를 추가하고 싶다면 하나씩 적어줘야 함box.className = 'bg-red';
box.className = 'bg-red txt-pink';
.classList
// 추가
box.classList.add('txt-white');
box.classList.add('bg-green', 'txt-white');
// 삭제
box.classList.remove('txt white');
// 변경
box.classList.replace('bg-red', 'bg-blue');
// 토글 (있으면 추가, 없으면 제거)
box.classList.toggle('bg-red');
<body>
<button type="button" id="btn">클릭3</button>
<button type="button" id="btn2">클릭4</button>
<script>
function sayHello() {
alert("hello");
}
// 방법 1
const btn = document.getElementById('btn');
btn.onclick = sayHello; // 괄호가 없어야 함 (반환값이 아니라 함수를 할당)
// 방법 2
const btn2 = document.getElementById('btn2');
// btn2.addEventListener('click', sayHello);
btn2.addEventListener('click', () => {
alert("hi");
});
</script>
</body>
addEventListener
로만 동작 ex) DOMContentLoadedaddEventListener
사용자식 요소에서 발생한 이벤트 객체는 더 이상 부모 요소가 없을 때까지 부모 요소로 전파됨
⇒ 이벤트 버블링
```html
<body>
<div id="box">
<ul id="list">
<li id="color">Red</li>
</ul>
</div>
<script>
const box = document.getElementById("box");
const list = document.getElementById("list");
const item = document.getElementById("color");
document.body.addEventListener('click', () => {
console.log("1. body");
})
box.addEventListener('click', () => {
console.log("2. box");
})
list.addEventListener('click', () => {
console.log("3. list");
})
item.addEventListener('click', () => {
console.log("4. item");
})
</script>
</body>
```
ex) li 클릭 시
버블링되지 않는 이벤트
버블링 X | 버블링 O (동작은 같음) |
---|---|
focus | focusin |
blur | focusout |
mouseenter | mouseover |
mouseleave | mouseout |
이벤트 버블링을 막는 방법
event.stopPropagation();
이벤트 위임
li
에 각각 클릭 이벤트를 달아준다면 요소가 100개일 경우, 100개의 EventListener를 작성해야 한다. 그런데 이벤트는 부모 요소로 버블링되므로 ul
에서 처리하면 하나의 EventListener만 작성할 수 있다. (부모 요소로 이벤트를 위임)