You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/2-events/01-introduction-browser-events/article.md
+1-36Lines changed: 1 addition & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,11 +24,7 @@
24
24
**CSS 이벤트:**
25
25
-`transitionend` -- CSS 애니메이션이 종료되었을 때 발생합니다.
26
26
27
-
<<<<<<< HEAD
28
27
이 외에도 다양한 이벤트가 있는데, 몇몇 이벤트는 다음 챕터에서 자세히 다룰 예정입니다.
29
-
=======
30
-
There are many other events. We'll get into more details of particular events in upcoming chapters.
31
-
>>>>>>> upstream/master
32
28
33
29
## 이벤트 핸들러
34
30
@@ -164,11 +160,7 @@ button.onclick = sayThanks;
164
160
button.onclick=sayThanks();
165
161
```
166
162
167
-
<<<<<<< HEAD
168
163
`sayThanks()` 같이 괄호를 덧붙이는 것은 함수를 호출하겠다는 것을 의미합니다. 위 예시의 마지막 줄처럼 sayThanks()를 프로퍼티에 할당하면 함수 호출의 *결괏(result)값*이 할당되죠. 함수 `sayThanks`가 아무것도 반환하지 않는다면 `onclick` 프로퍼티엔 `undefined`이 할당되므로 이벤트가 원하는 대로 동작하지 않습니다.
169
-
=======
170
-
If we add parentheses, then `sayThanks()` becomes a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work.
input.onclick=function() { alert(2); } // 이전 핸들러를 덮어씀
220
208
```
221
209
222
-
<<<<<<< HEAD
223
210
웹 표준에 관여하는 개발자들은 오래전부터 이 문제를 인지하고, `addEventListener` 와 `removeEventListener` 라는 특별한 메서드를 이용해 핸들러를 관리하자는 대안을 제시했습니다. 핸들러를 여러 개 할당할 수 있도록 말이죠.
224
-
=======
225
-
Developers of web standards understood that long ago and suggested an alternative way of managing handlers using the special methods `addEventListener` and `removeEventListener` which aren't bound by such constraint.
: 이벤트를 처리하는 요소. 화살표 함수를 사용해 핸들러를 만들거나 다른 곳에 바인딩하지 않은 경우엔 `this`가 가리키는 값과 같음, 화살표 함수를 사용했거나 함수를 다른 곳에 바인딩한 경우엔 `event.currentTarget`를 사용해 이벤트가 처리되는 요소 정보를 얻을 수 있음
360
336
361
-
<<<<<<< HEAD
362
-
`event.clientX / event.clientY`
337
+
`event.clientX` / `event.clientY`
363
338
: 포인터 관련 이벤트에서, 커서의 상대 좌표(모니터 기준 좌표가 아닌, 브라우저 화면 기준 좌표 - 옮긴이)
364
339
365
340
이 외에도 다양한 프로퍼티가 있습니다. 이벤트 타입에 따라 이벤트 객체에서 제공하는 프로퍼티는 다릅니다. 추후 다양한 종류의 이벤트를 학습하면서 이벤트별 프로퍼티에 대해서도 상세히 알아보겠습니다.
366
-
=======
367
-
`event.clientX` / `event.clientY`
368
-
: Window-relative coordinates of the cursor, for pointer events.
369
-
370
-
There are more properties. Many of them depend on the event type: keyboard events have one set of properties, pointer events - another one, we'll study them later when as we move on to the details of different events.
371
-
>>>>>>> upstream/master
372
341
373
342
````smart header="이벤트 객체는 HTML 핸들러 안에서도 접근할 수 있습니다."
374
343
HTML에서 핸들러를 할당한 경우에도 아래와 같이 `event` 객체를 사용할 수 있습니다.
@@ -404,11 +373,7 @@ HTML에서 핸들러를 할당한 경우에도 아래와 같이 `event` 객체
404
373
405
374
보시다시피 `addEventListener`가 인수로 객체 형태의 핸들러를 받으면 이벤트 발생 시 `obj.handleEvent(event)`가 호출됩니다.
406
375
407
-
<<<<<<< HEAD
408
376
클래스를 사용할 수도 있습니다.
409
-
=======
410
-
We could also use objects of a custom class, like this:
Copy file name to clipboardExpand all lines: 2-ui/2-events/02-bubbling-and-capturing/article.md
+8-53Lines changed: 8 additions & 53 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -120,46 +120,27 @@
120
120
121
121
이벤트엔 버블링 이외에도 '캡처링(capturing)' 이라는 흐름이 존재합니다. 실제 코드에서 자주 쓰이진 않지만, 종종 유용한 경우가 있으므로 알아봅시다.
122
122
123
-
<<<<<<< HEAD
124
-
표준 [DOM 이벤트](http://www.w3.org/TR/DOM-Level-3-Events/)에서 정의한 이벤트 흐름엔 3가지 단계가 있습니다.
125
-
=======
126
-
The standard [DOM Events](https://www.w3.org/TR/DOM-Level-3-Events/) describes 3 phases of event propagation:
127
-
>>>>>>> upstream/master
123
+
표준 [DOM 이벤트](https://www.w3.org/TR/DOM-Level-3-Events/)에서 정의한 이벤트 흐름엔 3가지 단계가 있습니다.
128
124
129
125
1. 캡처링 단계 -- 이벤트가 하위 요소로 전파되는 단계
130
126
2. 타깃 단계 -- 이벤트가 실제 타깃 요소에 전달되는 단계
131
127
3. 버블링 단계 -- 이벤트가 상위 요소로 전파되는 단계
132
128
133
-
<<<<<<< HEAD
134
129
테이블 안의 `<td>`를 클릭하면 어떻게 이벤트가 흐르는지 아래 그림을 보고 이해해 봅시다.
135
-
=======
136
-
Here's the picture, taken from the specification, of the capturing `(1)`, target `(2)` and bubbling `(3)` phases for a click event on a `<td>` inside a table:
137
-
>>>>>>> upstream/master
138
130
139
131

140
132
141
133
`<td>`를 클릭하면 이벤트가 최상위 조상에서 시작해 아래로 전파되고(캡처링 단계), 이벤트가 타깃 요소에 도착해 실행된 후(타깃 단계), 다시 위로 전파됩니다(버블링 단계). 이런 과정을 통해 요소에 할당된 이벤트 핸들러가 호출됩니다.
142
134
143
-
<<<<<<< HEAD
144
-
**캡처링 단계를 이용해야 하는 경우는 흔치 않기 때문에, 이전까진 주로 버블링만 설명했습니다. 캡처링에 관한 코드를 발견하는 일은 거의 없을 겁니다.**
135
+
캡처링 단계를 이용해야 하는 경우는 흔치 않기 때문에, 이전까진 주로 버블링만 설명했습니다. 캡처링에 관한 코드를 발견하는 일은 거의 없을 겁니다.
145
136
146
137
`on<event>` 프로퍼티나 HTML 속성, `addEventListener(event, handler)`를 이용해 할당된 핸들러는 캡처링에 대해 전혀 알 수 없습니다. 이 핸들러들은 두 번째 혹은 세 번째 단계의 이벤트 흐름(타깃 단계와 버블링 단계)에서만 동작합니다.
147
-
=======
148
-
Until now, we only talked about bubbling, because the capturing phase is rarely used.
149
-
150
-
In fact, the capturing phase was invisible for us, because handlers added using `on<event>`-property or using HTML attributes or using two-argument `addEventListener(event, handler)` don't know anything about capturing, they only run on the 2nd and 3rd phases.
151
-
>>>>>>> upstream/master
152
138
153
139
캡처링 단계에서 이벤트를 잡아내려면 `addEventListener`의 `capture` 옵션을 `true`로 설정해야 합니다.
1.`HTML` -> `BODY` -> `FORM` -> `DIV` (캡처링 단계, 첫 번째 리스너)
204
-
2.`P` (타깃 단계, 캡쳐링과 버블링 둘 다에 리스너를 설정했기 때문에 두 번 호출됩니다.)
184
+
2.`P` (타깃 단계, 캡처링과 버블링 둘 다에 리스너를 설정했기 때문에 두 번 호출됩니다.)
205
185
3.`DIV` -> `FORM` -> `BODY` -> `HTML` (버블링 단계, 두 번째 리스너)
206
-
=======
207
-
1.`HTML` -> `BODY` -> `FORM` -> `DIV -> P` (capturing phase, the first listener):
208
-
2.`P` -> `DIV` -> `FORM` -> `BODY` -> `HTML` (bubbling phase, the second listener).
209
-
210
-
Please note, the `P` shows up twice, because we've set two listeners: capturing and bubbling. The target triggers at the end of the first and at the beginning of the second phase.
211
-
>>>>>>> upstream/master
212
186
213
187
`event.eventPhase` 프로퍼티를 이용하면 현재 발생 중인 이벤트 흐름의 단계를 알 수 있습니다. 반환되는 정숫값에 따라 이벤트 흐름의 현재 실행 단계를 구분할 수 있죠. 하지만 핸들러를 통해 흐름 단계를 알 수 있기 때문에 이 프로퍼티는 자주 사용되지 않습니다.
214
188
215
189
```smart header="핸들러를 제거할 때 `removeEventListener`가 같은 단계에 있어야 합니다."
216
190
`addEventListener(..., true)`로 핸들러를 할당해 줬다면, 핸들러를 지울 때, `removeEventListener(..., true)`를 사용해 지워야 합니다. 같은 단계에 있어야 핸들러가 지워집니다.
217
191
```
218
192
219
-
<<<<<<< HEAD
220
193
````smart header="같은 요소와 같은 단계에 설정한 리스너는 설정한 순서대로 동작합니다."
221
194
특정 요소에 `addEventListener`를 사용해 한 단계에 이벤트 핸들러를 여러개 설정했다면 이 핸들러들은 설정한 순서대로 동작합니다.
222
-
=======
223
-
````smart header="Listeners on the same element and same phase run in their set order"
224
-
If we have multiple event handlers on the same phase, assigned to the same element with `addEventListener`, they run in the same order as they are created:
225
-
>>>>>>> upstream/master
226
195
227
196
```js
228
197
elem.addEventListener("click", e => alert(1)); // 첫 번째로 트리거됩니다.
229
198
elem.addEventListener("click", e => alert(2));
230
199
```
231
200
````
232
201
233
-
```smart header="The `event.stopPropagation()` during the capturing also prevents the bubbling"
234
-
The `event.stopPropagation()` method and its sibling `event.stopImmediatePropagation()` can also be called on the capturing phase. Then not only the futher capturing is stopped, but the bubbling as well.
202
+
```smart header="캡처링 단계에서 `event.stopPropagation()`을 호출하면 버블링도 막힙니다."
203
+
`event.stopPropagation()` 메서드와 형제 메서드인 `event.stopImmediatePropagation()`은 캡처링 단계에서도 호출할 수 있습니다. 이 경우 캡처링이 더 이상 진행되지 않을 뿐만 아니라 버블링도 중단됩니다.
235
204
236
-
In other words, normally the event goes first down ("capturing") and then up ("bubbling"). But if `event.stopPropagation()` is called during the capturing phase, then the event travel stops, no bubbling will occur.
205
+
다시 말해, 이벤트는 보통 먼저 아래로 내려가다가("캡처링") 다시 위로 올라갑니다("버블링"). 하지만 캡처링 단계에서 `event.stopPropagation()`이 호출되면 이벤트 전파가 멈추고, 버블링은 발생하지 않습니다.
237
206
```
238
207
239
208
240
209
## 요약
241
210
242
211
이벤트가 발생하면 이벤트가 발생한 가장 안쪽 요소가 '타깃 요소(`event.target`)'가 됩니다.
243
212
244
-
<<<<<<< HEAD
245
213
- 이벤트는 document에서 시작해 DOM 트리를 따라 `event.target`까지 내려갑니다. 이벤트는 트리를 따라 내려가면서 `addEventListener(..., true)`로 할당한 핸들러를 동작시킵니다. `addEventListener(..., true)`의 `true`는 `{capture: true}`의 축약형입니다.
246
214
- 이후 타깃 요소에 설정된 핸들러가 호출됩니다.
247
215
- 이후엔 이벤트가 `event.target`부터 시작해서 다시 최상위 노드까지 전달되면서 각 요소에 `on<event>`로 할당한 핸들러와 `addEventListener`로 할당한 핸들러를 동작시킵니다. `addEventListener`로 할당한 핸들러 중, 세 번째 인수가 없거나 `false`, `{capture: false}`인 핸들러만 호출됩니다.
248
-
=======
249
-
- Then the event moves down from the document root to `event.target`, calling handlers assigned with `addEventListener(..., true)` on the way (`true` is a shorthand for `{capture: true}`).
250
-
- Then handlers are called on the target element itself.
251
-
- Then the event bubbles up from `event.target` to the root, calling handlers assigned using `on<event>`, HTML attributes and `addEventListener` without the 3rd argument or with the 3rd argument `false/{capture:false}`.
252
-
>>>>>>> upstream/master
253
216
254
217
각 핸들러는 아래와 같은 `event` 객체의 프로퍼티에 접근할 수 있습니다.
255
218
@@ -259,18 +222,10 @@ In other words, normally the event goes first down ("capturing") and then up ("b
259
222
260
223
핸들러에서 `event.stopPropagation()`을 사용해 이벤트 버블링을 멈출 수 있습니다. 다만, 이 방법은 추천하지 않습니다. 지금은 상위 요소에서 이벤트가 어떻게 쓰일지 확실치 않더라도, 추후에 버블링이 필요한 경우가 생기기 때문입니다.
261
224
262
-
<<<<<<< HEAD
263
225
캡처링 단계는 거의 쓰이지 않고, 주로 버블링 단계의 이벤트만 다뤄집니다. 이렇게 된 데는 논리적 배경이 있습니다.
264
-
=======
265
-
The capturing phase is used very rarely, usually we handle events on bubbling. And there's a logical explanation for that.
266
-
>>>>>>> upstream/master
267
226
268
227
현실에서 사고가 발생하면 지역 경찰이 먼저 사고를 조사합니다. 그 지역에 대해 가장 잘 아는 기관은 지역 경찰이기 때문입니다. 추가 조사가 필요하다면 그 이후에 상위 기관이 사건을 넘겨받습니다.
269
228
270
-
<<<<<<< HEAD
271
-
이벤트 핸들러도 이와 같은 논리로 만들어졌습니다. 특정 요소에 할당된 핸들러는 그 요소에 대한 자세한 사항과 무슨 일을 해야 할지 가장 잘 알고 있습니다. `<td>`에 할당된 핸들러는 `<td>`에 대한 모든 것을 알고 있기 때문에 `<td>`를 다루는데 가장 적합합니다. 따라서 `<td>`를 다룰 기회를 이 요소에 할당된 핸들러에게 가장 먼저 주는 것입니다.
272
-
=======
273
-
The same for event handlers. The code that set the handler on a particular element knows maximum details about the element and what it does. A handler on a particular `<td>` may be suited for that exactly `<td>`, it knows everything about it, so it should get the chance first. Then its immediate parent also knows about the context, but a little bit less, and so on till the very top element that handles general concepts and runs the last one.
274
-
>>>>>>> upstream/master
229
+
이벤트 핸들러도 이와 같은 논리로 만들어졌습니다. 특정 요소에 할당된 핸들러는 그 요소에 대한 자세한 사항과 무슨 일을 해야 할지 가장 잘 알고 있습니다. `<td>`에 할당된 핸들러는 `<td>`에 대한 모든 것을 알고 있기 때문에 `<td>`를 다루는데 가장 적합합니다. 따라서 `<td>`를 다룰 기회를 이 요소에 할당된 핸들러에게 가장 먼저 주는 것입니다. 바로 위 부모 요소도 자식 요소만큼은 아니지만 관련 맥락을 알고 있으며, 이런 식으로 최상위 요소까지 거슬러 올라가 마지막에는 가장 일반적인 개념을 다루는 핸들러가 실행됩니다.
275
230
276
231
버블링과 캡처링은 '이벤트 위임(event delegation)'의 토대가 됩니다. 이벤트 위임은 강력한 이벤트 핸들링 패턴입니다. 다음 챕터에서 이를 다루도록 하겠습니다.
`addEventListener`의 `passive: true` 옵션은 브라우저에게 `preventDefault()`를 호출하지 않겠다고 알리는 역할을 합니다.
102
98
103
-
<<<<<<< HEAD
104
99
이 옵션은 왜 필요한 걸까요?
105
-
=======
106
-
Why might that be needed?
107
-
>>>>>>> upstream/master
108
100
109
101
모바일 기기에는 사용자가 스크린에 손가락을 대고 움직일 때 발생하는 `touchmove`와 같은 이벤트가 있습니다. 이런 이벤트는 기본적으로 스크롤링(scrolling)을 발생시킵니다. 그런데 핸들러의 `preventDefault()`를 사용하면 스크롤링을 막을 수 있습니다.
0 commit comments