- 버블링 / 캡쳐링
- preventDefault
- node
- 요소
- 요소 생성 / 이동
1) 버블링 / 캡쳐링
이벤트 캡처링 : 상위에서 하위로 이벤트 전파
이벤트 버블링 : 하위에서 상위로 이벤트 전파
<script>
'use strict';
let box = document.querySelectorAll('.box');
let output = document.querySelector('.output');
let txt = '';
const make=(e)=>{
txt += `<p>${e.currentTarget.dataset.name}</p>`;
output.innerHTML=txt;
}
box.forEach(item=>{
item.addEventListener('click', make);
})
</script>
하위에서 상위로 이벤트가 전파되므로 셋 box를 클릭하면 셋-둘-하나가 출력이 된다.
<script>
'use strict';
let box = document.querySelectorAll('.box');
let output = document.querySelector('.output');
let txt = '';
const make=(e)=>{
txt += `<p>${e.currentTarget.dataset.name}</p>`;
output.innerHTML=txt;
}
box.forEach(item=>{
item.addEventListener('click', make, true);
})
</script>
반대로 상위에서 하위로 이벤트가 전파되어 하나-둘-셋이 출력되었다.
2) preventDefault
링크가 걸린 이벤트를 취소할 때 사용한다.
<body>
<p><a href="http://www.google.com">구글</a></p>
<p><a href="http://www.naver.com">네이버</a></p>
<p><a href="http://www.nate.com">네이트</a></p>
<script>
'use strict';
let link = document.querySelectorAll('a');
link.forEach(item =>{
item.addEventListener('click',e=>{
e.preventDefault();
})
})
</script>
</body>
이렇게 맨 위에 preventDefault를 넣으면 a 링크를 눌러도 이벤트가 생성되지 않는다.
여러 링크를 막아야 할 땐 두 가지 방법을 사용한다.
<a href="javascript:void(0)"></a>
let link = document.querySelectorAll('a[href="#"]');
link.forEach(item => {
item.addEventListener('click', e=>{
e.preventDefault();
})
});
3) node
과거에 썼던 방법이며, 요즘은 쓰지 않는다.
childNodes : 자식 노드들(유사배열)
firstChild : 기준 노드의 첫 번째 자식
lastChild : 기준 노드의 마지막 자식
nextSibling : 다음 형제 노드
previousSibling : 이전 형제 노드
parentNode : 부모 노드
nodeType : 노드 유형(요소 : 1, 텍스트 : 3, document : 9)
nodeValue : 값
<script>
'use strict';
let list = document.querySelector('.list');
let li = document.querySelectorAll('.list li');
let p = document.querySelector('p');
// console.log(list.childNodes)
let a1 = list.firstChild;
let a2 = list.lastChild;
let a3 = list.parentNode;
let a4 = li[0].nextSibling.nextSibling;
a4.style.backgroundColor = 'tan'
let a5 = li[2].nextSibling.nextSibling.nextSibling.nextSibling;
// li-enter-li-enter-li
a5.style.backgroundColor = 'pink'
let a6 = li[6].previousSibling.previousSibling;
a6.style.backgroundColor = 'orange'
console.log(a4);
li[0].innerHTML = `0/ ${a1}`;
// li로 인식을 안하고 enter로 인식
li[1].innerHTML = `1/ ${a2}`;
// lastChild는 마지막 enter
li[2].innerHTML = `2/ ${a3}`;
// parentNode는 list의 부모인 div.box
li[3].innerHTML = `3/ ${a4}`;
li[4].innerHTML = `4/ `;
li[5].innerHTML = `5/ `;
li[6].innerHTML = `6/ `;
li[7].innerHTML = `7/ `;
li[8].innerHTML = `8/ `;
li[9].innerHTML = `9/ `;
</script>
노드는 enter도 인식을 한다. 따라서 li[0]은 첫 번째 li가 아니라 enter가 되는 것이다.
4) 요소
childern : 자식 요소
firstElementChild : 첫 번째 요소
lastElementChild : 마지막 요소
nextElementSibling : 다음 형제 요소
previousElementSibling : 이전 형제 요소
parentElement : 부모 요소
<script>
'use strict';
let list = document.querySelector('.list');
let li = document.querySelectorAll('.list li');
let p = document.querySelector('p');
let a1 = list.firstElementChild;
a1.style.backgroundColor = 'tan';
let a2 = list.lastElementChild;
a2.style.backgroundColor = 'pink';
let a3 = list.parentElement;
let a4 = list.children;
let a5 = list.children[2];
a5.style.backgroundColor = 'orange'
let a6 = li[2].nextElementSibling;
a6.style.backgroundColor = 'skyblue';
a6.nextElementSibling
.nextElementSibling
.nextElementSibling.style.backgroundColor = 'gold';
</script>
Element는 요소만 취급하기 때문에 li[n]처럼 쓸 수 있다.
5) 요소 생성 / 이동
노드(과거 사용했던 방식)
appendChild() : 부모 요소의 맨 뒤에 추가(생성) / 이동
부모.appendChild(자식) : 요소가 존재하면 이동
부모.appendChild(자식) : 요소 생성 후 부모 맨 뒤에 추가
removeChild() : 삭제(메모리에 존재, 완벽한 삭제 아님)
replaceChild(변경 후, 변경 전) : 변경
insertBefore() : 맨 앞으로 이동
append() : 부모 요소 맨 뒤에 추가(생성) / 이동
부모.append(자식) : 요소가 존재하면 이동
부모.append(자식) : 요소 생성 후 부모 맨 뒤에 추가
append(요소)
append('텍스트')
append(요소, 요소, '텍스트')
prepend() : 부모 요소 맨 앞에 추가(생성) / 이동
부모.prepend(자식)
remove() : 삭제(메모리에서도 삭제)