22-10-19-JavaScript(11) DOM(2)

YJ·2022년 10월 19일
0
post-thumbnail

textContent vs innerText

  1. textContent
    모든 텍스트를 그대로 가져온다. (해당 노드가 가지고 있는 텍스트 값 모두)

  2. innerText
    요소 내에서 사용자에게 보여지는 텍스트 값을 가져온다.
    숨겨지는 요소들은 안보이게 설정

  3. innerHTML
    요소 내에 있는 HTML과 XML 마크업을 가져오거나 설정한다.


출처 : MDN 문서

이벤트 흐름

브라우저 화면에서 이벤트가 발생한다면 가장 먼저 이벤트 대상을 찾기 시작한다.

  • 캡처링 단계
    가장 상위 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);

이벤트 traget, currentTarget

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로 내용 변경됨

이벤트의 this

이벤트가 연결된 노드를 참조
event.currentTarget와 동일 (-> 이벤트 리스너 연결된)
function 인 경우 this는 이벤트가 연결된 부분을 가리킴

화살표 함수로 사용하면 this가 가리키는 대상이 달라짐!!
(자신을 둘러 싸고 있는 외부 환경의 this를 참조)

이벤트 동작 취소 preventDefault()

const submit = document.querySelector('.submit');
submit.addEventListener('click', () => {
	console.log('clicked');
  	event.preventDefault();
})

버튼 클릭시 새로고침 되는 부분을 preventDefault()를 통해 클릭은 되지만 새로고침은 안되게 구현

stopPropagation()

이벤트 동작은 취소가 가능했지만 이벤트 흐름은 막지 못함
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 순으로 실행됨!!! (캡처링 이벤트가 먼저 실행됨)

profile
함께 배워나가고 싶습니다!

0개의 댓글