Merge remote-tracking branch 'upstream/main'

pull/90/head
Eugene Goh 4 years ago
commit 5e77c4f4a8

@ -3,8 +3,8 @@
![All About Accessibility](webdev101-a11y.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
[クチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/5?loc=ja)
## レッスン前の小テスト
[ッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/5?loc=ja)
> Web の力は、その普遍性にあります。障害の有無に関わらず、誰もがアクセスできることが重要です。
>
@ -215,8 +215,8 @@ CSS は、ページ上のあらゆる要素の外観を完全に制御するこ
</html>
```
## レクチャー後クイズ
[クチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/6?loc=ja)
## レッスン後の小テスト
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/6?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# 접근성이 좋지 않은 웹 사이트 분석하기
## 설명
여러분이 접근할 수 없다고 생각하는 사이트를 식별해보고, 접근성을 개선할 수 있는 실행 계획을 만들어봅니다. 여러분의 첫 과제는 사이트를 식별하고 분석 도구를 사용하지 않고 사이트에 접근할 수 없는 방법을 자세히 설명한 다음, Lighthouse 분석을 통해 그 사이트를 확인하는 것입니다. 분석의 결과를 가지고 사이트를 개선할 수 있는 10가지 포인트를 가진 세부 계획을 개략적으로 설명해봅니다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
학생 보고서 | 보고서에 Lighthouse의 진단 결과 캡쳐본이 pdf파일로 첨부되었고, 10가지의 개선점과 함께 개선방안을 포함한 단락들이 포함된 경우 | 필수조건이 20%정도 부족한 경우 | 필수조건이 50%정도 부족한 경우

@ -3,8 +3,8 @@
![JavaScript Basics - Data types](images/webdev101-js-datatypes.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
[クチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/7?loc=ja)
## レッスン前の小テスト
[ッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/7?loc=ja)
このレッスンでは、Web 上でインタラクティブな機能を提供する言語である JavaScript の基礎を学びます。
@ -184,8 +184,8 @@ let myString2 = "World";
JavaScript は、たまにデータ型を扱う際の意外な方法で悪名高いです。これらの 'gotchas' について少し調べてみてください。例えば: 大文字小文字の区別でつまずくことがあります! コンソールで以下のようにしてみてください。`let age = 1; let Age = 2; age == Age` (解決は `false` -- なぜ?) 他にどのような gotchas があるでしょうか?
## レクチャー後クイズ
[クチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/8?loc=ja)
## レッスン後の小テスト
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/8?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# 데이터 타입 연습
## 설명
쇼핑 카트를 만든다고 상상해봅시다. 필요한 데이터 타입들에 대한 문서를 작성해봅시다. 어떻게 그런 타입들을 고르게 됐습니까?
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 6가지 데이터 타입을 나열하고 자세히 살펴본 뒤 용도를 문서화한 경우 | 4가지 데이터 타입을 탐구한 답안 | 2가지 데이터 타입을 탐구한 경우

@ -3,8 +3,8 @@
![JavaScript Basics - Functions](images/webdev101-js-functions.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
[クチャー前クイズ](.github/pre-lecture-quiz.md)
## レッスン前の小テスト
[ッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/9?loc=ja)
コードを書くことを考えるとき、私たちは常にコードが読みやすいようにしたいと考えています。直感的ではないように聞こえるかもしれませんが、コードは書かれた回数よりも何度も読まれます。コードを確実にメンテナンスできるようにするための開発者のツールボックスの中心的なツールの一つが **関数** です。
@ -180,8 +180,8 @@ setTimeout(() => {
関数とメソッドの違いを一文で表現できますか?試してみてください。
## レクチャー後クイズ
[クチャー後クイズ](.github/post-lecture-quiz.md)
## レッスン後の小テスト
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/10?loc=ja)
## 復習と自己学習

@ -0,0 +1,13 @@
# 함수와 놀기
## 설명
무언가를 반환하는 함수와 아무것도 반환하지 않는 또 다른 함수를 만들어봅니다.
기본값이 없는 매개 변수와 있는 매개 변수를 잘 혼합해 함수를 만들 수 있는지를 확인합니다.
## 평가 기준
기준 | <br>모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 다양한 매개 변수를 가진 두개 이상의 잘 동작하는 함수를 포함한 답안 | 소수의 매개변수를 가진 한개의 함수를 포함한 답안 | 버그가 있는 답안

@ -3,9 +3,8 @@
![JavaScript Basics - Making decisions](images/webdev101-js-decisions.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
##
レクチャー前クイズ
[レクチャー前クイズ](.github/pre-lecture-quiz.md)
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/11?loc=ja)
意思決定を行い、コードの実行順序を制御することで、コードを再利用可能で堅牢なものにします。このセクションでは、JavaScript のデータフローを制御するための構文と、ブール値データ型で使用される場合の意味について説明します。
@ -160,9 +159,9 @@ if (firstNumber > secondNumber) {
最初に論理演算子を使ってプログラムを作成し、それを三項式で書き換えます。お好みの構文は?
## レクチャー後クイズ
## レッスン後の小テスト
[クチャー後クイズ](.github/post-lecture-quiz.md)
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/12?loc=ja)
## 復習と自己学習

@ -0,0 +1,40 @@
# 연산자
## 설명
연산자를 연습해봅니다. 여러분이 구현해볼 만한 프로그램을 제안해 드립니다.
서로 다른 방식으로 등급을 매기는 두 개의 시스템과 그 시스템에 속한 학생들이 있습니다.
### 첫번째 등급 시스템
이 등급 시스템은 1-5점으로 등급을 나눕니다. 3점 이상이면 과정을 통과했다는 의미입니다.
### 두번째 등급 시스템
다른 등급 시스템은 `A, A-, B, B-, C, C-` 등급이 있습니다. `A`가 가장 높은 등급이고 `C`가 가장 낮은 등급입니다.
### 과제
학생들과 그들의 등급의 정보가 담긴 배열 `allStudents` 이 주어집니다. 과정을 통과한 학생들을 담은 새로운 배열 `studentsWhoPass`을 만들어 주시면 됩니다.
> 팁, for-loop, if...else 그리고 비교 연산자를 사용해 보시기 바랍니다.
```javascript
let allStudents = [
'A',
'B-',
1,
4,
5,
2
]
let studentsWhoPass = [];
```
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 완전히 정답인 경우 | 부분적으로 정답인 경우 | 버그가 있는 경우

@ -3,8 +3,8 @@
![JavaScript Basics - Arrays](images/webdev101-js-arrays.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
[クチャー前クイズ](.github/pre-lecture-quiz.md)
## レッスン前の小テスト
[ッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/13?loc=ja)
このレッスンでは、Web 上でインタラクティブな機能を提供する言語である JavaScript の基礎を学びます。このレッスンでは、データを操作するために使用される配列とループについて学びます。
@ -111,8 +111,8 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
配列をループする方法は for ループと while ループ以外にもあります。[forEach](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)、[for-of](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of)、[map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map) があります。これらのテクニックのいずれかを使って、配列のループを書き換えてください。
## レクチャー後クイズ
[クチャー後クイズ](.github/post-lecture-quiz.md)
## レッスン後の小テスト
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/14?loc=ja)
## 復習と自己学習

@ -0,0 +1,13 @@
# 배열 순회하기
## 설명
1-20 사이의 숫자 중 모든 세 번째 숫자를 나열해 콘솔에 출력하는 프로그램을 만들어봅니다.
> 팁: for-loop를 사용하고 순회 표현식을 수정해봅니다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 프로그램이 올바르게 동작하며 설명하는 주석이 있는 경우 | 프로그램을 설명하는 주석이 없는 경우 | 프로그램이 불완전하거나 버그가 있는 경우

@ -3,9 +3,9 @@
![Introduction to HTML](images/webdev101-html.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
## レッスン前の小テスト
[クチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/15)
[ッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/15?loc=ja)
### イントロダクション
@ -215,9 +215,9 @@ HTML では、.html ファイルにタグを追加して Web ページの要素
HTMLに はまだ遊んで楽しいワイルドな「古い」タグがいくつかありますが、[これらのタグ](https://developer.mozilla.org/ja/docs/Web/HTML/Element#Obsolete_and_deprecated_elements)のような非推奨のタグをマークアップに使うべきではありません。それでも、古い `<marquee>` タグを使って h1 タイトルを水平方向にスクロールさせることはできますか?(もしそうする場合は、後から削除することを忘れないでください)
## レクチャー後クイズ
## レッスン後の小テスト
[クチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/16)
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/16?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# HTML 연습하기 : 블로그 모형 만들기
## 설명
여러분이 여러분의 개인 웹사이트를 디자인하거나 새로 디자인한다고 상상해봅시다. 여러분의 사이트의 그래픽 마크업을 만들어 봅시다. 그리고 사이트의 여러 요소들을 만드는 데 사용할 HTML 마크업을 작성해 봅시다. 종이에 해서 스캔해도 좋으며, 소프트웨어를 사용해도 좋습니다. HTML 마크업을 손으로 작성해보기만 하면 됩니다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 블로그 레이아웃이 10개 이상의 마크업 요소가 표시된 요소들로 표현되는 경우 | 블로그 레이아웃이 5개 정도의 마크업 요소가 표시된 요소들로 표현되는 경우 | 블로그 레이아웃이 최대 3개의 마크업 요소가 표시된 요소들로 표현되는 경우

@ -3,9 +3,9 @@
![Introduction to CSS](images/webdev101-css.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
## レッスン前の小テスト
[クチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/17)
[ッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/17?loc=ja)
### イントロダクション
@ -249,11 +249,11 @@ HTML マークアップの各植物には、id とクラスの組み合わせが
![finished terrarium](./images/terrarium-final.png)
クチャー後クイズを完成させるには、この Learn モジュールを通ってください: [HTML アプリを CSS でスタイルを整える](https://docs.microsoft.com/ja-jp/learn/modules/build-simple-website/4-css-basics)
ッスン後の小テストを完成させるには、この Learn モジュールを通ってください: [HTML アプリを CSS でスタイルを整える](https://docs.microsoft.com/ja-jp/learn/modules/build-simple-website/4-css-basics)
## レクチャー後クイズ
## レッスン後の小テスト
[クチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/18)
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/18?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# CSS 리팩터링
## 설명
Flexbox 또는 CSS Grid를 사용하여 테라리움을 다시 만들고 스크린샷을 찍어 여러 브라우저에서 테스트했음을 보여주시면 좋습니다. 마크업을 변경해야 할 수 있으므로 리팩터링 기술이 적용된 새로운 버전의 앱을 만들어 봅시다. 요소를 드래그할 수 있게 만드는 것은 생각하지 않아도 됩니다. 지금은 HTML과 CSS만 리팩터링 해봅시다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 테라리움을 Flexbox 또는 CSS Grid를 사용하여 완전히 다시 만든 경우 | 몇개의 요소만 다시 만든 경우 | 테라리움을 전혀 새로 만들지 못한 경우

@ -3,9 +3,9 @@
![DOM and a closure](images/webdev101-js.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
## レッスン前の小テスト
[クチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/19)
[ッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/19?loc=ja)
### イントロダクション
@ -199,9 +199,9 @@ function stopElementDrag() {
新しいイベントハンドラをクロージャに追加して、植物にもっと何かをするようにします。例えば、植物をダブルクリックして前の方に持ってきます。創造力を発揮してください。
## レクチャー後クイズ
## レッスン後の小テスト
[クチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/20)
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/20?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# DOM으로 좀 더 작업하기
## 설명
DOM 요소를 '채택'하여 DOM을 조금 더 조사합니다. MSDN의 [DOM 인터페이스 목록](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)을 방문하여 하나를 선택합니다. 웹의 웹 사이트에서 사용중인 것을 찾아 사용 방법에 대한 설명을 작성해봅니다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 예시와 함께 단락으로 작성한 경우 | 단락으로 작성했지만 예시가 없는 경우 | 기록이 없는 경우

@ -23,7 +23,7 @@
## 레슨
[이벤트 기반 프로그래밍을 사용하여 타이핑 게임 만들기](./project/README.md)
[이벤트 기반 프로그래밍을 사용하여 타이핑 게임 만들기](../typing-game/translations/README.ko.md)
## 크레딧

@ -1,8 +1,8 @@
# イベントを使ったゲームの作成
## レクチャー前クイズ
## レッスン前の小テスト
[クチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/21)
[ッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/21?loc=ja)
## イベント駆動型プログラミング
@ -324,9 +324,9 @@ typedValueElement.addEventListener('input', () => {
- 成功メッセージを含むモーダルダイアログボックスを表示します
- [localStorage](https://developer.mozilla.org/ja/docs/Web/API/Window/localStorage) を使ってハイスコアを保存します
## レクチャー後クイズ
## レッスン後の小テスト
[クチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/22)
[ッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/22?loc=ja)
## 復習と自己学習

@ -0,0 +1,338 @@
# 이벤트를 사용하여 게임 만들기
## 강의 전 퀴즈
[Pre-lecture quiz](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/21)
## 이벤트 기반 프로그래밍
브라우저 기반 애플리케이션을 만들 때, 사용자가 만든 것과 상호 작용하기 위한 그래픽 유저 인터페이스 (GUI)를 제공합니다. 브라우저와 상호 작용하는 가장 일반적인 방법은 다양한 요소를 클릭하고 입력하는 것입니다. 개발자로서 마주한 도전은 이러한 작업을 언제 수행할 지 모른다는 점입니다!
[Event-driven programming](https://en.wikipedia.org/wiki/Event-driven_programming)은 GUI를 만들기 위해 수행할 프로그래밍 타입의 이름입니다. 이 구문을 조금 자세히 보면, 여기서 핵심 단어가 **event**라는 점을 볼 수 있습니다. Merriam-Webster에 따르면, 이벤트는 "something which happens"로 정의됩니다. 이 상황을 완벽하게 설명합니다. 응답이라는 건 어떤 코드가 수행될 지 알고 있지만, 언제 발생할 지 모릅니다.
실행하려는 코드 섹션을 출력할 방법은 함수를 만드는 것입니다. [procedural programming](https://en.wikipedia.org/wiki/Procedural_programming)으로 생각해보면, 함수는 순차적으로 호출됩니다. 이벤트 기반 프로그래밍에서도 마찬가지입니다. 다른 점이라고 하면 함수가 호출되는 **방식**입니다.
이벤트(버튼 클릭, 타이핑 등)를 제어하기 위해서, **event listeners**를 등록합니다. 이벤트 리스너는 이벤트 발생을 수신하고 응답하는 함수입니다. 이벤트 리스너는 UI를 갱신하고, 서버를 호출하거나, 또는 작업에 응답하는 모든 작업을 수행할 수 있습니다. [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)를 사용하여 이벤트 리스너를 추가하고, 실행할 함수를 제공합니다.
> **NOTE:** 이벤트 리스너를 만드는 방법에는 여러 가지가 존재한다는 점을 강조하기에 충분합니다. 익명 함수를 사용하거나, 이름을 지어 만들 수 있습니다. `click` 속성을 설정하거나, `addEventListener`를 사용하는 등 다양한 단축으로 쓸 수 있습니다. 이 강의에서는 웹 개발자가 사용하는 가장 일반적인 기술인 `addEventLister`와 익명 함수에 초점을 맞출 것입니다. `addEventListener`가 모든 이벤트에서 작동하고, 이벤트 이름을 파라미터로 줄 수 있기 때문에 가장 유연합니다.
### 일반적인 이벤트
응용 프로그램을 만들 때 수신할 수 있는 [dozens of events](https://developer.mozilla.org/docs/Web/Events)가 있습니다. 기본적으로 사용자가 페이지에서 수행하는 모든 작업은 이벤트를 발생시키므로, 원하는 경험으로 많은 도움을 줍니다. 다행스럽게, 일반적인 이벤트만 필요합니다. 다음은 일반적 몇가지입니다 (게임을 만들 때 사용할 두 가지를 포함합니다):
- [click](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event): 사용자가 버튼 또는 하이퍼링크와 같은 무언가를 클릭했습니다
- [contextmenu](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event): 사용자가 우측 마우스 버튼을 클릭했습니다
- [select](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event): 사용자가 어떤 텍스트를 강조했습니다
- [input](https://developer.mozilla.org/en-US/docs/Web/API/Element/input_event): 사용자가 어떤 텍스트를 입력했습니다
## 게임 만들기
JavaScript에서 이벤트가 작동하는 게임을 만들 것입니다. 이 게임은 모든 개발자가 가질 과소평가된 기술 중 하나인, 타이핑 스킬을 검증합니다. 모두 타이핑 연습을 합시다! 게임의 일반적인 흐름은 다음과 같습니다:
- 플레이어가 시작 버튼을 누르면 입력할 인용문이 표시됩니다
- 플레이어는 텍스트박스에 빨리 인용문을 입력합니다
- 각 단어가 완성되면, 다음 단어가 강조됩니다
- 플레이어가 오타를 낸 경우에는, 텍스트박스가 빨간색으로 갱신됩니다
- 플레이어가 인용문을 완료하면, 경과된 시간과 함께 성공 메시지가 출력됩니다
게임을 제작하고, 이벤트에 대하여 배우겠습니다!
### 파일 구조
총 3개의 파일이 필요합니다: **index.html**, **script.js** 그리고 **style.css**. 더 편하게 살 수 있게 만들 수 있는 설정부터 시작하겠습니다.
- 콘솔 혹은 터미널 창을 열고 아래 명령을 수행하여 작업할 새로운 폴더를 만듭니다:
```bash
# Linux or macOS
mkdir typing-game && cd typing-game
# Windows
md typing-game && cd typing game
```
- Visual Studio Code를 엽니다
```bash
code .
```
- 다음 이름으로 Visual Studio Code의 폴더에 세 개의 파일을 추가합니다:
- index.html
- script.js
- style.css
## 사용자 인터페이스 만들기
요구사항을 찾아보면, HTML 페이지에 몇 요소가 필요하다는 점을 알 수 있습니다. 레시피처럼, 재료가 필요합니다:
- 사용자가 입력할 인용문을 출력할 위치
- 성공 메시지 같은, 메시지를 출력할 위치
- 입력할 텍스트박스
- 시작 버튼
각자 JavaScript에서 작업할 수 있게 ID가 필요합니다. 만드려는 CSS 및 JavaScript 파일에 대한 참조를 추가합니다.
**index.html**라고 이름지은 새로운 파일을 만듭니다. 아래 HTML을 추가합니다:
```html
<!-- inside index.html -->
<html>
<head>
<title>Typing game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Typing game!</h1>
<p>Practice your typing skills with a quote from Sherlock Holmes. Click **start** to begin!</p>
<p id="quote"></p> <!-- This will display our quote -->
<p id="message"></p> <!-- This will display any status messages -->
<div>
<input type="text" aria-label="current word" id="typed-value" /> <!-- The textbox for typing -->
<button type="button" id="start">Start</button> <!-- To start the game -->
</div>
<script src="script.js"></script>
</body>
</html>
```
### 애플리케이션 시작하기
어떻게 될 지 자주 보면서 개발하는 것이 가장 좋습니다. 애플리케이션을 시작합니다. 로컬로 애플리케이션을 호스팅하고 저장할 때마다 브라우저를 새로 고칠 [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)라는 멋진 Visual Studio Code 확장이 있습니다.
- 링크 따라 **Install** 클릭하여 [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)를 설치합니다
- 브라우저에서 Visual Studio Code를 열면, Visual Studio Code에서 설치를 수행하라는 메시지가 출력됩니다
- 메시지가 출력되면 Visual Studio Code를 다시 시작합니다
- 설치되면, Visual Studio Code에서, Ctl-Shift-P (혹은 Cmd-Shift-P)를 클릭하여 command pallate을 엽니다
- **Live Server: Open with Live Server**를 입력합니다
- Live Server가 애플리케이션 호스팅을 시작합니다
- 브라우저를 열고 **https://localhost:5500**으로 이동합니다
- 이제 만들었던 페이지를 볼 수 있습니다!
몇 가지 기능을 추가하겠습니다.
## CSS 추가하기
HTML이 만들어지면, 핵심 스타일링을 위한 CSS를 추가합니다. 플레이어가 입력할 단어를 강조하고, 입력한 내용이 잘못된 경우에는 텍스트박스에 색칠합니다. 두 클래스로 진행합니다.
**style.css**라는 새 파일을 만들고 다음 구문을 추가합니다.
```css
/* inside style.css */
.highlight {
background-color: yellow;
}
.error {
background-color: lightcoral;
border: red;
}
```
✅ CSS는 원하는대로 페이지를 레이아웃할 수 있습니다. 잠시 시간을 내서 페이지를 더 매력적으로 보일 수 있게 만들어 봅시다:
- 다른 글꼴 선택
- 헤더 색칠
- 아이템 크기 조정
## JavaScript
UI가 만들어졌으므로, 이제 로직을 제공할 JavaScript에 집중해야 합니다. 몇 단계로 나눌 것입니다:
- [Create the constants](#add-the-constants)
- [Event listener to start the game](#add-start-logic)
- [Event listener to typing](#add-typing-logic)
하지만 먼저, **script.js**라고 이름지은 새로운 파일을 생성합니다.
### 상수 추가하기
좀 더 편하게 살도록 프로그래밍할 수 있는 몇 가지 아이템이 필요합니다. 다시, 레시피와 비슷하게, 아래와 같은 것이 필요합니다:
- 모든 인용문 목록이 들어있는 배열
- 현재 인용문에 대한 모든 단어를 저장할 빈 배열
- 플레이어가 현재 입력하고 있는 단어를 색인한 저장 공간
- 플레이어가 시작을 누른 시간
UI 요소에 대한 참조도 필요합니다:
- 텍스트박스 (**typed-value**)
- 인용문 출력 (**quote**)
- 메시지 (**message**)
```javascript
// inside script.js
// all of our quotes
const quotes = [
'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.',
'There is nothing more deceptive than an obvious fact.',
'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.',
'I never make exceptions. An exception disproves the rule.',
'What one man can invent another can discover.',
'Nothing clears up a case so much as stating it to another person.',
'Education never ends, Watson. It is a series of lessons, with the greatest for the last.',
];
// store the list of words and the index of the word the player is currently typing
let words = [];
let wordIndex = 0;
// the starting time
let startTime = Date.now();
// page elements
const quoteElement = document.getElementById('quote');
const messageElement = document.getElementById('message');
const typedValueElement = document.getElementById('typed-value');
```
✅ 계속 게임에 더 많은 인용문을 추가합니다
> **NOTE:** `document.getElementById`로 원할 때마다 코드에서 요소를 찾을 수 있습니다. 이러한 요소를 계속 참조할 예정이기 때문에 문자열 리터럴로 상수를 만들어 오타를 내지 않을 것입니다. [Vue.js](https://vuejs.org/) 혹은 [React](https://reactjs.org/)와 같은 프레임워크를 사용하면 코드를 centralizing으로 관리할 수 있습니다.
잠시 시간을 내서 `const`, `let` 그리고 `var` 사용하는 방법에 대한 영상을 봅니다.
[![Types of variables](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "Types of variables")
> 변수에 대한 영상을 보려면 위의 이미지를 누릅니다.
### 시작 로직 추가하기
게임을 시작하려면, 플레이어가 시작을 누릅니다. 물론, 언제 시작을 누를지 알 수 없습니다. 여기에서 [이벤트 리스너](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)가 작동됩니다. 이벤트 리스너를 사용하면 (이벤트) 발생을 수신하고 응답해서 코드를 실행할 수 있습니다. 해당 케이스의 경우에는, 사용자가 시작을 누를 때 코드를 실행하려 합니다.
사용자가 **start**을 누르면, 인용문을 선택하고, 사용자 인터페이스를 설정하며, 현재 단어와 제한 시간를 추적해야 합니다. 다음은 추가해야 할 JavaScript 입니다. 스크립트 블록 바로 뒤에 적습니다.
```javascript
// at the end of script.js
document.getElementById('start').addEventListener('click', () => {
// get a quote
const quoteIndex = Math.floor(Math.random() * quotes.length);
const quote = quotes[quoteIndex];
// Put the quote into an array of words
words = quote.split(' ');
// reset the word index for tracking
wordIndex = 0;
// UI updates
// Create an array of span elements so we can set a class
const spanWords = words.map(function(word) { return `<span>${word} </span>`});
// Convert into string and set as innerHTML on quote display
quoteElement.innerHTML = spanWords.join('');
// Highlight the first word
quoteElement.childNodes[0].className = 'highlight';
// Clear any prior messages
messageElement.innerText = '';
// Setup the textbox
// Clear the textbox
typedValueElement.value = '';
// set focus
typedValueElement.focus();
// set the event handler
// Start the timer
startTime = new Date().getTime();
});
```
코드를 나누어 봅니다!
- 단어를 추적하도록 설정합니다
- [Math.floor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/floor)과 [Math.random](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random)을 사용하면 `quotes` 배열에서 인용문을 무작위로 선택할 수 있습니다
- 플레이어가 현재 입력하고 있는 단어를 추적할 수 있도록 `quote``words` 배열로 변환합니다
- 플레이어는 첫번째 단어부터 시작하므로, `wordIndex`는 0으로 설정합니다
- UI를 설정합니다
- `span` 요소 안에 각 단어를 포함하고 있는, `spanWords` 배열을 만듭니다
- 화면에서 단어를 강조하여 출력할 수 있습니다
- 배열을 `join`하여 `quoteElement``innerHTML`로 갱신할 때 사용할 문자열을 만듭니다
- 플레이어에게 인용문을 출력합니다
- 첫 번째 `span` 요소의 `className``highlight`로 설정하여 노란색을 강조합니다
- `innerText``''`로 설정하여 `messageElement`로 정리합니다
- 텍스트박스를 설정합니다
- `typedValueElement`의 현재 `value`를 지웁니다
- `focus``typedValueElement`로 설정합니다
- `getTime`로 호출하여 타이머를 시작합니다
### 타이핑 로직 추가하기
플레이어는 입력을 하면, `input` 이벤트가 발생됩니다. 이 이벤트 리스너는 플레이어가 단어를 잘 입력하고 있는지 확인하고, 게임의 현재 상태를 제어합니다. **script.js**로 돌아가서, 마지막에 아래 코드를 추가합니다. 나중에 나누어 볼 것입니다.
```javascript
// at the end of script.js
typedValueElement.addEventListener('input', () => {
// Get the current word
const currentWord = words[wordIndex];
// get the current value
const typedValue = typedValueElement.value;
if (typedValue === currentWord && wordIndex === words.length - 1) {
// end of sentence
// Display success
const elapsedTime = new Date().getTime() - startTime;
const message = `CONGRATULATIONS! You finished in ${elapsedTime / 1000} seconds.`;
messageElement.innerText = message;
} else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) {
// end of word
// clear the typedValueElement for the new word
typedValueElement.value = '';
// move to the next word
wordIndex++;
// reset the class name for all elements in quote
for (const wordElement of quoteElement.childNodes) {
wordElement.className = '';
}
// highlight the new word
quoteElement.childNodes[wordIndex].className = 'highlight';
} else if (currentWord.startsWith(typedValue)) {
// currently correct
// highlight the next word
typedValueElement.className = '';
} else {
// error state
typedValueElement.className = 'error';
}
});
```
코드를 나누어 봅니다! 현재 단어와 플레이어가 지금까지 입력한 값들을 알아가는 것으로 시작합니다. waterfall 로직으로서, 인용문과 단어가 온전한지, 단어가 올바른지, 혹은 (마지막으로) 오류가 있는지 확인합니다.
- 인용문이 완성되었습니다, `typedValue``currentWord`와 같고, `wordIndex``words``length`보다 하나 정도 적습니다
- 현재 시간에서 `startTime`을 빼서 `elapsedTime`을 계산합니다
- `elapsedTime`을 1,000으로 나누어 밀리 초에서 초로 변환합니다
- 성공 메시지 출력합니다
- 단어가 완성되었습니다, 공백(단어의 끝)으로 끝나는 `typedValue``currentWord`같은 `typedValue`로 출력합니다
- `typedElement``value``''`로 설정하여 다음 단어를 입력할 수 있습니다
- `wordIndex`를 증가시켜서 다음 단어로 이동합니다
- `quoteElement`의 모든 `childNodes`를 반복하여 `className``''`로 설정해서 기본적으로 출력되는 것으로 되돌립니다
- 현재 단어의 `className``highlight`로 설정하여 입력할 다음 단어를 플래그로 지정합니다
- 단어가 현재 올바르게 입력되었지만 (완전하지 않습니다), `typedValue`로 시작된 `currentWord`를 출력합니다
- `className`을 지워서 `typedValueElement`가 기본적으로 출력되는지 확인합니다
- 여기까지 도달해보면, 오류가 존재합니다
- `typedValueElement``className``error`로 설정합니다
## 애플리케이션 테스트하기
마지막까지 진행했습니다! 마지막 단계는 애플리케이션이 작동되는지 확인합니다. 한번 해보시기 바랍니다! 오류가 있어도 걱정하지 마세요; **모든 개발자**는 오류를 경험합니다. 메시지를 확인하고 필요하면 디버그합니다.
**start**를 클릭하고, 바로 입력합니다! 전에 본 애니메이션과 약간 비슷해보입니다.
![Animation of the game in action](../../images/demo.gif)
---
## 🚀 도전
더 많은 기능을 추가해봅니다
- 완성할 때 `input` 이벤트 리스너를 끄고, 버튼을 클릭하면 다시 키기
- 플레이어가 인용문을 다 작성하면 텍스트박스 끄기
- 성공 메시지와 함께 다이얼로그 박스 출력하기
- [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)를 사용하여 고득점 저장하기
## 강의 후 퀴즈
[Post-lecture quiz](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/22)
## 리뷰 & 자기주도 학습
웹 브라우저를 통해 [all the events available]((https://developer.mozilla.org/en-US/docs/Web/Events)) to the developer를 읽고, 각 이벤트를 사용할 시나리오를 고려합니다.
## 과제
[Create a new keyboard game](../assignment.md)

@ -0,0 +1,12 @@
# 새로운 키보드 게임 만들기
## 설명
키보드 이벤트를 사용하여 작업을 수행하는 작은 게임을 만듭니다. 다른 종류의 타이핑 게임이거나 키 입력으로 화면에 픽셀을 그리는 예술 유형 게임이 될 수도 있습니다. 창의력을 발휘해보세요!
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 완전한 게임을 구현한 경우 | 최소한의 기능을 가진 게임을 구현한 경우 | 게임에 버그가 있는 경우
| | |

@ -5,7 +5,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/23)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/23?loc=ja)
### イントロダクション
@ -149,7 +149,7 @@ npm install
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/24)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/24?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# 나만의 확장 프로그램 만들기
## 설명
확장 프로그램의 예시 코드에는 스타일이 적용되어 있으나, 그대로 사용하지 않아도 됩니다. css 파일을 수정해서 나만의 멋진 확장 프로그램을 만들어봅시다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 새로운 스타일을 적용한 경우 | 스타일이 미완성된 경우 | 스타일에 오류가 있는 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/25)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/25?loc=ja)
### イントロダクション
@ -210,7 +210,7 @@ async function displayCarbonUsage(apiKey, region) {
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/26)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/26?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# API 사용하기
## 설명
API를 사용하면 매우 재밌을 것입니다. 여기에 [무료 API 리스트](https://github.com/public-apis/public-apis)가 있습니다. API를 선택하고, 문제를 해결하는 브라우저 확장프로그램을 만들어봅시다. 반려동물 사진을 충분히 가지고 있지 않은 것이 작은 문제일 수 있습니다. (그러면, [dog CEO API](https://dog.ceo/dog-api/)) 또는 더 거대한 API를 이용해보세요. - 재미있게 만들어보세요!
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 위 API를 사용하여 브라우저 확장프로그램을 만든 경우 | 일부만 API를 사용한 경우 | 오류가 있는 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/27)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/27?loc=ja)
### イントロダクション
@ -147,7 +147,7 @@ function drawIcon(value) {
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/28)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/28?loc=ja)
## 復習と自己学習

@ -0,0 +1,9 @@
# 사이트 성능 분석
웹 사이트에서 성능에 문제가 있는 영역을 보여주는 자세한 보고서를 만들어 봅시다. 사이트가 느린 이유와 속도를 높이기 위해 무엇을 할 수 있는지 분석해보세요. 브라우저 도구에만 의존하지 말고, 성능 분석을 위한 다른 도구들도 알아보세요.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 브라우저 도구 뿐만 아니라 다른 도구에서 제공하는 세부 정보를 포함하여 보고서를 만든 경우 | 브라우저 도구를 사용하여 기본적인 보고서를 만든 경우 | 최소한의 보고서를 만든 경우

@ -4,7 +4,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/29)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/29?loc=ja)
### ゲーム開発における継承とコンポジション
@ -213,7 +213,7 @@ pub-sub パターンがどのようにゲームを盛り上げるかを考えて
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/30)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/30?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# 게임 제작하기
## 설명
수업에 있는 예제 코드를 사용해서 게임을 만들어 봅시다. 간단한 게임이어야 하며, 목표는 class 또는 composition 패턴과 pub/sub 패턴 중 하나를 사용하여 게임을 만드는 것입니다. 창의력을 보여주세요!
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 화면에 세개의 요소가 있고 조작할 수 있는 경우 | 화면에 두개의 요소가 있고 조작할 수 있는 경우 | 화면에 한개의 요소가 있고 조작할 수 있는 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/31)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/31?loc=ja)
## Canvas
@ -205,7 +205,7 @@ npm start
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/32)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/32?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# Canvas API 사용하기
## 설명
Canvas API에서 한 요소를 선택하고 그 주위에 재미있는 요소를 추가해 봅시다. 수많은 별이 모인 은하수를 만들수 있나요? 색깔이 있는 선으로 특별한 질감을 만들 수 있나요? 영감이 필요한다면 CodePen을 참고해보세요. (복사하지는 마세요.)
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 특별한 질감 또는 모양을 보여주는 코드를 제출한 경우 | 코드가 제출되었지만 실행되지 않는 경우 | 코드가 제출되지 않은 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/33)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/33?loc=ja)
ゲームは、あなたが画面上を走り回るエイリアンを持っているまでは、あまり楽しいものではありません! このゲームでは、2種類の動きを使用しています。このゲームでは、2種類の動きを利用していきます。
@ -376,7 +376,7 @@ npm start
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/34)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/34?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# 코드 주석 달기
## 설명
게임 폴더에 있는 /app.js 파일을 살펴보고, 주석을 달고 정리해 봅시다. 코드가 많아지면 통제하기가 어려워질 수 있습니다. 지금 주석을 추가해서 나중에도 코드를 쉽게 파악할 수 있도록 조치해 봅시다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| `app.js` 코드가 주석으로 충분히 설명되어 있고 논리적으로 설계된 경우 | `app.js` 코드가 주석으로 적절히 설명된 경우 | `app.js` 코드가 주석으로 충분히 설명되지 않고 복잡하게 설계된 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/35)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/35?loc=ja)
このレッスンでは、JavaScript でレーザーを撃つ方法を学びます! 私たちはゲームに2つのものを追加します。
@ -287,7 +287,7 @@ npm start
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/36)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/36?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# 충돌 감지
## 설명
## 평가 기준
충돌이 어떻게 작용하는지 더 잘 이해하기 위해 충돌하는 몇 가지 항목으로 아주 작은 게임을 만들어 봅시다. 키를 누르거나 마우스 클릭으로 이동하게 하고, 부딪혔을 때는 아이템들 중 하나에 무슨 일이 일어나게 해보세요. 부딪히는 것은 지구를 강타하는 유성이거나, 범퍼카 같은 것일 수도 있습니다. 창의력을 보여주세요!
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 항목을 캔버스에 끌어다 놓거나, 기본 충돌이 발생하고, 반응이 있는 샘플 코드를 만든 경우 | 코드가 일부 미완성인 경우 | 코드에 오류가 있는 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/37)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/37?loc=ja)
このレッスンでは、ゲームに得点を加えてライフを計算する方法を学びます。
@ -179,7 +179,7 @@ npm start
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/38)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/38?loc=ja)
## 復習と自己学習

@ -0,0 +1,11 @@
# 득점 게임 만들기
## 설명
생명과 포인트를 창의적으로 보여주는 게임을 만들어 봅시다. 화면 가운데 하단에는 생명과 포인트를 큰 숫자로 나타내보세요. [무료 게임 목록](https://www.kenney.nl/)을 참고해보세요.
# 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 완성도 있는 게임을 만든 경우 | 일부만 작동하는 게임을 만든 경우 | 게임에 오류가 있는 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/39)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/39?loc=ja)
ゲーム内での表現方法や *終了条件* の表現方法は様々です。なぜゲームが終了したのかは、ゲームを作る側のあなた次第です。ここでは、あなたが今まで作ってきた宇宙ゲームの話をしていると仮定して、いくつかの理由を挙げてみましょう。
@ -212,7 +212,7 @@ npm start
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/40)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/40?loc=ja)
## 復習と自己学習

@ -0,0 +1,19 @@
# 샘플 게임 만들기
## 설명
게임이 끝나는 다양한 조건을 연습할 수 있는 작은 게임을 만들어 봅시다. 점수를 얼마나 얻어야 하는지에 따라 주인공이 목숨을 다 잃거나 모든 몬스터들이 패배합니다. 콘솔 기반 어드벤처 게임과 같은 간단한 것을 만들어봅시다. 아래 예시를 참고해서 영감을 얻어 보세요.
```
영웅> 양날검 휘두르기 - 오크는 3포인트의 데미지를 입는다.
오크> 클럽 휘두르기 - 영웅은 2포인트의 데미지를 입는다.
영웅> 발차기 - 오크는 1포인트의 데미지를 입는다.
게임> 오크가 지는 경우 - 영웅은 2코인을 얻는다.
게임> ****해치울 몬스터가 더 이상 없으면 당신은 악마의 요새를 정복한 것입니다****
```
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 완성도 있는 게임을 만든 경우 | 부분적인 게임을 구현한 경우 | 게임에 일부 버그가 있는 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/41)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/41?loc=ja)
### イントロダクション
@ -293,7 +293,7 @@ updateRoute();
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/42)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/42?loc=ja)
## 復習と自己学習

@ -0,0 +1,14 @@
# 라우팅 개선
## 설명
경로 선언에는 현재 사용할 템플릿 ID만 포함됩니다. 하지만 새 페이지를 표시할 때는 추가할 것이 더 생기는 경우가 있습니다. 두 가지 추가 기능을 사용하여 라우팅 구현을 개선해 봅시다.
- 각 템플릿에 제목을 부여하고 템플릿이 변경되면 새 제목으로 창 제목을 변경합니다.
- 템플릿 변경 후 일부 코드를 실행하는 옵션을 추가합니다. 대시보드 페이지가 표시될 때마다 개발자 콘솔에 `'대시보드가 보임'`을 출력합니다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 두 기능이 구현되고 작동하는 경우. 제목 및 코드 추가는 `routes` 선언에 추가된 새 경로에서도 작동합니다. | 두 기능은 작동하지만, 동작은 하드 코딩되어 있으며 `routes` 선언을 통해 구성할 수 없는 경우. <br> 세 번째 경로를 제목과 코드와 함께 추가하면 작동하지 않거나 부분적으로 작동합니다. | 기능 중 하나가 없거나 제대로 작동하지 않는 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/43)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/43?loc=ja)
### イントロダクション
@ -281,7 +281,7 @@ async function register() {
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/44)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/44?loc=ja)
## 復習と自己学習

@ -0,0 +1,13 @@
# 은행 앱 스타일링
## 설명
`styles.css` 파일을 만들고 현재 `index.html` 파일에 링크를 추가해봅니다. 방금 만든 CSS 파일에서 *로그인**대시 보드* 페이지가 멋지고 깔끔하게 보이도록 스타일을 추가합니다. 앱에 자체 브랜딩을 제공하기 위해 색상 테마를 만들어봅니다.
> 팁 : HTML을 수정하고 필요한 경우 새 요소와 클래스를 추가 할 수 있습니다.
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 모든 페이지가 깔끔하고 읽기 쉬우며 일관된 색상 테마와 다양한 섹션들이 적절하게 돋보이는 경우 | 페이지가 스타일링되어있지만 테마가 없거나 섹션들이 명확하게 구분되지 않은 경우 | 페이지가 스타일링되어 있지 않았으며 섹션들이 질서가 없고 정보를 읽기가 어려운 경우

@ -25,21 +25,21 @@ curl http://localhost:5000/api
## AJAX and data fetching
Traditional web sites update the content displayed when the user click on a link or submit data using a form, by reloading the full HTML page. Every time new data needs to be loaded, the web server returns a brand new HTML page that needs to be processed by the browser, interrupting the current user action and limiting interactions during the reload. This workflow is also called a *Multi-Page Application* or *MPA*.
Traditional web sites update the content displayed when the user selects a link or submits data using a form, by reloading the full HTML page. Every time new data needs to be loaded, the web server returns a brand new HTML page that needs to be processed by the browser, interrupting the current user action and limiting interactions during the reload. This workflow is also called a *Multi-Page Application* or *MPA*.
![Update workflow in a multi-page application](./images/mpa.png)
When web applications started to become more complex and interactive, a new technique called [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) emerged. This technique allows web apps to send and retrieve data from a server asynchronously using JavaScript, without having to reload the HTML page, resulting in faster updates and smoother user interactions. When new data is received from the server, the current HTML page can also be updated with JavaScript using the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) API. Over time, this approach has evolved into what we is now called a [*Single-Page Application* or *SPA*](https://en.wikipedia.org/wiki/Single-page_application).
When web applications started to become more complex and interactive, a new technique called [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) emerged. This technique allows web apps to send and retrieve data from a server asynchronously using JavaScript, without having to reload the HTML page, resulting in faster updates and smoother user interactions. When new data is received from the server, the current HTML page can also be updated with JavaScript using the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) API. Over time, this approach has evolved into what is now called a [*Single-Page Application* or *SPA*](https://en.wikipedia.org/wiki/Single-page_application).
![Update workflow in a single-page application](./images/spa.png)
When AJAX was first introduced, the only API available to fetch data asynchronously was [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). But modern browsers now also implement the more convenient and powerful [`Fetch` API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), which use promises and is better suited to manipulate JSON data.
When AJAX was first introduced, the only API available to fetch data asynchronously was [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). But modern browsers now also implement the more convenient and powerful [`Fetch` API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), which uses promises and is better suited to manipulate JSON data.
> While all modern browsers supports the `Fetch API`, if you want your web application to work on legacy or old browsers it's always a good idea to check the [compatibility table on caniuse.com](https://caniuse.com/fetch) first.
> While all modern browsers support the `Fetch API`, if you want your web application to work on legacy or old browsers it's always a good idea to check the [compatibility table on caniuse.com](https://caniuse.com/fetch) first.
### Task
In [the previous lesson](../2-forms/README.md) we implented the registration form to create an account. We'll now add code to login using an existing account, and fetch its data. Open the `app.js` file and add a new `login` function:
In [the previous lesson](../2-forms/README.md) we implemented the registration form to create an account. We'll now add code to login using an existing account, and fetch its data. Open the `app.js` file and add a new `login` function:
```js
async function login() {
@ -63,9 +63,9 @@ async function getAccount(user) {
}
```
We use the `fetch` API to request the data asynchronously from the server, but this time we don't need any extra parameters other than the URL to call, as we're only querying data. By default, `fetch` create a [`GET`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) HTTP request, which is what we are seeking here.
We use the `fetch` API to request the data asynchronously from the server, but this time we don't need any extra parameters other than the URL to call, as we're only querying data. By default, `fetch` creates a [`GET`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) HTTP request, which is what we are seeking here.
`encodeURIComponent()` is a function that escapes special characters for URL. What possible issues could we possibly have if we do not call this function and use directly the `user` value in the URL?
`encodeURIComponent()` is a function that escapes special characters for URL. What issues could we possibly have if we do not call this function and use directly the `user` value in the URL?
Let's now update our `login` function to use `getAccount`:
@ -84,9 +84,9 @@ async function login() {
}
```
First, as `getAccount` is an asynchronous function we need to match it with the `await` keyword to wait for the server result. As with any server request, we also have to deal with errors cases. For now we'll only add a log message to display the error, and come back to it layer.
First, as `getAccount` is an asynchronous function we need to match it with the `await` keyword to wait for the server result. As with any server request, we also have to deal with error cases. For now we'll only add a log message to display the error, and come back to it later.
Then we have to store the data somewhere so we can later use it to display the dashboard informations. Since we the `account` variable does not exist yet, we'll create a global variable for it at the top of our file:
Then we have to store the data somewhere so we can later use it to display the dashboard informations. Since the `account` variable does not exist yet, we'll create a global variable for it at the top of our file:
```js
let account = null;
@ -94,7 +94,7 @@ let account = null;
After the user data is saved into a variable we can navigate from the *login* page to the *dashboard* using the `navigate()` function we already have.
Finally, we need to call our `login` function when the login form is submitted by modifying the HTML:
Finally, we need to call our `login` function when the login form is submitted, by modifying the HTML:
```html
<form id="loginForm" action="javascript:login()">
@ -109,17 +109,17 @@ account = result;
navigate('/dashboard');
```
✅ Did you know that by default, you can only call server APIs from the *same domain and port* than the web page you are viewing? This is security mechanism enforced by browsers. But wait, our web app is running on `localhost:3000` whereas the server API is running on ` localhost:5000`, why does it work? By using a technique called [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) it is possible to perform cross-origin HTTP requests is the server add specials headers to the response, allowing exceptions for specific domains.
✅ Did you know that by default, you can only call server APIs from the *same domain and port* than the web page you are viewing? This is security mechanism enforced by browsers. But wait, our web app is running on `localhost:3000` whereas the server API is running on ` localhost:5000`, why does it work? By using a technique called [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), it is possible to perform cross-origin HTTP requests if the server adds special headers to the response, allowing exceptions for specific domains.
## Update HTML to display data
Now that we have the user data, we have to update the existing HTML to display it. We already know how to retrieve element from the DOM using for example `document.getElementById()`. After you have a base element, here are some APIs you can use to modify it or add child elements to it:
Now that we have the user data, we have to update the existing HTML to display it. We already know how to retrieve an element from the DOM using for example `document.getElementById()`. After you have a base element, here are some APIs you can use to modify it or add child elements to it:
- Using the [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) property you can change the text of an element. Note that changing this values removes all the element's children (if there's any) and replace it with the text provided. As such, it's also an efficient method to remove all children of a given element by assigning an empty string `''` to it.
- Using the [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) property you can change the text of an element. Note that changing this value removes all the element's children (if there's any) and replaces it with the text provided. As such, it's also an efficient method to remove all children of a given element by assigning an empty string `''` to it.
- Using [`document.createElement()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) along with the [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) method you can create and attach one or more new child elements.
✅ Using the [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) property of an element it's also possible to change its HTML contents, but this one should avoided as it's vulnerable to [cross-site scripting (XSS)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) attacks.
✅ Using the [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) property of an element it's also possible to change its HTML contents, but this one should be avoided as it's vulnerable to [cross-site scripting (XSS)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) attacks.
### Task
@ -134,7 +134,7 @@ Let's add a placeholder element in the login form where we can display an error
...
```
This `<div>` element is empty, meaning that nothing we be displayed on the screen until we add some content to it. We also give it an `id` so we can retrieve it easily with JavaScript.
This `<div>` element is empty, meaning that nothing will be displayed on the screen until we add some content to it. We also give it an `id` so we can retrieve it easily with JavaScript.
Go back to the `app.js` file and create a new helper function `updateElement`:
@ -145,7 +145,7 @@ function updateElement(id, text) {
}
```
This one is quite straightforward, given an element *id* and *text* it will update the text content of the DOM element with the matching `id`. Let's use this method in place of the previous error message in the `login` function:
This one is quite straightforward: given an element *id* and *text*, it will update the text content of the DOM element with the matching `id`. Let's use this method in place of the previous error message in the `login` function:
```js
if (data.error) {
@ -167,7 +167,7 @@ Implement the same behavior for the `register` function errors (don't forget to
## Display information on the dashboard
Using the same techniques we've just seen we'll also take care of displaying the account information on the the dashboard page.
Using the same techniques we've just seen, we'll also take care of displaying the account information on the dashboard page.
This is what an account object received from the server looks like:
@ -242,11 +242,11 @@ const routes = {
};
```
With this change, everytime the dashboard page is displayed then the function `updateDashboard()` is called. After a login, you should then be able to see the account balance, currency and description.
With this change, every time the dashboard page is displayed, the function `updateDashboard()` is called. After a login, you should then be able to see the account balance, currency and description.
## Create table rows dynamically with HTML templates
In the [first lesson](../1-template-route/README.md) we used HTML template along with the [`appendChild()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild) method to implement the navigation in our app. Templates can also be smaller and used to dynamically populate repetitive parts of a page.
In the [first lesson](../1-template-route/README.md) we used HTML templates along with the [`appendChild()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild) method to implement the navigation in our app. Templates can also be smaller and used to dynamically populate repetitive parts of a page.
We'll use a similar approach to display the list of transactions in the HTML table.
@ -286,7 +286,7 @@ function createTransactionRow(transaction) {
}
```
This function does exactly what its names implies: using the template we created earlier, it create a new table row and fill in its contents using transaction data. We'll use this to in our `updateDashboard()` function to populate the table:
This function does exactly what its names implies: using the template we created earlier, it creates a new table row and fills in its contents using transaction data. We'll use this in our `updateDashboard()` function to populate the table:
```js
const transactionsRows = document.createDocumentFragment();
@ -297,7 +297,7 @@ for (const transaction of account.transactions) {
updateElement('transactions', transactionsRows);
```
We use here the method [`document.createDocumentFragment()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment) that create a new DOM fragment on which we can work, before finally attaching it to our HTML table.
Here we use the method [`document.createDocumentFragment()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment) that creates a new DOM fragment on which we can work, before finally attaching it to our HTML table.
There's still one more thing we have to do before this code can work, as our `updateElement()` function currently supports text content only. Let's change its code a bit:

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/45)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/45?loc=ja)
### イントロダクション
@ -325,7 +325,7 @@ function updateElement(id, textOrNode) {
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/46)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/46?loc=ja)
## 課題

@ -0,0 +1,15 @@
# 코드 리팩터링 및 주석
## 설명
코드베이스가 커짐에 따라 코드를 자주 리팩터링하여 시간이 지남에 따라 가독성과 유지 관리가 가능하도록 유지하는 것이 중요합니다. 주석을 추가하고 `app.js` 를 리팩터링하여 코드 품질을 개선합니다.
- 서버 API 기본 URL과 같은 상수 추출
- 유사한 코드를 분해합니다. 예를 들어 `createAccount()``getAccount()` 모두에서 사용되는 코드를 다시 그룹화하는 `sendRequest()` 함수를 만들 수 있습니다.
- 읽기 쉽도록 코드 재구성 및 주석 추가
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 코드 주석이 잘 짜여진 여러개의 섹션으로 나뉘며 읽기 쉬운 경우. 그리고 상수들이 추출되고 잘 쪼개진 `sendRequest()` 함수를 생성한 경우 | 코드는 깔끔하지만 더 많은 주석, 지속적인 추출 또는 분해를 통해 개선될 수 있는 경우 | 코드가 지저분하고 주석도 잘 작성하지 않았으며 상수 또한 추출되지 않고 코드도 분해되지 않은 경우

@ -2,7 +2,7 @@
## レッスン前の小テスト
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/47)
[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/47?loc=ja)
### イントロダクション
@ -270,7 +270,7 @@ const routes = {
## レッスン後の小テスト
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/48)
[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/48?loc=ja)
## 課題

@ -0,0 +1,24 @@
# "거래 추가" 대화 상자 구현
## 설명
우리 은행 앱에는 여전히 새로운 거래를 입력 할 수 있는 한 가지 중요한 기능이 없습니다. 이전 네 가지 수업에서 배운 모든 것을 사용하여 "트랜잭션 추가" 대화 상자를 구현해봅시다.
- 대시 보드 페이지에 "거래 추가" 버튼 추가
- HTML 템플릿으로 새 페이지를 만들거나 JavaScript를 사용하여 대시 보드 페이지를 벗어나지 않고 대화 상자 HTML을 표시하거나 숨깁니다(해당 항목에 대해 [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) 속성 또는 CSS 클래스를 사용할 수 있음).
- 대화 상자에 대한 [키보드 및 화면 판독기 접근성](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/)을 처리해야합니다.
- 입력 데이터 수신을 위한 HTML 양식 구현
- 양식 데이터에서 JSON 데이터를 만들어 API로 보냅니다.
- 새 데이터로 대시 보드 페이지 업데이트
호출해야하는 API와 예상되는 JSON 형식을 확인하려면 [서버 API 사양](../api/README.md) 을 살펴보세요.
다음은 과제를 완료 한 후의 예시 결과입니다.
![예시를 보여주는 스크린샷 이미지](./images/dialog.png)
## 평가 기준
기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | --- | ---
| 거래 추가 기능이 수업에서 본 모든 모범 사례에 따라 완전히 구현된 경우 | 거래 추가기능은 구현되지만, 강의에 표시된 모범 사례를 따르지 않거나 부분적으로만 작동하는 경우 | 거래 추가기능이 전혀 동작하지 않는 경우

@ -0,0 +1,11 @@
# 공식문서 읽기
## 설명
웹 개발자들이 필요할 만한 도구들이 [MDN 클라이언트 사이드 도구 문서](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview)에 소개되어있습니다. 이번 수업내용에 포함되지 않은 3개의 도구를 선택하고, 왜 웹 개발자들이 사용할만한지를 설명해봅시다. 그리고 이 범주에 속하는 도구를 찾아서 문서를 공유해봅시다. MDN문서에 있는 똑같은 예시를 사용하면 안 됩니다.
## 평가 기준
모범 답안 | 적당한 답안 | 개선이 필요한 답안
--- | --- | ---
웹 개발자가 도구를 사용하는 이유를 설명한 경우 | 개발자가 도구를 사용하는 방법은 설명했지만 도구를 사용하는 이유는 설명하지 않은 경우 | 개발자가 도구를 사용하는 이유나 방법을 설명하지 않은 경우
Loading…
Cancel
Save