Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Part 2 - 2.1 브라우저 이벤트 소개 과제 4-7 문제 & 해설 번역 (#1546) #1587

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

First we need to choose a method of positioning the ball.
우선 공을 배치하는 방법을 선택해야 합니다.

We can't use `position:fixed` for it, because scrolling the page would move the ball from the field.
페이지를 스크롤 하면 공이 필드에서 이동하므로 `position:fixed`를 사용할 수 없습니다.

So we should use `position:absolute` and, to make the positioning really solid, make `field` itself positioned.
따라서 `position:absolute`를 사용해야 하고 위치 잡기를 정말 견고하게 하기 위해서는 `field` 자체를 위치 잡기 해야 합니다.

Then the ball will be positioned relatively to the field:
그러면 공은 필드에 상대적으로 배치됩니다.

```css
#field {
Expand All @@ -16,36 +16,36 @@ Then the ball will be positioned relatively to the field:

#ball {
position: absolute;
left: 0; /* relative to the closest positioned ancestor (field) */
left: 0; /* 가장 가깝게 배치된 조상(field)에 상대적으로 위치하기 */
top: 0;
transition: 1s all; /* CSS animation for left/top makes the ball fly */
transition: 1s all; /* CSS 애니메이션으로 왼쪽·위쪽으로 공이 날아가는 효과를 구현합니다 */
}
```

Next we need to assign the correct `ball.style.left/top`. They contain field-relative coordinates now.
그런 다음 올바른 `ball.style.left/top`을 할당해야 합니다. 이제 상대적인 필드 기준 좌표가 포함됩니다.

Here's the picture:
사진은 다음과 같습니다.

![](move-ball-coords.svg)

We have `event.clientX/clientY` -- window-relative coordinates of the click.
클릭한 위치의 창 기준 좌표를 표시하는 `event.clientX/clientY`가 있습니다.

To get field-relative `left` coordinate of the click, we can substract the field left edge and the border width:
클릭 시 필드에 상대적인 `left` 좌표를 구하려면 필드의 왼쪽 가장자리와 테두리의 너비를 빼면 됩니다.

```js
let left = event.clientX - fieldCoords.left - field.clientLeft;
```

Normally, `ball.style.left` means the "left edge of the element" (the ball). So if we assign that `left`, then the ball edge, not center, would be under the mouse cursor.
일반적으로 `ball.style.left`는 '요소(공)의 왼쪽 가장자리'를 의미합니다. 따라서 `left`를 할당하면 공의 중앙이 아닌 가장자리가 마우스 커서 아래로 오게 됩니다.

We need to move the ball half-width left and half-height up to make it center.
중앙으로 가게 만들려면 공을 왼쪽으로 반너비, 위쪽으로 반 높이 이동해야 합니다.

So the final `left` would be:
따라서 `left`는 최종적으로 다음과 같습니다.

```js
let left = event.clientX - fieldCoords.left - field.clientLeft - ball.offsetWidth/2;
```

The vertical coordinate is calculated using the same logic.
수직 좌표는 같은 논리를 사용하여 계산됩니다.

Please note that the ball width/height must be known at the time we access `ball.offsetWidth`. Should be specified in HTML or CSS.
공의 너비·높이는 `ball.offsetWidth`에 접근할 때 알아야 한다는 점을 주의해 주세요. HTML 또는 CSS로 지정해야 합니다.
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@ importance: 5

---

# Move the ball across the field
# 필드를 가로질러 공 이동하기

Move the ball across the field to a click. Like this:
클릭으로 필드를 가로질러 공을 이동해 주세요.

예시:
[iframe src="solution" height="260" link]

Requirements:
요구사항은 다음과 같습니다.

- The ball center should come exactly under the pointer on click (if possible without crossing the field edge).
- CSS-animation is welcome.
- The ball must not cross field boundaries.
- When the page is scrolled, nothing should break.
- 공의 중앙이 클릭 시 포인터 바로 아래에 와야 합니다(가능하면 필드 가장자리를 넘지 않아야 함).
- CSS-animation을 사용하는 것도 환영합니다.
- 공은 필드의 경계를 넘어서면 안 됩니다.
- 페이지를 스크롤 할 때 깨짐 현상이 없어야 합니다.

Notes:
이 두 가지를 주의하세요.

- The code should also work with different ball and field sizes, not be bound to any fixed values.
- Use properties `event.clientX/event.clientY` for click coordinates.
- 해당 코드는 특정 값에 고정되지 않고, 다른 공과 필드 크기에서도 작동해야 합니다.
- 클릭 좌표에 `event.clientX/event.clientY` 프로퍼티를 사용하세요.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

# HTML/CSS
First let's create HTML/CSS.
# HTML·CSS
먼저 HTML·CSS를 만들어 봅시다.

A menu is a standalone graphical component on the page, so it's better to put it into a single DOM element.
메뉴는 페이지의 독립적으로 실행하는 그래픽 구성요소이므로 단일 DOM 요소에 놓는 것이 좋습니다.

A list of menu items can be laid out as a list `ul/li`.
메뉴 항목 목록은 목록 `ul/li`로 배치할 수 있습니다.

Here's the example structure:
다음은 메뉴 구조 예시입니다.

```html
<div class="menu">
Expand All @@ -19,29 +19,29 @@ Here's the example structure:
</div>
```

We use `<span>` for the title, because `<div>` has an implicit `display:block` on it, and it will occupy 100% of the horizontal width.
`<div>`는 암시적으로 `display:block`을 가지고 있으며 가로 너비의 100%를 차지하기 때문에 제목에는 `<span>`을 사용합니다.

Like this:
이렇게 말이죠.

```html autorun height=50
<div style="border: solid red 1px" onclick="alert(1)">Sweeties (click me)!</div>
```

So if we set `onclick` on it, then it will catch clicks to the right of the text.
그래서 `onclick`을 설정하면 텍스트 오른쪽에 클릭이 나타납니다.

As `<span>` has an implicit `display: inline`, it occupies exactly enough place to fit all the text:
`<span>`에는 암시적으로 `display: inline`이 있으므로 모든 텍스트에 정확히 맞도록 충분한 공간을 차지합니다.

```html autorun height=50
<span style="border: solid red 1px" onclick="alert(1)">Sweeties (click me)!</span>
```

# Toggling the menu
# 메뉴 토글 하기

Toggling the menu should change the arrow and show/hide the menu list.
메뉴를 토글 하면 화살표 방향이 바뀌고 메뉴 목록이 표시되거나 숨겨져야 합니다.

All these changes are perfectly handled by CSS. In JavaScript we should label the current state of the menu by adding/removing the class `.open`.
이 모든 변경 사항은 CSS로 처리할 수 있습니다. 자바스크립트에서 클래스 `.open`을 추가·제거하여 현재 메뉴 상태를 구분해야 합니다.

Without it, the menu will be closed:
`.open`이 없으면 메뉴는 닫힙니다.

```css
.menu ul {
Expand All @@ -58,7 +58,7 @@ Without it, the menu will be closed:
}
```

...And with `.open` the arrow changes and the list shows up:
`.open`을 사용하면 화살표가 바뀌고 목록이 표시됩니다.

```css
.menu.open .title::before {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ importance: 5

---

# Create a sliding menu
# 슬라이드 메뉴 구현하기

Create a menu that opens/collapses on click:
클릭 시 열리거나 접히는 메뉴를 구현해보세요.

[iframe border=1 height=100 src="solution"]

P.S. HTML/CSS of the source document is to be modified.
주의사항: 원본 문서의 HTML·CSS를 수정해야 합니다.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

To add the button we can use either `position:absolute` (and make the pane `position:relative`) or `float:right`. The `float:right` has the benefit that the button never overlaps the text, but `position:absolute` gives more freedom. So the choice is yours.
닫기 버튼을 추가하려면 `position:absolute`(그리고 패널을 `position:relative`로 설정하기) 또는 `float:right` 중 하나를 사용할 수 있습니다. `float:right`는 버튼이 텍스트와 절대 겹치지 않는다는 장점이 있지만 `position:absolute`로는 더 자유롭게 배치할 수 있습니다. 어떤 방법을 사용할지 선택하세요.

Then for each pane the code can be like:
각 패널의 코드는 다음과 같습니다.
```js
pane.insertAdjacentHTML("afterbegin", '<button class="remove-button">[x]</button>');
```

Then the `<button>` becomes `pane.firstChild`, so we can add a handler to it like this:
그러면 `<button>``pane.firstChild`가 되므로 다음과 같이 핸들러를 추가할 수 있습니다.

```js
pane.firstChild.onclick = () => pane.remove();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ importance: 5

---

# Add a closing button
# 닫기 버튼 추가하기

There's a list of messages.
메시지 목록이 있습니다.

Use JavaScript to add a closing button to the right-upper corner of each message.
자바스크립트를 사용해 각 메시지의 오른쪽 위 모서리에 닫기 버튼을 추가해보세요.

The result should look like this:
결과물은 다음과 같아야 합니다.

[iframe src="solution" height=450]
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
The images ribbon can be represented as `ul/li` list of images `<img>`.
이미지 슬라이드는 이미지 `<img>`의 `ul/li` 목록으로 나타낼 수 있습니다.

Normally, such a ribbon is wide, but we put a fixed-size `<div>` around to "cut" it, so that only a part of the ribbon is visible:
일반적으로 이런 이미지 슬라이드는 폭이 넓지만, 슬라이드 일부만 보이도록 고정 크기의 `<div>`로 감쌌습니다.

![](carousel1.svg)

To make the list show horizontally we need to apply correct CSS properties for `<li>`, like `display: inline-block`.
이미지 목록을 가로로 표시하려면 `<li>``display: inline-block`과 같은 올바른 CSS 프로퍼티를 적용해야 합니다.

For `<img>` we should also adjust `display`, because by default it's `inline`. There's extra space reserved under `inline` elements for "letter tails", so we can use `display:block` to remove it.
`<img>``display`가 기본적으로 `inline`이므로 조정해야 합니다. '문자의 끝(letter tails)'을 위한 `inline` 요소 아래에 여분의 공간이 확보되어 있으므로 `display:block`을 사용해 삭제하겠습니다.

To do the scrolling, we can shift `<ul>`. There are many ways to do it, for instance by changing `margin-left` or (better performance) use `transform: translateX()`:
스크롤 하려면 `<ul>`을 이동하면 됩니다. `margin-left`를 바꾸거나 `transform: translateX()`(더 나은 기능 구현을 위해)를 사용하는 등 여러 가지 방법이 있습니다.

![](carousel2.svg)

The outer `<div>` has a fixed width, so "extra" images are cut.
외부 `<div>`는 고정된 너비를 가지고 있으므로 '여분' 이미지는 잘립니다.

The whole carousel is a self-contained "graphical component" on the page, so we'd better wrap it into a single `<div class="carousel">` and style things inside it.
캐러셀 전체는 페이지에 독립된 '그래픽 구성 요소(graphical component)'이므로 단일 `<div class="carousel">`로 감싸서 그 안에서 스타일링 하는 것이 좋습니다.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ importance: 4

---

# Carousel
# 캐러셀

Create a "carousel" -- a ribbon of images that can be scrolled by clicking on arrows.
'캐러셀'(화살표를 클릭하여 스크롤 할 수 있는 이미지 슬라이드)을 만들어보세요.

[iframe height=200 src="solution"]

Later we can add more features to it: infinite scrolling, dynamic loading etc.
무한 스크롤, 동적 로딩 등 더 많은 기능은 나중에 추가할 수 있습니다.

P.S. For this task HTML/CSS structure is actually 90% of the solution.
힌트를 드리자면, 이 과제에서는 HTML·CSS 구조가 해답의 90%입니다.