textContent
모든 텍스트를 그대로 가져온다. (해당 노드가 가지고 있는 텍스트 값 모두)
innerText
요소 내에서 사용자에게 보여지는 텍스트 값을 가져온다.
숨겨지는 요소들은 안보이게 설정
innerHTML
요소 내에 있는 HTML과 XML 마크업을 가져오거나 설정한다.
브라우저 화면에서 이벤트가 발생한다면 가장 먼저 이벤트 대상을 찾기 시작한다.
캡처링 단계
가장 상위 window에서 document -> body 순으로 DOM 트리 따라 내려가는 단계
이벤트 버블링 단계
이벤트 대상을 찾아가는 과정에서 중간에 만나는 모든 캡처링 이벤트 리스너를 실행
이벤트 대상 찾고 캡처링 끝나면 다시 DOM 트리를 올라가면서 만나는 모든 버블링 이벤트 리스너를 실행
한 요소에 이벤트가 발생하면 이 요소에 할당된 핸들러 동작 -> 부모 요소 핸들러 동작
-> 가장 최상단을 만날 때까지 반복되면서 할당된 핸들러 동작
이벤트 발생한 타깃 요소
document -> DOM 트리를 따라 event.target까지 내려간다.
이벤트는 트리를 따라 내려가면서 캡처링 -> 타깃 요소 -> 버블링
이벤트 리스너가 차례대로 실행되는 것 -> 이벤트 전파 (event propagation)
아래 코드는
const parent = document.querySelector('.parent');
const btnFirst = document.querySelector('.btn');
btnFirst.addEventListener('click', () => {
console.log("btn capture!");
}, true);
// true : 캡처링 단계의 이벤트 발생되게 함
// 기본값은 false
window.addEventListener(...., true());
document.addEventListener(..., true());
....
document.addEventListener(...);
window.addEventListener(...);
capture의 2가지 옵션
1. false, default -> 핸들러는 버블링 단계에서 동작
2. true -> 핸들러는 캡처링 단계에서 동작
cap.addEventListener(..., true);
target : 이벤트가 발생한 진원지의 정보
-> 이벤트 리스너가 없는 요소의 이벤트가 발생했을 때도 접근 가능
currentTarget : 이벤트 리스너가 연결된 요소 참조
parent.addEventListener('click', function (event) {
console.log(event.target); // 이벤트 발생한 곳
console.log(event.currentTarget); // 이벤트 리스너 연결된 곳
})
// 버튼을 누른 경우
// target -> 이벤트가 발생한 진원지의 정보 (button)
// currentTarget -> 이벤트 리스너가 연결된 article 부분
이벤트 리스너가 없어도 리스너가 있는 것 처럼 해당 요소에 접근 가능
이벤트 위임이 없다면?
-> 버튼을 일일이 찾아서 하나씩 이벤트 리스너 달아줘야 함
요소 공통 조상 (부모)에 이벤트 헨들러를 달아서 여러 요소를 한꺼번에 다룰 수 있다.
-> 공통 조상에 할당한 핸들러에서 event.target를 이용
(최초로 이벤트를 발생시킨 엘리먼트를 가리킴)
// 부모로부터 이벤트 위임
// 부모 안 특정 요소 선택했을 때 (조건 달아주기 - 요소 이름 대문자로)
parent.addEventListener('click', function (event) {
console.log(event.target);
if(event.target.nodeName === "BUTTON") {
event.target.innerText = "버튼4");
}
})
nodeName 프로퍼티는 언제나 해당 HTML 요소의 태그 이름을 "대문자"로 저장!!
노드 고유의 이름을 저장, 읽기 전용 프로퍼티
버튼4로 내용 변경됨
이벤트가 연결된 노드를 참조
event.currentTarget와 동일 (-> 이벤트 리스너 연결된)
function 인 경우 this는 이벤트가 연결된 부분을 가리킴
화살표 함수로 사용하면 this가 가리키는 대상이 달라짐!!
(자신을 둘러 싸고 있는 외부 환경의 this를 참조)
const submit = document.querySelector('.submit');
submit.addEventListener('click', () => {
console.log('clicked');
event.preventDefault();
})
버튼 클릭시 새로고침 되는 부분을 preventDefault()를 통해 클릭은 되지만 새로고침은 안되게 구현
이벤트 동작은 취소가 가능했지만 이벤트 흐름은 막지 못함
event.stopPropagation() -> 를 통해서 이벤트 전파 막기
const submit = document.querySelector('.submit');
submit.addEventListener('click', () => {
console.log('clicked');
// 버튼의 기본적인 새로고침 효과 막기
event.preventDefault();
// event.stopPropagation();
});
document.body.addEventListener('click', () => {
console.log('event still alive');
})
event.stopPropagation()을 주석처리한 채 실행한 경우
버튼 클릭했을 때 body 이벤트까지 출력됨
submit 이벤트가 끝나고 버블링 이벤트 시작되면서 부모 요소 시작
event.stopPropagation()을 주석 해제한다면
버튼만 클릭할 경우 -> clicked
버튼 옆 body를 클릭할 경우 -> event still alive!가 따로 따로 출력됨
만약)
body 이벤트 리스너에 , true를 사용한다면 (캡처링)
event still alive!
clicked 순으로 실행됨!!! (캡처링 이벤트가 먼저 실행됨)