Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions Part2/01-브라우저 이벤트/이경하.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# 1️⃣ 브라우저 이벤트 소개

## 자주 사용되는 DOM 이벤트

### 마우스 이벤트

- click, contextmenu, mouseover & mouseout, mousedown & mouseup, mousemove

### 폼 요소 이벤트

- submit, focus

### 키보드 이벤트

- keydown, keyup

### 문서 이벤트

- DOMContentLoaded

### CSS 이벤트

- transitionend

## “이벤트는 DOM에만 한정되진 않습니다”
— 비 DOM 이벤트 예시

- window 객체 이벤트
- load
- beforeunload / unload
- 자바스크립트 동작 관련 이벤트
- Promise 객체의 then이나 catch 같은 콜백 함수
- WebSocket 통신에서 새로운 메시지가 수신되었을 때 발생하는 이벤트

## 이벤트 핸들러

- 이벤트가 발생했을 때 실행되는 함수
(사용자의 행동에 어떻게 반응할지를 자바 스크립트 코드로 표현한 것)
- 복수의 이벤트 핸들러를 할당할 수 없다(기존 핸들러는 덮어씌워짐)
- 할당방법
1) HTML 속성
2) DOM 프로퍼티
3) addEventListener
- 핸들러 제거하고 싶다면 null 할당해주면 됨
`elem.onclick = null;`

### HTML 속성

- HTML안의 `on<event>` 속성에 핸들러 할당

```jsx
<input value="클릭해 주세요." onclick="alert('클릭!')" type="button">
```

ex) `onclick`, `onmouseover`, `onkeyup`, `onsubmit`, `onchange` …

- 코드가 길다면, 함수를 만들어 호출하도록 함
- HTML 속성은 대소문자를 구분하지 않지만, 대개 onclick 같이 소문자로 작성

### DOM 프로퍼티(HTML + 자바스크립트)

- ex) `elem.onclick`
- DOM프로퍼티는 대소문자를 구분함

### addEventListener / removeEventListener

- 핸들러를 여러개 할당/삭제할 수 있는 방법
- 문법
`element.addEventListener(이벤트 이름, 핸들러 함수, [options]);`
- `option` — 아래 프로퍼티를 갖는 객체
`once`: `true`면 이벤트가 트리거 될 때 리스너가 자동으로 삭제됨
`capture`: 버블링 or 캡쳐링
`passive`: `true`면 리스너에서 지정한 함수가 `preventDefault()`를 호출하지 않음
- 핸들러를 삭제하려면 핸들러 할당 시 사용한 함수를 그대로 전달해야함
- transitionend와 DOMContentLoaded 같은 일부 이벤트는 addEventListener를 써야만 동작
- 함수 뿐만 아니라 객체를 이벤트 핸들러로 할당할 수 있는데,
이벤트가 발생하면 객체에 구현한 handleEvent 메서드가 호출됨

## this로 요소에 접근하기

- 핸들러 내부의 `this` 값 = 핸들러가 할당된 요소
this 를 사용해 ‘요소 자체’를 참조할 수 있음
- ex)

```jsx
<button onclick="alert(this.innerHTML)">클릭해 주세요.</button>
```

- this.innerHTML 에서 this는 button

## 자주 하는 실수(주의사항)

1. 함수를 직접 핸들러에 할당할 때, 함수명만 작성해야 함
`button.onclick = sayThanks;` O
`button.onclick = sayThanks();` X
( ㄴ 함수 호출의 결괏값이 할당됨 )
그러나, HTML 속성값에는 괄호 있어야함
( ㄴ 브라우저는 속성값을 읽고, 속성값을 함수 본문으로 하는 핸들러 함수를 만들기 때문 )
`<input type="button" id="button" onclick="sayThanks()">`
2. `setAttribute`로 핸들렁 할당하면 안됨

## 이벤트 객체

- 이벤트가 발생하면 브라우저는 이벤트 객체(event object)를 만듦
여기에 이벤트에 관한 상세한 정보를 넣은 다음,
핸들러에 인수 형태로 전달

### 이벤트 객체 프로퍼티

- ex) `.type`, `.currentTarget`, `.clientX` …

# 2️⃣ 버블링과 캡처링

## 버블링

- ‘이벤트 버블링’ 이란?
한 요소에 이벤트가 발생할 때, 가장 최상단의 조상 요소를 만날 때까지 요소 각각에 할당된 핸들러가 동작
- 꼭 필요한 경우가 아니라면 버블링을 막지 않아야 한다

### event.target

- 이벤트 가장 안쪽의 요소는 `target` 요소라 불리며,
부모 요소 핸들러가 `event.target`을 사용해 접근할 수 있다.

cf) event.currentTarget(=this) — 이벤트를 핸들링하는 현재 요소


### 버블링 중단

- `event.stopPropagation()`을 사용하면 핸들러가 이벤트를 완전히 처리한 후 버블링을 중단함
- `event.stopImmediatePropagation()`을 사용하면 한 요소의 특정 이벤트를 처리하는 핸들러가 여러개인 상황에서 핸들러가 모두 동작하지 않음

## 캡처링

- 버블링과 반대
이벤트가 하위 요소로 전파되는 단계
- 캡처링 단계에서 이벤트를 잡아내려면 addEventListener의 capture옵션을 true로 설정해야 함

```jsx
elem.addEventListener(..., {capture: true})
//or
elem.addEventListener(..., true)
```

- false(default값) ⇒ 버블링 단계에서 동작
true ⇒ 캡처링 단계에서 동작
111 changes: 111 additions & 0 deletions 이경하.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# 1️⃣ 모듈

