DOM이란?
DOM이란 Document Object Model의 약자로 문서 객체 모델을 의미한다.
쉽게 말해 HTML안의 내용물들을 node(html을 구성하는 최소 단위?정도로 이해하면 될 것 같다)의 형태로 변화시켜서
script문서 내에서 관리 할 수 있도록 만들어주는것이다. 즉 웹을 구성하는 html의 내용물(text, img, elemet등)을 DOM을 이용해서 조작 할 수 있다.
그런데 왜 우리는 간편한 html문서를 두고 dom을 이용하여 문서를 조작하는것일까?
그 이유는 html은 정적인 요소만을 마크업 할 수 있지만
우리의 웹페이지는 정적이지 않다. 사용자가 어떻게 페이지를 사용하느냐에 따라 화면의 변화가 일어나야 한다.
그렇기때문에 dom을 이용하여 사용자가 페이지를 조작할 때 화면을 정적으로 변화시켜주는것이다.
이때 이렇게 화면을 조작하며 일어나는 변화를 우리는 event라고 부른다.
eventListener란?
EVENT를 사용하기 위해 필요한 핸들러를 eventListener 라고 한다.
이 eventListener은 event 콜백함수로 핸들링이 가능하다
최근 많이 쓰이는 추세의 eventListner은 eddEventListener()인데,
onclick=function() 등의 핸들러와의 차이점은
이벤트 타입 / 핸들링의 기본기능에 3번째요소로 어떻게 컨트롤할것인지에 대한 옵션도 넣어줄 수 있기 때문에
조금 더 정교하게 조작이 가능하다는 것에 있고, 이벤트에 핸들러를 여러개를 붙일수도있다 (현업에서 잘 쓰이는 기능은 아니다)
자주 사용되는 Event Type
load - 파일의 Load가 끝났을때 이벤트를 발생시킨다
scroll - 화면을 scroll할 때 이벤트를 발생시킨다
resize - 화면의 크기를 재조정 할 때 이벤트를 발생시킨다
blur - 요소에 초점을 맞추었다가 다른곳으로 초점을 옮길때 이벤트를 발생시킨다
focus - 요소에 초점을 맞추었을 때(클릭 혹은 tab바 등으로) 이벤트를 발생시킨다
change - input요소나 textarea등의 값이 바뀌었을 때(일반적으로 사용자의 입력했을 때) 이벤트를 발생시킨다
submit - 제출 버튼을 눌렀을 때 이벤트를 발생시킨다
click - 요소를 클릭할 때 이벤트를 발생시킨다 (가장 많이 사용됨)
mousedown - cilck이 요소를 클릭하고 떼었을 때 이벤트를 발생시킨다면 mousedown은 마우스를 꾹 누르고 있을 때 이벤트를 발생시킨다
mouseenter - 요소에 마우스가 진입했을 때 이벤트를 발생시킨다
mouseleave - 요소에서 마우스가 떠났을 때 이벤트를 발생시킨다
mouseup - 마우스에서 손을 뗐을 때 이벤트를 발생시킨다
keydown - 특정 키를 눌렀을 때 이벤트를 발생시킨다 (esc키 등을 눌렀을 때 화면을 나가게 하는 용도로 많이 사용됨)
keyup - 특정 키에서 손을 뗴었을 때 이벤트를 발생시킨다
EVENT FLOW란?
HTML의 구조는 기본적으로 중첩되어있다
예를들면 <html><body><div><button></button></div></body></html> 이런식으로 하나의 요소 내부에 여러가지 요소들이 들어가는 구조를 지닌다.
eventflow의 이해를 위해 이 중첩된 구조들을 html문서의 측면에서 바라봤다고 생각하고 3D로 표현 해 보겠다
<button></button>
<div>--------------------</div>
<body>-----------------------------</body>
<html>-------------------------------------</html>
중첩된 구조는 이런식으로 하나의 요소위에 다른 하나가 올라와 있다고 볼 수 있는데
이때 개발자가 button과 body에 click이벤트를 작성했다고 가정해보자.
그렇게되면 사용자가 button을 클릭하고자 했을때, button의 클릭이벤트와 body의 클릭이벤트가 모두 발생되는 문제가 생길것이다.
이러한 현상을 가리키는 용어는
currentTarget-이벤트의 진짜 주인 / target -이벤트의 시발점
위의 상황을 예시로 들었을 때 button과 body입장에서 이벤트의 주인(currentTarget)은 요소 자신이지만, 그 이벤트를 불러오게 된 시발점(target)은 button이 된다.
이렇게 중첩된 구조내에서 이벤트가 겹쳤을때 어느 이벤트를 먼저 실행시키느냐?에 대한 규칙으로 event는 event flow라는것을 가지고 있다.
이 event flow는 window에서 가장 가까운 요소의 순서대로 (html->body->div->button)순으로 흐름을 가지게 되고 이러한 과정을 Capture phase라고 한다. 그리고 그 이벤트가 시작된 당사자를 Target phase라고 한다. 그다음 다시 window에 가까운 요소까지 내려오는 과정을 Bubble phase라고 한다.
이러한 이벤트의 flow때문에 발생되는 문제가 있다
위의 예시를 들은 상황으로 상황을 확인해보자.
button을 클릭했을때 capture phase과정(html->body->div->button)에서 body와 button의 클릭 이벤트가 순서대로 실행되는데,
Target phase를 확인 후 다시 내려가는 Bubble phase (button->div->body->html)과정에서 다시 body의 이벤트가 실행되면서 이벤트 버블링 문제가 발생한다.
이것을 해결하기 위해 브라우저는 currentTarget과 target이 일치하지 않을 때 이벤트를 capture단계에서 발생시킬 지 bubble단계에서 발생시킬지 선택할 수 있게 한다. (브라우저의 기본값은 bubble이다)
그럼 이 capture와 bubble은 어떻게 조작할까?
바로 위에서 나왔던 eddEventListener(이벤트,핸들러,컨트롤옵션)의 컨트롤옵션부분에 true 혹은 false를 넣어주면 된다
false는 bubble, true는 capture로 flow의 순서를 실행시키는 것이고 따로 설정하지 않는다면 기본값은 false로 된다.
하지만 개발을 하다보면 이런 event의 flow가 맘에 들지 않을수도 있다
button값을 클릭했을땐 button 값의 이벤트만 실행시키고 body의 이벤트는 실행시키고 싶지 않을 수도 있을것이다.
이때 사용할 수 있는 메서드로는 e.stopPropagation()이 있다. 이것은 target에 도착했을때 flow를 끊는 명령어이다.
이때 주의할것은 button값에 e.stopPropagation()를 실행시켜 흐름을 제어할 수도 있지만, div나 body등에 해당 메서드를 쓰게되면
button까지 도달하는 flow를 끊기 때문에 정작 button이 이벤트를 받지 못하게 될수도 있다.
'JAVASCRIPT' 카테고리의 다른 글
Object(객체) (0) | 2021.05.15 |
---|---|
배열 내장함수 총 정리 (0) | 2021.03.25 |
배열내장함수 - reduce (0) | 2021.03.24 |
배열내장함수 - concat / join (0) | 2021.03.23 |
배열 내장함수 - shift / pop / unshift / push (0) | 2021.03.23 |