- 모듈이란, 분리된 파일 하나하나를 말한다.
대개 클래스 하나 혹은 특정한 목적을 가진 복수의 함수로 구성된 라이브러리 하나로 구성됨
- export와 import 지시자를 적용하면 다른 모듈을 불러오고 호출하는 기능 공유가 가능해짐
- 브라우저에서 동작 시킬 땐, <script type=”module”> 과 같이 속성을 설정해 해당 스크립트가 모듈임을 알 수 있게 해야함
- 개념적으로는 알겠으나 머릿속에 잘 들어오지 않음.
- 그렇다면 대체 일반 스크립트와 모듈의 차이가 무엇일까?

## 모듈의 핵심 기능

1. 모듈은 항상 엄격 모드로 실행된다.
- 엄격모드를 지키지 않은 코드는 에러를 발생시킴
2. 모듈은 자신만의 스코프가 있다.
- 따라서 모듈 내부에서 정의한 변수나 함수는 다른 스크립트에서 접근할 수 없음
3. 동일한 모듈이 여러 곳에서 사용되더라도
모듈은 최초 호출 시 단 한 번만 실행된다.
- **실무에선 최상위 레벨 모듈을 대개 초기화나 내부에서 쓰이는 데이터 구조를 만들고 이를 내보내 재사용하고 싶을 때 사용**
4. `import.meta` 객체로 현재 모듈에 대한 정보를 알 수 있다.
5. 모듈 최상위 레벨의 this는 undefined

cf) 일반 스크립트의 최상위 this는 전역객체(window)


## 브라우저 특정 기능

브라우저 환경에서
`type=”module”`이 붙은 스크립트와 일반 스크립트의 차이점

1. 모듈 스크립트는 항상 지연 실행된다.
(외부, 인라인 스크립트와 관계없이 defer 속성을 붙인 것 처럼 실행)

**주의해야하는 이유??
페이지 내 특정 기능이 모듈 스크립트에 의존적인 경우,
모듈이 완전히 로딩되기 전에 페이지가 먼저 노출되면 사용자가 혼란을 느낄 수 있기 때문**

2. 모듈 스크립트에서는 async 속성을 인라인 스크립트에 적용할 수 있다.
cf) 일반 스크립트에서 async 속성은 외부 스크립트를 불러올 때만 유효

**어디에도 종속되지 않는 기능을 구현할 때 유용하게 사용 가능
(ex. 광고, 문서 레벨 이벤트 리스너, 카운터 등)**

3. 외부 스크립트
1. src 속성값이 동일한 외부 스크립트는 한 번만 실행된다.
2. 외부 사이트 같이 다른 오리진에서 모듈 스크립트를 불러오려면 CORS 헤더가 필요하다. — 보안 강화
4. 경로가 없는 모듈은 허용되지 않는다.
따라서 브라우저 환경에서 `import`는 반드시 URL 앞에 와야한다.

## 빌드 툴

- 브라우저 환경에서 모듈을 단독으로 쓰기 보단, 웹팩(Webpack)과 같은 특별한 툴을 사용해 모듈을 번들링 후 프로덕션 서버에 올리는 방식을 사용함.
- 번들러를 사용하면??
모듈 분해를 통제할 수 있음 + 경로가 없는 모듈이나 CSS, HTML 모듈을 사용할 수 있게 해줌
- 번들링 과정 이후 import, export가 사라지기 때문에 type=”module” 이 필요 없어짐 → 일반 스크립트 같이 취급 가능

### 빌드 툴의 역할

1. 주요(main) 모듈 선택
2. 주요 모듈에 의존하고 있는 모듈 분석으로 모듈 간의 의존 관계 파악
3. 모든 모듈을 모아 하나의 파일로 만듦
4. 3번 과정 중 변형과 최적화 수행
- 도달 불가능한 코드 삭제
- 내보내기 모듈 중 쓰이지 않는 모듈 삭제
- consolem debugger 같은 개발 관련 코드 삭제
- 동일한 기능을 하는 낮은 버전의 스크립트로 변환 — 바벨 사용
- 크기 줄임(공백제거, 변수 이름 줄이기 등)

# 2️⃣ 모듈 내보내고 가져오기

## 내보내기 방법

1. 선언부 앞에 export
2. 선언부와 떨어진 곳에 export(마지막줄, 선언 위 등등)
3. `export 원래 이름 ‘as’ 변경하고 싶은 이름` 로 이름 바꿔서 내보내기
4. export default
사용하면 좋은 점 ??
‘해당 모듈엔 개체가 하나만 있다’는 사실을 명시함
default로 내보내면 중괄호{} 없이 가져오기 가능

## 가져오기 방법

1. 한꺼번에 모든 걸 가져오기 — import * as <obj>
이 방법 보다 가져올 대상을 구체적으로 명시해주는 게 좋음

이유??
1) 어차피 번들링과 최적화 과정에서 안쓰이는 리소스는 삭제
2) 이름을 간결하게 써줄 수 있음
(`<obj>.함수명` 대신 `함수명`만 적어도 사용 가능)
3) 코드 구조를 파악하기 쉬워 리팩토링이나 유지보수에 도움

2. `import 원래 이름 ‘as’ 변경하고 싶은 이름` 로 이름 바꿔서 가져오기

## 다시 내보내기

1. `export … from …` 사용하면 가져온 개체 즉시 다시 내보내기 가능
(단, `export * from "module”` 사용하면 default export는 다시 내보내지지 않음, 2번 방법으로 default는 따로 다시 내보내야함)

ex)

```jsx
//1-2 모두 login과 logout을 가지고 온 후 바로 내보내는 코드

//1
import {login, logout} from './helpers.js';
export {login, logout};

//2
export {login, logout} from './helpers.js';
```

2. `export {default as …}`로 다시 내보내기