🌐 Update translations via Co-op Translator

pull/1494/head
leestott 11 months ago committed by GitHub
parent 0717b63fe0
commit a2fda673a6

@ -1,17 +1,17 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "c63675cfaf1d223b37bb9fecbfe7c252",
"translation_date": "2025-08-23T23:29:40+00:00",
"original_hash": "2dcbb9259dee4f20a4f08d9a1aa2bd4c",
"translation_date": "2025-08-28T18:01:10+00:00",
"source_file": "1-getting-started-lessons/1-intro-to-programming-languages/README.md",
"language_code": "ja"
}
-->
# プログラミング言語とツールの基礎
このレッスンでは、プログラミング言語の基本を学びます。ここで扱うトピックは、今日のほとんどの現代的なプログラミング言語に適用されます。「ツールの基礎」セクションでは、開発者として役立つソフトウェアについて学びます。
このレッスンでは、プログラミング言語の基本について学びます。ここで取り上げるトピックは、今日のほとんどの現代的なプログラミング言語に適用されます。「ツールの基礎」セクションでは、開発者として役立つソフトウェアについて学びます。
![Intro Programming](../../../../sketchnotes/webdev101-programming.png)
![Intro Programming](../../../../translated_images/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前のクイズ
@ -24,15 +24,15 @@ CO_OP_TRANSLATOR_METADATA:
- プログラミングとは何か?
- プログラミング言語の種類
- プログラムの基本要素
- プロフェッショナルな開発者に役立つソフトウェアとツール
- プロフェッショナルな開発者向けの便利なソフトウェアとツール
> このレッスンは [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/introduction-programming/?WT.mc_id=academic-77807-sagibbon) で受講できます!
## プログラミングとは?
プログラミング(コーディングとも呼ばれる)は、コンピュータやモバイルデバイスなどの機器に指示を与えるプロセスです。これらの指示はプログラミング言語を使って記述され、デバイスによって解釈されます。これらの指示セットはさまざまな名前で呼ばれることがありますが、*プログラム*、*コンピュータプログラム*、*アプリケーション(アプリ)*、*実行可能ファイル* などが一般的です。
プログラミング(コーディングとも呼ばれる)は、コンピュータやモバイルデバイスなどの機器に指示を与えるプロセスです。これらの指示はプログラミング言語を使って記述され、デバイスによって解釈されます。これらの指示セットはさまざまな名前で呼ばれることがありますが、*プログラム*、*コンピュータプログラム*、*アプリケーション(アプリ)*、*実行ファイル* などが一般的な名称です。
*プログラム* はコードで書かれたものすべてを指します。ウェブサイト、ゲーム、スマホアプリなどがプログラムです。コードを書かずにプログラムを作成することも可能ですが、その基盤となるロジックはデバイスによって解釈され、そのロジックはほとんどの場合コードで書かれています。*実行中* または *実行している* プログラムは指示を実行しています。このレッスンを読んでいるデバイスも、画面に表示するためのプログラムを実行しています。
*プログラム* はコードで記述されたものであれば何でも該当します。ウェブサイト、ゲーム、スマホアプリなどがプログラムの例です。コードを書かずにプログラムを作成することも可能ですが、その基盤となるロジックはデバイスによって解釈され、そのロジックはおそらくコードで記述されています。*実行中* または *コードを実行している* プログラムは指示を実行しています。あなたがこのレッスンを読んでいるデバイスも、画面に表示するためのプログラムを実行しています。
✅ 少し調べてみましょう: 世界初のコンピュータプログラマーとされる人物は誰でしょう?
@ -42,9 +42,9 @@ CO_OP_TRANSLATOR_METADATA:
プログラミング言語にはさまざまな形式があり、目的も異なる場合があります。例えば、JavaScriptは主にウェブアプリケーションに使用され、Bashは主にオペレーティングシステムに使用されます。
*低水準言語* は通常、デバイスが指示を解釈するために必要なステップが少なくなります。しかし、*高水準言語* が人気なのは、その読みやすさとサポートの充実度です。JavaScriptは高水準言語とされています。
*低水準言語* は、デバイスが指示を解釈するために必要なステップが *高水準言語* よりも少ないことが一般的です。しかし、高水準言語が人気なのは、その読みやすさとサポートの充実度です。JavaScriptは高水準言語とされています。
以下のコードは、高水準言語であるJavaScriptと低水準言語であるARMアセンブリコードの違いを示しています。
以下のコードは、JavaScriptという高水準言語とARMアセンブリコードという低水準言語の違いを示しています。
```javascript
let number = 10
@ -85,15 +85,15 @@ back add r0,r1
信じられないかもしれませんが、*どちらも同じことをしています*: フィボナッチ数列を10まで表示しています。
✅ フィボナッチ数列は [定義](https://en.wikipedia.org/wiki/Fibonacci_number) によると、0と1から始まり、各数がその前の2つの数の合計となる数列です。フィボナッチ数列の最初の10個の数字は、0, 1, 1, 2, 3, 5, 8, 13, 21, 34です。
✅ フィボナッチ数列は [定義](https://en.wikipedia.org/wiki/Fibonacci_number) によると、0と1から始まり、各数がその前の2つの数の合計となる一連の数です。フィボナッチ数列に従う最初の10個の数は、0, 1, 1, 2, 3, 5, 8, 13, 21, 34です。
## プログラムの要素
プログラム内の単一の指示は *ステートメント* と呼ばれ、通常は指示が終了する場所、つまり *終端* を示す文字や行間隔があります。プログラムの終端方法は言語によって異なります。
プログラム内の単一の指示は *ステートメント* と呼ばれ、通常は指示が終了する場所、つまり *終端* を示す文字や行間が含まれています。プログラムの終端方法は言語によって異なります。
プログラム内のステートメントは、ユーザーやその他の場所から提供されるデータに依存して指示を実行することがあります。データはプログラムの動作を変える可能性があるため、プログラミング言語にはデータを一時的に保存して後で使用できる方法が備わっています。これを *変数* と呼びます。変数は、デバイスにデータをメモリに保存するよう指示するステートメントです。プログラム内の変数は代数の変数に似ており、ユニークな名前を持ち、その値は時間とともに変化する可能性があります。
プログラム内のステートメントは、ユーザーやその他の場所から提供されるデータに依存して指示を実行する場合があります。データはプログラムの動作を変える可能性があるため、プログラミング言語にはデータを一時的に保存して後で使用できる方法が備わっています。これを *変数* と呼びます。変数は、デバイスにデータをメモリに保存するよう指示するステートメントです。プログラム内の変数は代数の変数に似ており、ユニークな名前を持ち、その値は時間とともに変化する可能性があります。
一部のステートメントがデバイスによって実行されない可能性があります。これは通常、開発者によって意図的に書かれた場合や、予期しないエラーが発生した場合に起こります。このようなアプリケーションの制御は、より堅牢で保守性の高いものにします。通常、これらの制御の変更は特定の条件が満たされたときに発生します。現代のプログラミングでよく使われるステートメントの1つに `if..else` ステートメントがあります。
一部のステートメントがデバイスによって実行されない可能性があります。これは通常、開発者によって意図的に書かれた場合や、予期しないエラーが発生した場合に起こります。このようなアプリケーションの制御は、より堅牢で保守性の高いものにします。通常、これらの制御の変更は特定の条件が満たされた場合に発生します。現代のプログラミングでよく使われる制御ステートメントの1つが `if..else` ステートメントです。
✅ このタイプのステートメントについては、後のレッスンでさらに学びます。
@ -101,9 +101,9 @@ back add r0,r1
[![Tools of the Trade](https://img.youtube.com/vi/69WJeXGBdxg/0.jpg)](https://youtube.com/watch?v=69WJeXGBdxg "Tools of the Trade")
> 🎥 上の画像をクリックしてツールに関する動画を視聴
> 🎥 上の画像をクリックするとツールに関する動画が再生されます
このセクションでは、プロフェッショナルな開発の旅を始める際に非常に役立つソフトウェアについて学びます。
このセクションでは、プロフェッショナルな開発の旅を始める際に役立つソフトウェアについて学びます。
**開発環境** とは、開発者がソフトウェアを書く際に頻繁に使用するツールや機能の独自のセットです。これらのツールは開発者の特定のニーズに合わせてカスタマイズされている場合があり、開発者が仕事や個人プロジェクトの優先順位を変更したり、異なるプログラミング言語を使用したりする場合に変化することがあります。開発環境は、それを使用する開発者と同じくらいユニークです。
@ -111,11 +111,11 @@ back add r0,r1
ソフトウェア開発において最も重要なツールの1つがエディタです。エディタはコードを書く場所であり、時にはコードを実行する場所でもあります。
開発者がエディタを用する理由は以下の通りです:
開発者がエディタを使用する理由は以下の通りです:
- *デバッグ* は、コードを1行ずつステップ実行してバグやエラーを見つけるのに役立ちます。一部のエディタにはデバッグ機能があり、特定のプログラミング言語に合わせてカスタマイズして追加することができます。
- *構文ハイライト* は、コードに色やテキストフォーマットを追加し、読みやすくします。ほとんどのエディタはカスタマイズ可能な構文ハイライトを提供しています。
- *拡張機能と統合* は、開発者による開発者のための専門的なツールです。これらのツールは基本エディタに組み込まれていません。例えば、多くの開発者はコードの動作を説明するためにドキュメントを作成します。彼らはスペルチェック拡張機能をインストールして、ドキュメント内の誤字を見つけることができます。ほとんどの拡張機能は特定のエディタ内で使用することを目的としており、ほとんどのエディタには利用可能な拡張機能を検索する方法が備わっています。
- *デバッグ* は、コードを1行ずつステップ実行することでバグやエラーを発見するのに役立ちます。一部のエディタにはデバッグ機能があり、特定のプログラミング言語に合わせてカスタマイズして追加することができます。
- *構文ハイライト* は、コードに色やテキストフォーマットを追加し、読みやすくします。ほとんどのエディタはカスタマイズ可能な構文ハイライトを提供しています。
- *拡張機能と統合* は、開発者による開発者のための専門的なツールです。これらのツールは基本エディタに組み込まれていません。例えば、多くの開発者はコードの動作を説明するためにドキュメントを作成します。彼らはドキュメント内のタイプミスを見つけるためにスペルチェック拡張機能をインストールするかもしれません。ほとんどの拡張機能は特定のエディタ内で使用することを目的としており、ほとんどのエディタには利用可能な拡張機能を検索する方法が備わっています。
- *カスタマイズ* により、開発者は自分のニーズに合わせた独自の開発環境を作成できます。ほとんどのエディタは非常にカスタマイズ可能で、開発者が独自の拡張機能を作成することも可能です。
#### 人気のエディタとウェブ開発拡張機能
@ -135,9 +135,9 @@ back add r0,r1
### ブラウザ
もう1つ重要なツールがブラウザです。ウェブ開発者は、ウェブ上でコードがどのように動作するかを確認するためにブラウザを利用します。また、HTMLのようにエディタで書かれたウェブページの視覚的要素を表示するためにも使用されます。
もう1つ重要なツールがブラウザです。ウェブ開発者は、ウェブ上でコードがどのように動作するかを確認するためにブラウザを使用します。また、HTMLのようにエディタで記述されたウェブページの視覚的要素を表示するためにも使用されます。
多くのブラウザには *開発者ツール* (DevTools) が搭載されており、アプリケーションに関する重要な情報を収集・キャプチャするための便利な機能が含まれています。例えば、ウェブページにエラーがある場合、エラーが発生したタイミングを知ることが役立つことがあります。ブラウザのDevToolsはこの情報をキャプチャするように設定できます。
多くのブラウザには *開発者ツール* (DevTools) が搭載されており、アプリケーションに関する重要な情報を収集・キャプチャするための便利な機能が含まれています。例えば、ウェブページにエラーがある場合、それがいつ発生したかを知ることが役立つことがあります。ブラウザのDevToolsはこの情報をキャプチャするように設定できます。
#### 人気のブラウザとDevTools
@ -147,7 +147,7 @@ back add r0,r1
### コマンドラインツール
一部の開発者は、日常の作業においてグラフィカルなビューをあまり必要とせず、コマンドラインを利用することを好みます。コードを書くには大量のタイピングが必要であり、一部の開発者はキーボードでの作業の流れを中断したくないと考えます。彼らはキーボードショートカットを使てデスクトップウィンドウを切り替えたり、異なるファイルで作業したり、ツールを使用したりします。ほとんどのタスクはマウスで完了できますが、コマンドラインを使用する利点の1つは、マウスとキーボードを切り替える必要なく多くの作業をコマンドラインツールで完了できることです。コマンドラインのもう1つの利点は、カスタマイズ可能であり、カスタム設定を保存して後で変更したり、他の開発マシンにインポートしたりできることです。開発環境は開発者ごとに非常にユニークであるため、コマンドラインを完全に避ける人もいれば、完全に依存する人もおり、その両方を好む人もいます。
一部の開発者は、日常の作業においてグラフィカルなビューをあまり使用せず、コマンドラインを好むことがあります。コードを書くには大量のタイピングが必要であり、一部の開発者はキーボードでの作業の流れを中断したくないと考えます。彼らはキーボードショートカットを使用してデスクトップウィンドウを切り替えたり、異なるファイルで作業したり、ツールを使用したりします。ほとんどのタスクはマウスで完了できますが、コマンドラインを使用する利点の1つは、マウスとキーボードを切り替えることなく多くの作業をコマンドラインツールで完了できることです。コマンドラインのもう1つの利点は、設定を保存して後で変更したり、他の開発マシンにインポートしたりできることです。開発環境が開発者ごとに非常にユニークであるため、一部の開発者はコマンドラインを完全に避けることもあれば、完全に依存することもあり、またはその両方を好む場合もあります。
### 人気のコマンドラインオプション
@ -182,17 +182,17 @@ back add r0,r1
### ドキュメント
開発者が新しいことを学びたいとき、最も頼りにするのはドキュメントです。開発者はツールや言語を正しく使用する方法を学ぶため、またその仕組みを深く理解するためにドキュメントを利用します。
開発者が新しいことを学びたいと思ったとき、最も頼りにするのはドキュメントです。開発者はツールや言語を正しく使用する方法を学ぶため、またその仕組みを深く理解するためにドキュメントを利用します。
#### ウェブ開発に関する人気のドキュメント
- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web) - Mozillaによる、[Firefox](https://www.mozilla.org/firefox/)ブラウザの発行元
- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web), Mozillaによる、[Firefox](https://www.mozilla.org/firefox/)ブラウザの発行元
- [Frontend Masters](https://frontendmasters.com/learn/)
- [Web.dev](https://web.dev) - Googleによる、[Chrome](https://www.google.com/chrome/)の発行元
- [Microsoftの開発者向けドキュメント](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers) - [Microsoft Edge](https://www.microsoft.com/edge)向け
- [Web.dev](https://web.dev), Googleによる、[Chrome](https://www.google.com/chrome/)の発行元
- [Microsoftの開発者向けドキュメント](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers), [Microsoft Edge](https://www.microsoft.com/edge)向け
- [W3 Schools](https://www.w3schools.com/where_to_start.asp)
✅ 調査してみましょう: ウェブ開発者の環境の基本を理解した、ウェブデザイナーの環境と比較してみましょう。
✅ 調査してみましょう: ウェブ開発者の環境の基本を理解したところで、ウェブデザイナーの環境と比較してみましょう。
---
@ -201,15 +201,17 @@ back add r0,r1
いくつかのプログラミング言語を比較してみましょう。JavaScriptとJavaのユニークな特徴は何ですかCOBOLとGoではどうでしょう
## 講義後のクイズ
[講義後のクイズ](https://ff-quizzes.netlify.app/web/quiz/2)
[講義後のクイズ](https://ff-quizzes.netlify.app/web/)
## 復習と自己学習
プログラマーが利用できるさまざまな言語について少し学びましょう。1つの言語で1行を書、それを別の2つの言語で書き直してみてください。何を学びましたか
プログラマーが利用できるさまざまな言語について少し学びましょう。1つの言語で1行を書いてみて、それを別の2つの言語で書き直してみてください。何を学びましたか
## 課題
[ドキュメントを読む](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確さが含まれる可能性があります。元の言語で記載された原文が公式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。

@ -1,29 +1,29 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "05666cecb8983a72cf0ce1d18932b5b7",
"translation_date": "2025-08-23T23:19:37+00:00",
"original_hash": "361249da70432ddfd4741c917d1a6f50",
"translation_date": "2025-08-28T18:03:29+00:00",
"source_file": "1-getting-started-lessons/2-github-basics/README.md",
"language_code": "ja"
}
-->
# GitHubの概要
# GitHubの紹介
このレッスンでは、コードのホスティングと変更管理を行うプラットフォームであるGitHubの基本を学びます。
このレッスンでは、コードをホストし、変更を管理するためのプラットフォームであるGitHubの基本を学びます。
![GitHubの概要](../../../../sketchnotes/webdev101-github.png)
![GitHubの紹介](../../../../translated_images/webdev101-github.8846d7971abef6f947909b4f9d343e2a23778aa716ca6b9d71df7174ee5009ac.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/3)
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app)
## はじめに
このレッスンでは以下を学びます:
- 自分のマシンでの作業を追跡する方法
- 自分のマシン上での作業の追跡
- 他の人とプロジェクトを進める方法
- オープンソースソフトウェアに貢献する方法
- オープンソースソフトウェアへの貢献方法
### 前提条件
@ -34,26 +34,26 @@ Gitがインストールされていない場合は、[Gitをダウンロード]
* `git config --global user.name "your-name"`
* `git config --global user.email "your-email"`
Gitがすでに設定されているか確認するには以下を入力します
Gitがすでに設定されているか確認するには以下を入力します:
`git config --list`
また、GitHubアカウント、コードエディタ例: Visual Studio Code、ターミナルまたはコマンドプロンプト必要です。
また、GitHubアカウント、コードエディタ例: Visual Studio Code、ターミナルまたはコマンドプロンプト必要です。
[github.com](https://github.com/)にアクセスして、まだアカウントを作成していない場合は作成し、ログインしてプロファイルを完成させてください。
[github.com](https://github.com/)にアクセスして、まだアカウントを作成していない場合は作成し、ログインしてプロフィールを埋めてください。
✅ GitHubは世界で唯一のコードリポジトリではありません。他にもありますが、GitHubが最もよく知られています。
### 準備
ローカルマシンートPCまたはPCにコードプロジェクトのフォルダと、他の人のプロジェクトに貢献する方法を学ぶための例として使用するGitHub上の公開リポジトリが必要です
ローカルマシンートPCまたはPCにコードプロジェクトのフォルダを用意し、他の人のプロジェクトに貢献する方法を学ぶための例として、GitHub上に公開リポジトリを作成してください
---
## コード管理
ローカルにコードプロジェクトのフォルダがあり、その進捗をバージョン管理システムであるGitを使って追跡したいとします。Gitを使うことは、未来の自分へのラブレターを書くようなものだと例えられることがあります。数日、数週間、数ヶ月後にコミットメッセージを読むことで、なぜその決定をしたのかを思い出したり、変更を「巻き戻す」ことができます。ただし、良い「コミットメッセージ」を書いた場合に限ります。
ローカルにコードプロジェクトのフォルダがあり、その進捗をバージョン管理システムであるgitを使って追跡したいとします。一部の人は、gitを使うことを「未来の自分へのラブレターを書くこと」に例えます。数日、数週間、または数か月後にコミットメッセージを読むことで、なぜその決定をしたのかを思い出したり、変更を「ロールバック」したりすることができます。ただし、良い「コミットメッセージ」を書いた場合に限ります。
### タスク: リポジトリを作成しコードをコミットする
### タスク: リポジトリを作成しコードをコミットする
> 動画をチェック
>
@ -70,19 +70,19 @@ Gitがすでに設定されているか確認するには以下を入力しま
cd [name of your folder]
```
1. **Gitリポジトリを初期化**。プロジェクトで以下を入力します:
1. **gitリポジトリを初期化**。プロジェクトで以下を入力します:
```bash
git init
```
1. **ステータスを確認**。リポジトリのステータスを確認するには以下を入力します:
1. **ステータスを確認**。リポジトリのステータスを確認するには以下を入力します:
```bash
git status
```
出力は以下のようになることがあります:
出力は次のようになる場合があります:
```output
Changes not staged for commit:
@ -93,16 +93,16 @@ Gitがすでに設定されているか確認するには以下を入力しま
modified: file2.txt
```
通常、`git status`コマンドは、リポジトリに保存する準備ができたファイルや変更があるファイルなどを教えてくれます。
通常、`git status`コマンドは、リポジトリに保存する準備ができているファイルや、変更が加えられたファイルなどを教えてくれます。
1. **すべてのファイルを追跡対象に追加**
これはファイルをステージングエリアに追加することを意味します。
これはファイルをステージングエリアに追加することとも呼ばれます。
```bash
git add .
```
`git add`と`.`の引数は、すべてのファイルと変更を追跡対象にすることを示します。
`git add`に`.`を付けることで、すべてのファイルと変更を追跡対象に追加します。
1. **選択したファイルを追跡対象に追加**
@ -110,35 +110,35 @@ Gitがすでに設定されているか確認するには以下を入力しま
git add [file or folder name]
```
すべてのファイルを一度にコミットしたくない場合に、選択したファイルだけをステージングエリアに追加するのに役立ちます。
すべてのファイルを一度にコミットしたくない場合に、選択したファイルだけをステージングエリアに追加できます。
1. **すべてのファイルをステージング解除**
1. **すべてのファイルをステージ解除**
```bash
git reset
```
このコマンドは、すべてのファイルを一度にステージング解除するのに役立ちます。
このコマンドは、すべてのファイルを一度にステージ解除するのに役立ちます。
1. **特定のファイルをステージング解除**
1. **特定のファイルをステージ解除**
```bash
git reset [file or folder name]
```
このコマンドは、次のコミットに含めたくない特定のファイルだけをステージング解除するのに役立ちます。
次のコミットに含めたくない特定のファイルだけをステージ解除するのに役立ちます。
1. **作業を永続化**。この時点で、ファイルをいわゆるステージングエリアに追加しました。Gitがファイルを追跡している場所です。変更を永続化するには、ファイルをコミットする必要があります。コミットを作成するには、`git commit`コマンドを使用します。コミットはリポジトリの履歴における保存ポイントを表します。以下を入力してコミットを作成します:
1. **作業を永続化**。この時点で、ファイルをいわゆるステージングエリアに追加しました。Gitがファイルを追跡している場所です。変更を永続化するには、ファイルをコミットする必要があります。`git commit`コマンドを使用してコミットを作成します。コミットはリポジトリの履歴における保存ポイントを表します。以下を入力してコミットを作成します:
```bash
git commit -m "first commit"
```
これにより、すべてのファイルがコミットされ、「first commit」というメッセージが追加されます。将来のコミットメッセージでは、変更の種類を伝えるためにもっと具体的な説明をすることをお勧めします。
これにより、すべてのファイルがコミットされ、「first commit」というメッセージが追加されます。将来のコミットメッセージでは、どのような変更を行ったのかを伝えるために、より具体的な説明を記述することをお勧めします。
1. **ローカルGitリポジトリをGitHubと接続**。ローカルリポジトリはマシン上で便利ですが、ファイルのバックアップをどこかに保存したり、他の人をリポジトリに招待したりしたい場合があります。そのための素晴らしい場所がGitHubです。すでにGitHubでリポジトリを作成しているので、ローカルGitリポジトリをGitHubと接続するだけです。`git remote add`コマンドを使用します。以下のコマンドを入力してください
1. **ローカルGitリポジトリをGitHubと接続**。ローカルリポジトリはマシン上で便利ですが、ファイルのバックアップをどこかに保存したり、他の人を招待してリポジトリで作業してもらいたい場合があります。そのための素晴らしい場所がGitHubです。すでにGitHubでリポジトリを作成しているので、ローカルGitリポジトリをGitHubと接続するだけです。`git remote add`コマンドを使用します。以下のコマンドを入力します
> 注意コマンドを入力する前に、GitHubリポジトリページに移動してリポジトリURLを見つけてください。このURLを以下のコマンドで使用します。```https://github.com/username/repository_name.git```をGitHub URLに置き換えてください。
> 注意コマンドを入力する前に、GitHubリポジトリページに移動してリポジトリURLを見つけてください。このURLを以下のコマンドで使用します。```https://github.com/username/repository_name.git```をGitHubURLに置き換えてください。
```bash
git remote add origin https://github.com/username/repository_name.git
@ -146,7 +146,7 @@ Gitがすでに設定されているか確認するには以下を入力しま
これにより、「origin」という名前のリモート接続が作成され、先ほど作成したGitHubリポジトリを指します。
1. **ローカルファイルをGitHubに送信**。これまでのところ、ローカルリポジトリとGitHubリポジトリの間に接続を作成しました。次に、これらのファイルをGitHubに送信します。以下の`git push`コマンドを使用します:
1. **ローカルファイルをGitHubに送信**。これまでローカルリポジトリとGitHubリポジトリの間に接続を作成しました。次に、以下の`git push`コマンドを使用してファイルをGitHubに送信します:
> 注意:デフォルトのブランチ名が```main```と異なる場合があります。
@ -156,7 +156,7 @@ Gitがすでに設定されているか確認するには以下を入力しま
これにより、「main」ブランチのコミットがGitHubに送信されます。
2. **さらに変更を加える**。変更を続けてGitHubにプッシュしたい場合は、以下の3つのコマンドを使用するだけです
2. **さらに変更を加える場合**。変更を続けてGitHubにプッシュしたい場合は、以下の3つのコマンドを使用するだけです
```bash
git add .
@ -164,21 +164,21 @@ Gitがすでに設定されているか確認するには以下を入力しま
git push
```
> ヒント:`.gitignore`ファイルを採用して、GitHubに表示したくないファイルを追跡対象から除外することを検討してください。例えば、同じフォルダに保存しているメモファイルなどで、公開リポジトリには不要なものです。`.gitignore`ファイルのテンプレートは[.gitignore templates](https://github.com/github/gitignore)で見つけることができます。
> ヒント:`.gitignore`ファイルを採用して、追跡したくないファイルがGitHubに表示されないようにすることも検討してください。例えば、同じフォルダに保存しているメモファイルなどで、公開リポジトリには不要なものです。`.gitignore`ファイルのテンプレートは[.gitignore templates](https://github.com/github/gitignore)で見つけることができます。
#### コミットメッセージ
優れたGitコミットの件名は以下の文を完成させます:
「このコミットが適用されると、<件名>」
優れたGitコミットの件名行は、次の文を完成させる形になります:
「このコミットが適用されると、<件名>」
件名は命令形の現在形を使用します。「変更する」ではなく「変更した」や「変更する予定」ではありません。
件名と同様に、本文(オプション)でも命令形の現在形を使用します。本文には変更の動機を含め、以前の動作と対比させます。`なぜ`を説明するのであって、`どのように`ではありません
件名は命令形の現在形を使用します。「変更する」ではなく「変更した」や「変更すること」でもありません。
件名と同様に、本文(任意)でも命令形の現在形を使用します。本文には変更の動機を含め、以前の動作と対比させます。`どうやって`ではなく、`なぜ`を説明します。
✅ GitHubを少し探索してみてください。非常に優れたコミットメッセージを見つけることができますか?非常に簡素なものはどうですか?コミットメッセージで伝えるべき最も重要で有用な情報は何だと思いますか?
✅ GitHubを少し探索してみてください。特に優れたコミットメッセージを見つけられますか?非常に簡素なものはどうですか?コミットメッセージで伝えるべき最も重要で有用な情報は何だと思いますか?
### タスク: コラボレーション
GitHubにコードをアップロードする主な理由は、他の開発者とコラボレーションを可能にすることです。
GitHubにコードを置く主な理由は、他の開発者とコラボレーションを可能にすることです。
## 他の人とプロジェクトを進める
@ -188,29 +188,29 @@ GitHubにコードをアップロードする主な理由は、他の開発者
リポジトリ内で、`Insights > Community`に移動して、プロジェクトが推奨されるコミュニティ標準とどのように比較されるかを確認します。
以下はGitHubリポジトリを改善するためのポイントです
- **説明**。プロジェクト説明を追加しましたか?
- **README**。READMEを追加しましたかGitHubは[READMEの書き方](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon)についてのガイダンスを提供しています。
以下はGitHubリポジトリを改善するためのいくつかのポイントです:
- **説明**。プロジェクト説明を追加しましたか?
- **README**。READMEを追加しましたかGitHubは[READMEの書き方](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon)についてガイドを提供しています。
- **貢献ガイドライン**。プロジェクトに[貢献ガイドライン](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon)がありますか?
- **行動規範**。[行動規範](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/)がありますか?
- **ライセンス**。おそらく最も重要な[ライセンス](https://docs.github.com/articles/adding-a-license-to-a-repository/)がありますか?
これらのリソースは新しいチームメンバーのオンボーディングに役立ちます。そして、これらは通常、新しい貢献者がコードを見る前にプロジェクトが自分の時間を費やす価値があるかどうかを判断するために見るものです。
これらのリソースは新しいチームメンバーのオンボーディングに役立ちます。また、新しい貢献者がコードを見る前に、プロジェクトが自分の時間を費やす価値がある場所かどうかを判断するために通常確認するものです。
✅ READMEファイルは準備に時間がかかることがありますが、忙しいメンテナーによってしばしば無視されます。特に説明的なREADMEの例を見つけることができますか良いREADMEを作成するための[ツール](https://www.makeareadme.com/)がいくつかありますので、試してみてください。
✅ READMEファイルは準備に時間がかかるものの、忙しいメンテナーによってしばしば軽視されます。特に詳細なREADMEの例を見つけられますか良いREADMEを作成するための[ツール](https://www.makeareadme.com/)もありますので、試してみてください。
### タスク: コードをマージする
貢献ドキュメントは人々がプロジェクトに貢献するのを助けます。どのような種類の貢献を求めているか、プロセスがどのように機能するかを説明します。貢献者はGitHubのリポジトリに貢献するために一連のステップを踏む必要があります:
貢献ドキュメントは人々がプロジェクトに貢献するのを助けます。どのような種類の貢献を求めているか、プロセスがどのように機能するかを説明します。貢献者はGitHubのリポジトリに貢献するために一連のステップを実行する必要があります:
1. **リポジトリをフォークする**。通常、プロジェクトをフォークするように求めます。フォークとは、リポジトリの複製を自分のGitHubプロファイルに作成することを意味します。
1. **リポジトリをフォークする**。通常、プロジェクトをフォークするように求めます。フォークとは、自分のGitHubプロファイルにリポジトリの複製を作成することを意味します。
1. **クローン**。そこからプロジェクトをローカルマシンにクローンします。
1. **ブランチを作成**。作業用のブランチを作成するように求めます。
1. **変更を1つの領域に集中**。貢献者に1度に1つのことに集中するように求めます。そうすることで、彼らの作業をマージする可能性が高くなります。例えば、バグ修正、新機能の追加、複数のテストの更新を行った場合、3つのうち2つまたは1つしか実装できない場合はどうしますか
1. **ブランチを作成**。作業用のブランチを作成するように依頼します。
1. **変更を1つの領域に集中**。貢献者に、1回の貢献で1つのことに集中するよう依頼します。そうすることで、作業をマージする可能性が高くなります。例えば、バグ修正、新機能の追加、いくつかのテストの更新を同時に行った場合、3つのうち2つまたは1つしか実装できない場合があります。
✅ ブランチが特に重要になる状況を想像してみてください。どのようなユースケースが考えられますか?
> 注意:自分自身もブランチを作成して作業することで、他の人に良い例を示しましょう。現在「チェックアウト」しているブランチにコミットが行われます。`git status`を使用して、どのブランチにいるか確認してください
> 注意:自分自身もブランチを作成して作業することで、他の人に良い例を示しましょう。現在「チェックアウト」しているブランチにコミットが行われます。どのブランチにいるかを確認するには、`git status`を使用します
貢献者のワークフローを見てみましょう。貢献者がすでにリポジトリをフォークし、クローンしていると仮定します。つまり、ローカルマシンで作業可能なGitリポジトリが準備されています
@ -226,67 +226,67 @@ GitHubにコードをアップロードする主な理由は、他の開発者
git switch [branch-name]
```
1. **作業を行う**。この時点で変更を加えます。以下のコマンドを使用してGitに変更を伝えるのを忘れないでください:
1. **作業を行う**。この時点で変更を加えます。以下のコマンドを使用してGitに変更を通知するのを忘れないでください:
```bash
git add .
git commit -m "my changes"
```
コミットに良い名前を付けることを忘れないでください。自分のためにも、リポジトリのメンテナーのためにも役立ちます。
コミットには良い名前を付けてください。自分のためにも、リポジトリのメンテナーのためにも役立ちます。
1. **作業を`main`ブランチと統合**。作業が完了したら、`main`ブランチと作業を統合したいと思います。`main`ブランチはその間に変更されている可能性があるので、以下のコマンドで最新の状態に更新してください:
1. **作業を`main`ブランチと統合**。作業が完了したら、`main`ブランチと作業を統合したいとします。その間に`main`ブランチが変更されている可能性があるため、以下のコマンドで最新の状態に更新してください:
```bash
git switch main
git pull
```
この時点で、競合Gitが変更を簡単に統合できない状況が作業ブランチで発生することを確認してください。そのため、以下のコマンドを実行します:
この時点で、_コンフリクト_Gitが変更を簡単に統合できない状況が作業ブランチで発生しないようにします。そのため、以下のコマンドを実行します:
```bash
git switch [branch_name]
git merge main
```
これにより、`main`ブランチからすべての変更がブランチに取り込まれ、問題なく作業を続けることができます。もし競合が発生した場合は、VS CodeがGitが混乱している箇所を教えてくれるので、影響を受けたファイルを変更して最も正確な内容を指定します。
これにより、`main`からすべての変更がブランチに取り込まれ、通常はそのまま作業を続けることができます。そうでない場合は、VS CodeがGitが「混乱」している場所を教えてくれるので、影響を受けたファイルを変更して、どの内容が最も正確かを指定します。
1. **作業をGitHubに送信**。作業をGitHubに送信するには2つのことが必要です。ブランチをリポジトリにプッシュし、PRプルリクエストを開くことです。
1. **作業をGitHubに送信**。作業をGitHubに送信するには、2つのことを行います。ブランチをリポジトリにプッシュし、PRプルリクエストを開きます。
```bash
git push --set-upstream origin [branch-name]
```
上記のコマンドはフォークしたリポジトリにブランチを作成します。
上記のコマンドはフォークしたリポジトリにブランチを作成します。
1. **PRを開く**。次に、PRを開きます。フォークしたリポジトリのGitHubページに移動します。GitHubで新しいPRを作成するかどうかを尋ねる表示があり、それをクリックすると、コミットメッセージのタイトルを変更したり、より適切な説明を追加したりるインターフェースに移動します。これで、フォークしたリポジトリのメンテナーがこのPRを確認し、_うまくいけば_ PRを評価してマージしてくれるでしょう。これで貢献者になりました、やったね
1. **PRを開く**。次に、PRを開きます。GitHubのフォークしたリポジトリに移動します。GitHubで新しいPRを作成するかどうかを尋ねるインジケーターが表示されます。それをクリックすると、コミットメッセージのタイトルを変更したり、より適切な説明を追加したりできるインターフェースに移動します。これで、フォークしたリポジトリのメンテナーがこのPRを確認し、_うまくいけば_感謝してPRをマージしてくれるでしょう。これであなたは貢献者です。おめでとうございます :)
1. **クリーンアップ**。PRが正常にマージされた後は、クリーンアップすることが良い習慣とされています。ローカルブランチとGitHubにプッシュしたブランチの両方をクリーンアップしたいと思います。まず、以下のコマンドでローカルブランチを削除します:
1. **クリーンアップ**。PRが正常にマージされた後は、クリーンアップするが良い習慣とされています。ローカルブランチとGitHubにプッシュしたブランチの両方をクリーンアップします。まず、以下のコマンドでローカル削除します:
```bash
git branch -d [branch-name]
```
GitHub のフォークしたリポジトリのページに移動し、先ほどプッシュしたリモートブランチを削除してください。
`Pull request`(プルリクエスト)という言葉は少し変に思えるかもしれません。実際にはプロジェクトに変更を「プッシュ」したいわけですが、メンテナー(プロジェクトの所有者)やコアチームがその変更をプロジェクトの「メイン」ブランチにマージする前に検討する必要があります。つまり、メンテナーに変更の判断を「リクエスト」しているのです。
次に、フォークしたリポジトリのGitHubページに移動し、プッシュしたリモートブランチを削除してください。
`Pull request`(プルリクエスト)という言葉は、一見すると少し変に思えるかもしれません。なぜなら、実際にはプロジェクトに変更を「プッシュ」したいからです。しかし、メンテナー(プロジェクトの所有者)やコアチームが、あなたの変更をプロジェクトの「メイン」ブランチにマージする前に、その変更を検討する必要があります。つまり、メンテナーに変更の判断を「リクエスト」しているわけです。
プルリクエストは、ブランチで導入された差分をレビュー、コメント、統合テストなどを通じて比較・議論する場です。良いプルリクエストは、コミットメッセージとほぼ同じルールに従います。例えば、作業が特定の課題を解決する場合、課題トラッカーの課題番号を参照として追加できます。これは `#` に続けて課題番号を記載することで行います。例: `#97`
プルリクエストは、ブランチで導入された差分をレビュー、コメント、統合テストなどを通じて比較・議論する場です。良いプルリクエストは、コミットメッセージとほぼ同じルールに従います。例えば、作業が特定の課題を解決する場合、課題トラッカーの課題番号を参照として追加することができます。これは、`#`の後に課題番号を記載することで行います。例えば、`#97`のように記述します。
🤞すべてのチェックが通り、プロジェクト所有者があなたの変更をプロジェクトにマージしてくれることを祈りましょう🤞
🤞すべてのチェックが通り、プロジェクト所有者があなたの変更をプロジェクトにマージしてくれることを祈りましょう🤞
現在のローカル作業ブランチを GitHub 上の対応するリモートブランチの新しいコミットで更新するには、以下を実行します:
現在のローカル作業ブランチを、GitHub上の対応するリモートブランチの最新コミットで更新するには、以下を実行します:
`git pull`
## オープンソースへの貢献方法
まず、GitHub 上で興味のあるリポジトリ(または **repo**)を見つけ、そこに変更を加えたいと思ったら、その内容を自分のマシンにコピーします
まずは、GitHubで興味のあるリポジトリ**repo**)を見つけ、それに変更を加えたいと思ったら、その内容を自分のマシンにコピーしましょう
'初心者向け' のリポジトリを見つける良い方法は、[タグ 'good-first-issue' で検索すること](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/)です。
✅ 初心者向けのリポジトリを見つける良い方法は、[「good-first-issue」タグで検索すること](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/)です。
![リポジトリをローカルにコピー](../../../../1-getting-started-lessons/2-github-basics/images/clone_repo.png)
![リポジトリをローカルにコピー](../../../../translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.ja.png)
コードをコピーする方法はいくつかあります。一つの方法は、HTTPS、SSH、または GitHub CLIコマンドラインインターフェースを使用してリポジトリの内容を「クローン」することです。
コードをコピーする方法はいくつかあります。その一つは、HTTPS、SSH、またはGitHub CLIコマンドラインインターフェースを使用してリポジトリの内容を「クローン」する方法です。
ターミナルを開き、以下のようにリポジトリをクローンします:
`git clone https://github.com/ProjectURL`
@ -294,44 +294,46 @@ GitHub のフォークしたリポジトリのページに移動し、先ほど
プロジェクトで作業するには、正しいフォルダに移動します:
`cd ProjectURL`
また、[Codespaces](https://github.com/features/codespaces)GitHub の組み込みコードエディタ/クラウド開発環境)や [GitHub Desktop](https://desktop.github.com/) を使用してプロジェクト全体を開くこともできます。
また、[Codespaces](https://github.com/features/codespaces)GitHubの埋め込みコードエディタ/クラウド開発環境)や[GitHub Desktop](https://desktop.github.com/)を使用してプロジェクト全体を開くこともできます。
最後に、コードを zip フォルダとしてダウンロードすることも可能です。
最後に、コードをZIPフォルダとしてダウンロードすることも可能です。
### GitHub に関するいくつかの興味深いポイント
### GitHubに関するいくつかの興味深いポイント
GitHub 上の公開リポジトリは、スターを付けたり、ウォッチしたり、「フォーク」したりすることができます。スターを付けたリポジトリは、右上のドロップダウンメニューから確認できます。これはコードのブックマークのようなものです。
GitHub上の公開リポジトリは、スターを付けたり、ウォッチしたり、「フォーク」することができます。スターを付けたリポジトリは、右上のドロップダウンメニューから確認できます。これは、コードをブックマークするようなものです。
プロジェクトには、通常 GitHub の「Issues」タブにある課題トラッカーがあり、そこでプロジェクトに関連する問題について議論します。また、「Pull Requests」タブでは、進行中の変更について議論やレビューが行われます。
プロジェクトには、通常「Issues」タブにある課題トラッカー特にGitHub上があります。ここでは、プロジェクトに関連する問題について議論が行われます。また、「Pull Requests」タブでは、進行中の変更について議論やレビューが行われます。
プロジェクトによっては、フォーラム、メーリングリスト、Slack、Discord、IRC などのチャットチャンネルで議論が行われることもあります。
プロジェクトによっては、フォーラム、メーリングリスト、Slack、Discord、IRCなどのチャットチャンネルで議論が行われることもあります。
✅ 新しい GitHub リポジトリを見て回り、設定を編集したり、リポジトリに情報を追加したり、プロジェクト(例えばカンバンボード)を作成したりしてみてください。できることはたくさんあります!
✅ 新しいGitHubリポジトリを見て回り、設定を編集したり、リポジトリに情報を追加したり、プロジェクト例えばカンバンボードを作成したりしてみましょう。できることはたくさんあります!
---
## 🚀 チャレンジ
友達とペアを組んでお互いのコードに取り組みましょう。共同でプロジェクトを作成し、コードをフォークし、ブランチを作成し、変更をマージしてください。
友達とペアを組んでお互いのコードに取り組みましょう。共同でプロジェクトを作成し、コードをフォークし、ブランチを作成し、変更をマージしてみてください。
## 講義後のクイズ
[講義後のクイズ](https://ff-quizzes.netlify.app/web/quiz/4)
[講義後のクイズ](https://ff-quizzes.netlify.app/web/en/)
## 復習と自己学習
[オープンソースソフトウェアへの貢献について](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution)をさらに読んでみましょう
[オープンソースソフトウェアへの貢献についてもっと読む](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution)。
[Git チートシート](https://training.github.com/downloads/github-git-cheat-sheet/)。
[Gitチートシート](https://training.github.com/downloads/github-git-cheat-sheet/)。
練習、練習、練習。GitHub には [skills.github.com](https://skills.github.com) を通じて素晴らしい学習パスが用意されています:
練習、練習、練習。GitHubには[skills.github.com](https://skills.github.com)で利用できる素晴らしい学習パスがあります:
- [GitHub の最初の一週間](https://skills.github.com/#first-week-on-github)
- [GitHubでの最初の1週間](https://skills.github.com/#first-week-on-github)
さらに高度なコースも見つかります。
さらに高度なコースも見つけることができます。
## 課題
[GitHub の最初の一週間コース](https://skills.github.com/#first-week-on-github)を完了してください。
[GitHubでの最初の1週間コース](https://skills.github.com/#first-week-on-github)を完了してください。
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は責任を負いません。

@ -1,25 +1,25 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e4cd5b1faed4adab5acf720f82798003",
"translation_date": "2025-08-23T23:24:56+00:00",
"original_hash": "7598502c4dd1630c72b19ae6bd2523a4",
"translation_date": "2025-08-28T18:02:41+00:00",
"source_file": "1-getting-started-lessons/3-accessibility/README.md",
"language_code": "ja"
}
-->
# アクセシブルなウェブページの作成
![アクセシビリティについて](../../../../sketchnotes/webdev101-a11y.png)
![アクセシビリティについて](../../../../translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前のクイズ
[講義前のクイズ](https://ff-quizzes.netlify.app/web/quiz/5)
## 講義前のクイズ
[講義前のクイズ](https://ff-quizzes.netlify.app/web/)
> ウェブの力はその普遍性にあります。障害の有無にかかわらず、誰もがアクセスできることが重要です。
>
> Webの力はその普遍性にあります。障害の有無にかかわらず、誰もがアクセスできることが重要です。
>
> \- Sir Timothy Berners-Lee, W3Cディレクター、ワールドワイドウェブの発明者
この引用は、アクセシブルなウェブサイトを作成する重要性を完璧に強調しています。すべての人がアクセスできないアプリケーションは、定義上排他的です。ウェブ開発者として、常にアクセシビリティを念頭に置くべきです。最初からこの点に焦点を当てることで、作成するページがすべての人にアクセス可能であることを確保する道を進むことができます。このレッスンでは、ウェブ資産がアクセシブルであることを確認するためのツールと、アクセシビリティを考慮して構築する方法について学びます。
この引用は、アクセシブルなウェブサイトを作成する重要性を完璧に強調しています。すべての人がアクセスできないアプリケーションは、定義上排他的です。ウェブ開発者として、常にアクセシビリティを念頭に置くべきです。最初からこの点に焦点を当てることで、作成するページがすべての人にアクセス可能であることを確保する道を進むことができます。このレッスンでは、ウェブ資産がアクセシブルであることを確保するためのツールと、アクセシビリティを考慮した構築方法について学びます。
> このレッスンは[Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon)で受講できます!
@ -27,35 +27,35 @@ CO_OP_TRANSLATOR_METADATA:
### スクリーンリーダー
最もよく知られているアクセシビリティツールの1つがスクリーンリーダーです。
最もよく知られているアクセシビリティツールのつがスクリーンリーダーです。
[スクリーンリーダー](https://en.wikipedia.org/wiki/Screen_reader)は、視覚障害のある人々がよく使用するクライアントです。ブラウザが共有したい情報を適切に伝えるようにするのと同様に、スクリーンリーダーが同じように情報を伝えることを確認する必要があります。
[スクリーンリーダー](https://en.wikipedia.org/wiki/Screen_reader)は、視覚障害を持つ人々がよく使用するクライアントです。ブラウザが共有したい情報を適切に伝えるようにするのと同様に、スクリーンリーダーが同じ情報を正しく伝えるようにする必要があります。
スクリーンリーダーの基本的な機能は、ページを上から下まで音声で読み上げることです。ページがすべてテキストで構成されている場合、リーダーはブラウザと同様に情報を伝えます。しかし、ウェブページは純粋にテキストだけで構成されることはほとんどありません。リンク、グラフィック、色、その他の視覚的要素が含まれることが一般的です。これらの情報がスクリーンリーダーによって正しく読み取られるように注意を払う必要があります。
スクリーンリーダーは基本的に、ページを上から下まで音声で読み上げます。ページがすべてテキストで構成されている場合、リーダーはブラウザと同様に情報を伝えます。しかし、ウェブページは純粋にテキストだけで構成されることはほとんどありません。リンク、グラフィック、色、その他の視覚的要素が含まれることが一般的です。これらの情報がスクリーンリーダーによって正しく読み取られるように注意を払う必要があります。
すべてのウェブ開発者はスクリーンリーダーに慣れるべきです。上記で強調したように、それはユーザーが利用するクライアントです。ブラウザの操作方法に慣れているのと同じように、スクリーンリーダーの操作方法を学ぶべきです。幸いなことに、ほとんどのオペレーティングシステムにはスクリーンリーダーが組み込まれています。
すべてのウェブ開発者はスクリーンリーダーに慣れるべきです。上記で強調したように、それはユーザーが利用するクライアントです。ブラウザの操作方法に精通しているのと同じように、スクリーンリーダーの操作方法を学ぶべきです。幸いなことに、スクリーンリーダーはほとんどのオペレーティングシステムに組み込まれています。
一部のブラウザには、テキストを音声で読み上げたり、基本的なナビゲーション機能を提供するアクセシビリティツールが組み込まれている場合があります。例えば、[Edgeブラウザのアクセシビリティツール](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features)などです。これらも重要なアクセシビリティツールですが、スクリーンリーダーとは異なる機能を持ち、スクリーンリーダーのテストツールとして誤解してはいけません。
一部のブラウザには、テキストを音声で読み上げたり、基本的なナビゲーション機能を提供するアクセシビリティツールが組み込まれています。例えば、[Edgeブラウザのアクセシビリティツール](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features)などです。ただし、これらはスクリーンリーダーとは異なる機能を持ち、スクリーンリーダーのテストツールとして誤解してはいけません。
✅ スクリーンリーダーとブラウザのテキストリーダーを試してみましょう。Windowsでは[ナレーター](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon)がデフォルトで含まれており、[JAWS](https://webaim.org/articles/jaws/)や[NVDA](https://www.nvaccess.org/about-nvda/)もインストール可能です。macOSやiOSでは[VoiceOver](https://support.apple.com/guide/voiceover/welcome/10)がデフォルトでインストールされています。
### ズーム
視覚障害のある人々がよく使用するもう1つのツールがズーム機能です。最も基本的なズームは静的ズームで、`Control + プラス記号 (+)`を使用するか、画面解像度を下げることで制御されます。このタイプのズームはページ全体をリサイズするため、[レスポンシブデザイン](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design)を使用して、ズームレベルが高い場合でも良好なユーザー体験を提供することが重要です。
視覚障害を持つ人々がよく使用するもう一つのツールがズーム機能です。最も基本的なズームは静的ズームで、`Control + プラス記号 (+)`画面解像度を下げることで制御されます。このタイプのズームはページ全体をリサイズするため、[レスポンシブデザイン](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design)を使用して、ズームレベルが高くても良好なユーザー体験を提供することが重要です。
もう1つのタイプのズームは、特定の画面領域を拡大してパンする特殊なソフトウェアを使用するもので、実際の拡大鏡を使用するようなものです。Windowsでは[拡大鏡](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198)が組み込まれており、[ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/)はより多くの機能を持つサードパーティ製の拡大ソフトウェアです。macOSやiOSには[Zoom](https://www.apple.com/accessibility/mac/vision/)という拡大ソフトウェアが組み込まれています。
もう一つのタイプのズームは、画面の特定の領域を拡大してパンする特殊なソフトウェアを使用します。これは実際の拡大鏡を使用するようなものです。Windowsでは[拡大鏡](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198)が組み込まれており、[ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/)はより多くの機能を持つサードパーティ製の拡大ソフトウェアです。macOSやiOSには[Zoom](https://www.apple.com/accessibility/mac/vision/)という拡大ソフトウェアが組み込まれています。
### コントラストチェッカー
ウェブサイトの色は、色覚異常のあるユーザーや低コントラストの色が見づらい人々のニーズに応えるよう慎重に選ぶ必要があります。
ウェブサイトの色は、色覚異常のユーザーや低コントラストの色を見るのが難しい人々のニーズに応えるよう慎重に選ぶ必要があります。
✅ お気に入りのウェブサイトをブラウザ拡張機能(例: [WCAGのコントラストチェッカー](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon))で色の使用をテストしてみましょう。何が学べますか?
✅ お気に入りのウェブサイトをブラウザ拡張機能で色の使用をテストしてみましょう。例えば[WCAGのコントラストチェッカー](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon)などです。何が学べますか?
### Lighthouse
ブラウザの開発者ツールエリアにはLighthouseツールがあります。このツールは、ウェブサイトのアクセシビリティおよびその他の分析を初めて確認するために重要です。Lighthouseだけに頼るべきではありませんが、100%のスコアは基準として非常に役立ちます。
✅ ブラウザの開発者ツールパネルでLighthouseを見つけ、任意のサイトを分析してみましょう。何がかりますか?
✅ ブラウザの開発者ツールパネルでLighthouseを見つけ、任意のサイトを分析してみましょう。何がかりますか?
## アクセシビリティを考慮したデザイン
@ -69,23 +69,23 @@ CO_OP_TRANSLATOR_METADATA:
### 色の安全なパレット
人々は世界をさまざまな方法で見ていますが、これには色も含まれます。サイトのカラースキームを選択する際には、すべての人にとってアクセシブルであることを確認する必要があります。優れた[カラーパレット生成ツールはColor Safe](http://colorsafe.co/)です。
人々は世界を異なる方法で見ますが、これには色も含まれます。サイトのカラースキームを選択する際には、すべての人にとってアクセシブルであることを確認する必要があります。素晴らしい[カラーパレット生成ツールはColor Safe](http://colorsafe.co/)です。
✅ 色の使用が非常に問題のあるウェブサイトを特定してください。なぜ問題なのでしょうか?
### 正しいHTMLを使用する
CSSやJavaScriptを使用すると、任意の要素を任意のタイプのコントロールのように見せることができます。例えば、`<span>`を使用して`<button>`を作成したり、`<b>`を使用してハイパーリンクを作成することが可能です。しかし、これではスクリーンリーダーに何も伝えられません。ページ上のコントロールを作成する際には適切なHTMLを使用してください。ハイパーリンクを作成したい場合は`<a>`を使用してください。適切なHTMLを使用することは、セマンティックHTMLを活用することと呼ばれます。
CSSやJavaScriptを使用すると、任意の要素を任意のタイプのコントロールのように見せることができます。例えば、`<span>`を使用して`<button>`を作成したり、`<b>`を使用してハイパーリンクを作成することが可能です。しかし、これではスクリーンリーダーに何も伝えません。ページ上のコントロールを作成する際には適切なHTMLを使用してください。ハイパーリンクを作成したい場合は`<a>`を使用してください。適切なHTMLを使用することは、セマンティックHTMLを活用することと呼ばれます。
✅ 任意のウェブサイトにアクセスし、デザイナーや開発者がHTMLを正しく使用しているか確認してください。リンクであるべきボタンを見つけることができますかヒント: ブラウザで右クリックして「ページソースを表示」を選択し、基礎となるコードを確認してください。
✅ 任意のウェブサイトにアクセスし、デザイナーや開発者がHTMLを正しく使用しているか確認してください。リンクであるべきボタンを見つけることができますかヒント: ブラウザで右クリックして「ページソースを表示」を選択し、基礎となるコードを確認してください。
### 説明的な見出し階層を作成する
スクリーンリーダーのユーザーは[見出しに大きく依存しています](https://webaim.org/projects/screenreadersurvey8/#finding)。情報を見つけたり、ページをナビゲートしたりするためです。説明的な見出しコンテンツを作成し、セマンティックな見出しタグを使用することは、スクリーンリーダーのユーザーにとって簡単にナビゲート可能なサイトを作成するために重要です。
スクリーンリーダーのユーザーは[見出しに大きく依存](https://webaim.org/projects/screenreadersurvey8/#finding)して情報を見つけたりページをナビゲートします。説明的な見出しコンテンツを作成し、セマンティックな見出しタグを使用することは、スクリーンリーダーのユーザーにとって簡単にナビゲート可能なサイトを作成するために重要です。
### 良い視覚的手がかりを使用する
CSSはページ上の任意の要素の外観を完全に制御できます。アウトラインのないテキストボックスや下線のないハイパーリンクを作成することが可能です。しかし、これらの手がかりを削除すると、それに依存する人々がコントロールの種類を認識するのが難しくなる可能性があります。
CSSはページ上の任意の要素の外観を完全に制御ます。アウトラインのないテキストボックスや下線のないハイパーリンクを作成することができます。しかし、これらの手がかりを削除すると、それに依存する人々がコントロールの種類を認識するのが難しくなる可能性があります。
## リンクテキストの重要性
@ -93,7 +93,7 @@ CSSはページ上の任意の要素の外観を完全に制御できます。
### スクリーンリーダーとリンク
予想通り、スクリーンリーダーはリンクテキストをページ上の他のテキストと同じように読み取ります。この点を考慮すると、以下のようなテキストは完全に許容されるように感じるかもしれません。
予想通り、スクリーンリーダーはリンクテキストをページ上の他のテキストと同じように読み取ります。この点を考慮すると、以下の例のテキストは完全に許容できるように感じるかもしれません。
> リトルペンギンは、フェアリーペンギンとも呼ばれ、世界で最も小さいペンギンです。[こちらをクリック](https://en.wikipedia.org/wiki/Little_penguin)して詳細をご覧ください。
@ -105,17 +105,17 @@ CSSはページ上の任意の要素の外観を完全に制御できます。
### URLを使用する問題点
スクリーンリーダーはテキストを読み取ります。テキストにURLが含まれている場合、スクリーンリーダーはURLを読み上げます。一般的に、URLは意味のある情報を伝えず、煩わしく聞こえることがあります。携帯電話がテキストメッセージ内のURLを音声で読み上げた経験があるかもしれません。
スクリーンリーダーはテキストを読み取ります。テキストにURLが含まれている場合、スクリーンリーダーはURLを読み上げます。一般的に、URLは意味のある情報を伝えず、煩わしく聞こえることがあります。携帯電話がURLを含むテキストメッセージを音声で読み上げた経験があるかもしれません。
### 「こちらをクリック」の問題点
スクリーンリーダーはページ上のハイパーリンクのみを読み取る機能も持っています。視覚的なユーザーがページをスキャンしてリンクを探すのと同じようにです。リンクテキストがすべて「こちらをクリック」である場合、ユーザーは「こちらをクリック、こちらをクリック、こちらをクリック、こちらをクリック、こちらをクリック、...」としか聞こえません。すべてのリンクが区別できなくなります。
スクリーンリーダーはページ上のハイパーリンクだけを読み取る機能も持っています。視覚的なユーザーがページをスキャンしてリンクを探すのと同じようにです。リンクテキストがすべて「こちらをクリック」である場合、ユーザーは「こちらをクリック、こちらをクリック、こちらをクリック、こちらをクリック、こちらをクリック、...」としか聞こえません。すべてのリンクが区別できなくなります。
### 良いリンクテキスト
良いリンクテキストは、リンク先の内容を簡潔に説明します。上記のリトルペンギンに関する例では、リンクはその種に関するWikipediaページに向けられています。「リトルペンギン」というフレーズは、リンク先で何を学べるかを明確に示しているため、完璧なリンクテキストになります。
良いリンクテキストは、リンク先の内容を簡潔に説明します。上記のリトルペンギンに関する例では、リンク先はその種に関するWikipediaページです。「リトルペンギン」というフレーズは、リンク先で何を学べるかを明確に示しているため、完璧なリンクテキストになります。
> リトルペンギンは、フェアリーペンギンとも呼ばれ、世界で最も小さいペンギンです。[リトルペンギン](https://en.wikipedia.org/wiki/Little_penguin)についてさらに詳しく知る
> [リトルペンギン](https://en.wikipedia.org/wiki/Little_penguin)は、フェアリーペンギンとも呼ばれ、世界で最も小さいペンギンです
✅ 数分間ウェブを閲覧して、曖昧なリンク戦略を使用しているページを見つけてください。それらをより良いリンクを使用しているサイトと比較してください。何が学べますか?
@ -129,22 +129,22 @@ CSSはページ上の任意の要素の外観を完全に制御できます。
| 商品 | 説明 | 注文 |
| ------------ | ------------------ | ------------ |
| Widget | [説明](../../../../1-getting-started-lessons/3-accessibility/') | [注文](../../../../1-getting-started-lessons/3-accessibility/') |
| Super widget | [説明](../../../../1-getting-started-lessons/3-accessibility/') | [注文](../../../../1-getting-started-lessons/3-accessibility/') |
| ウィジェット | [説明](../../../../1-getting-started-lessons/3-accessibility/') | [注文](../../../../1-getting-started-lessons/3-accessibility/') |
| スーパーウィジェット | [説明](../../../../1-getting-started-lessons/3-accessibility/') | [注文](../../../../1-getting-started-lessons/3-accessibility/') |
この例では、説明と注文のテキストを重複させることはブラウザを使用する人にとっては理にかなっています。しかし、スクリーンリーダーを使用する人にとっては、*説明*と*注文*という言葉が文脈なしで繰り返されるだけです。
この例では、ブラウザを使用する人にとって説明と注文のテキストを重複させることは理にかなっています。しかし、スクリーンリーダーを使用する人にとっては、*説明*と*注文*という言葉が文脈なしで繰り返されるだけです。
このようなシナリオをサポートするために、HTMLは[アクセシブルリッチインターネットアプリケーション (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA)と呼ばれる属性セットをサポートしています。これらの属性を使用すると、スクリーンリーダーに追加情報を提供できます。
> **NOTE**: HTMLの多くの側面と同様に、ブラウザやスクリーンリーダーのサポートは異なる場合があります。ただし、ほとんどの主要なクライアントはARIA属性をサポートしています。
> **NOTE**: HTMLの多くの側面と同様に、ブラウザやスクリーンリーダーのサポートは異なる場合があります。ただし、主要なクライアントのほとんどはARIA属性をサポートしています。
`aria-label`を使用して、ページの形式がそれを許さない場合にリンクを説明できます。Widgetの説明は以下のように設定できます:
`aria-label`を使用して、ページの形式がそれを許さない場合にリンクを説明することができます。ウィジェットの説明は以下のように設定できます:
``` html
<a href="#" aria-label="Widget description">description</a>
```
✅ 一般的に、上記で説明したセマンティックマークアップを使用することはARIAの使用に優先しますが、HTMLウィジェットにセマンティックな同等物がない場合があります。良い例はツリーです。ツリーに対応するHTMLの同等物はないため、この要素の汎用的な`<div>`を適切な役割とARIA値で識別します。[MDNのARIAに関するドキュメント](https://developer.mozilla.org/docs/Web/Accessibility/ARIA)にはさらに役立つ情報が含まれています。
✅ 一般的に、上記で説明したセマンティックマークアップを使用することはARIAの使用を上回りますが、HTMLウィジェットにセマンティックな同等物がない場合があります。良い例はツリーです。ツリーにはHTMLの同等物がないため、この要素の汎用的な`<div>`を適切な役割とARIA値で識別します。[MDNのARIAに関するドキュメント](https://developer.mozilla.org/docs/Web/Accessibility/ARIA)にはさらに役立つ情報が含まれています。
```html
<h2 id="tree-label">File Viewer</h2>
@ -155,14 +155,15 @@ CSSはページ上の任意の要素の外観を完全に制御できます。
## 画像
スクリーンリーダーが画像内の内容を自動的に読み取ることができないのは言うまでもありません。画像がアクセシブルであることを確保するのはそれほど手間がかかりません。それが`alt`属性の目的です。すべての意味のある画像には、それが何であるかを説明する`alt`を設定する必要があります。純粋に装飾的な画像の場合、`alt`属性を空の文字列に設定します:`alt=""`。これにより、スクリーンリーダーが装飾的な画像を不必要に読み上げることを防ぎます。
スクリーンリーダーが画像の内容を自動的に読み取ることはできないことは言うまでもありません。画像をアクセシブルにすることはそれほど手間がかかりません。それが`alt`属性の目的です。すべての意味のある画像には、それが何であるかを説明する`alt`を設定する必要があります。
純粋に装飾的な画像の場合、`alt`属性を空の文字列に設定します:`alt=""`。これにより、スクリーンリーダーが装飾的な画像を不必要に読み上げることを防ぎます。
✅ 予想通り、検索エンジンも画像内の内容を理解することができません。検索エンジンもaltテキストを使用します。そのため、ページがアクセシブルであることを確保することで追加のメリットが得られます
✅ 予想通り、検索エンジンも画像の内容を理解することはできません。検索エンジンもaltテキストを使用します。そのため、ページがアクセシブルであることを確保することで追加のメリットが得られます
## キーボード
一部のユーザーはマウスやトラックパッドを使用できず、代わりにキーボード操作に依存してタブキーで要素を移動します。キーボードユーザーが文書を下に移動する際に各インタラクティブ要素にアクセスできるよう、ウェブサイトのコンテンツを論理的な順序で提示することが重要です。セマンティックマークアップを使用してウェブページを構築し、CSSを使用して視覚的なレイアウト
多くの政府はアクセシビリティ要件に関する法律を制定しています。自国のアクセシビリティに関する法律について調べてみましょう。どのような内容が含まれていて、どのような内容が含まれていないのかを確認してください。例えば、[この政府のウェブサイト](https://accessibility.blog.gov.uk/)があります。
一部のユーザーはマウスやトラックパッドを使用できず、代わりにキーボード操作に依存してタブキーで要素を移動します。キーボードユーザーがドキュメントを下に移動する際に各インタラクティブ要素にアクセスできるよう、ウェブサイトのコンテンツを論理的な順序で提示することが重要です。セマンティックマークアップを使用してウェブページを構築し、CSSを使用して視覚的なレイアウトをスタイル設定すれば、サイトはキーボードでナビゲート可能になりますが、この側面を手動でテストすることが重要です。[キーボードナビゲーション戦略](https://webaim.org/techniques/keyboard/)についてさらに
多くの国の政府はアクセシビリティ要件に関する法律を制定しています。自分の国のアクセシビリティに関する法律について調べてみましょう。どのような内容が含まれていて、どのような内容が含まれていないのかを確認してください。例えば、[この政府のウェブサイト](https://accessibility.blog.gov.uk/)があります。
## 課題
@ -170,5 +171,7 @@ CSSはページ上の任意の要素の外観を完全に制御できます。
クレジット: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) by Instrument
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤った解釈について、当方は責任を負いません。

@ -1,19 +1,19 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "fc6aef8ecfdd5b0ad2afa6e6ba52bfde",
"translation_date": "2025-08-23T22:47:50+00:00",
"original_hash": "b95fdd8310ef467305015ece1b0f9411",
"translation_date": "2025-08-28T17:55:27+00:00",
"source_file": "2-js-basics/1-data-types/README.md",
"language_code": "ja"
}
-->
# JavaScriptの基本: データ型
![JavaScript Basics - Data types](../../../../sketchnotes/webdev101-js-datatypes.png)
![JavaScript Basics - Data types](../../../../translated_images/webdev101-js-datatypes.4cc470179730702c756480d3ffa46507f746e5975ebf80f99fdaaf1cff09a7f4.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前のクイズ
[講義前のクイズ](https://ff-quizzes.netlify.app/web/quiz/7)
[講義前のクイズ](https://ff-quizzes.netlify.app/web/)
このレッスンでは、ウェブ上でインタラクティブ性を提供する言語であるJavaScriptの基本を学びます。
@ -31,7 +31,7 @@ CO_OP_TRANSLATOR_METADATA:
変数はコード内で使用したり変更したりできる値を格納します。
変数を**宣言**する際の構文は **[キーワード] [名前]** です。これは以下の2つの部分で構成されています:
変数を作成して**宣言**するには、次の構文を使用します: **[キーワード] [名前]**。これは以下の2つの部分で構成されています:
- **キーワード**: キーワードには`let`や`var`が使用できます。
@ -46,7 +46,7 @@ CO_OP_TRANSLATOR_METADATA:
let myVariable;
```
`myVariable`は`let`キーワードを使用して宣言されましたが、現在は値が設定されていません。
`myVariable`は`let`キーワードを使用して宣言されましたが、現在は値を持っていません。
1. **値を代入する**: `=`演算子を使用して変数に値を格納します。その後に期待される値を記述します。
@ -56,23 +56,23 @@ CO_OP_TRANSLATOR_METADATA:
> 注意: このレッスンでの`=`の使用は、変数に値を設定するための「代入演算子」を意味します。これは等号を意味するものではありません。
`myVariable`は現在123という値で*初期化*されています。
`myVariable`は現在、値123で*初期化*されています。
1. **リファクタリング**: 次のコードに置き換えてみましょう
1. **リファクタリングする**: 次の文にコードを置き換えてください
```javascript
let myVariable = 123;
```
上記は_明示的初期化_と呼ばれ、変数を宣言すると同時に値を代入する方法です。
上記は_明示的初期化_と呼ばれ、変数が宣言されると同時に値が代入されます。
1. **変数の値を変更する**: 次の方法で変数の値を変更してみましょう:
1. **変数の値を変更する**: 次の方法で変数の値を変更します:
```javascript
myVariable = 321;
```
変数が宣言されると、コード内の任意のポイントで`=`演算子と新しい値を使用してその値を変更することができます。
変数が宣言されると、コード内の任意の時点で`=`演算子と新しい値を使用してその値を変更できます。
✅ 試してみましょうブラウザでJavaScriptを直接書くことができます。ブラウザウィンドウを開き、開発者ツールに移動してください。コンソールでプロンプトが表示されます。`let myVariable = 123`と入力してリターンキーを押し、その後`myVariable`と入力してください。何が起こりますか?これらの概念については後のレッスンでさらに学びます。
@ -86,23 +86,23 @@ const MY_VARIABLE = 123;
定数は変数と似ていますが、以下の2つの例外があります:
- **値が必要**: 定数は初期化されていなければならず、コードを実行するとエラーが発生します。
- **参照を変更できない**: 定数が初期化されると、その参照を変更することはできず、コードを実行するとエラーが発生します。以下の例を見てみましょう:
- **単純な値**: 次のコードは許可されません:
- **値が必要**: 定数は初期化されていなとエラーが発生します。
- **参照を変更できない**: 定数が初期化されると、その参照を変更することはできず、コード実行時にエラーが発生します。以下の例を見てみましょう:
- **単純な値**: 次の操作は許可されません:
```javascript
const PI = 3;
PI = 4; // not allowed
```
- **オブジェクト参照が保護される**: 次のコードは許可されません:
- **オブジェクト参照が保護される**: 次の操作は許可されません:
```javascript
const obj = { a: 3 };
obj = { b: 5 } // not allowed
```
- **オブジェクトの値は保護されない**: 次のコードは許可されます:
- **オブジェクトの値は保護されない**: 次の操作は許可されます:
```javascript
const obj = { a: 3 };
@ -115,9 +115,9 @@ const MY_VARIABLE = 123;
## データ型
変数には、数値やテキストなどさまざまな種類の値を格納できます。これらの異なる種類の値は**データ型**として知られています。データ型はソフトウェア開発において重要な要素であり、コードの書き方やソフトウェアの動作方法に関する判断を助けます。さらに、一部のデータ型には、値を変換したり追加情報を抽出したりするための独自の機能があります。
変数には、数値やテキストなどさまざまな種類の値を格納できます。これらのさまざまな種類の値は**データ型**として知られています。データ型はソフトウェア開発において重要な部分であり、コードの書き方やソフトウェアの動作方法に関する決定を助けます。さらに、一部のデータ型には、値を変換したり追加情報を抽出したりするためのユニークな機能があります。
✅ データ型はJavaScriptのデータプリミティブとも呼ばれ、言語によって提供される最も低レベルのデータ型です。プリミティブデータ型には、string、number、bigint、boolean、undefined、null、symbolの7種類があります。それぞれが何を表しているかをイメージしてみてください。`zebra`とは何でしょう?`0`は?`true`は?
✅ データ型はJavaScriptのデータプリミティブとも呼ばれ、言語によって提供される最も低レベルのデータ型です。プリミティブデータ型は7種類あります: string, number, bigint, boolean, undefined, null, symbol。それぞれが何を表しているかをイメージしてみてください。`zebra`とは何でしょう?`0`は?`true`は?
### 数値
@ -125,19 +125,19 @@ const MY_VARIABLE = 123;
`let myVariable = 123;`
変数には、小数や負の数を含むすべての種類の数値を格納できます。数値はまた、[次のセクション](../../../../2-js-basics/1-data-types)で説明する算術演算子とともに使用することができます。
変数には、小数や負の数を含むすべての種類の数値を格納できます。数値はまた、[次のセクション](../../../../2-js-basics/1-data-types)で説明する算術演算子とともに使用できます。
### 算術演算子
算術関数を実行する際に使用る演算子にはいくつかの種類があり、以下にその一部を示します:
算術関数を実行する際に使用できる演算子にはいくつかの種類があり、以下にその一部を示します:
| 記号 | 説明 | 例 |
| ------ | -------------------------------------------------------------------- | -------------------------------- |
| `+` | **加算**: 2つの数値の合計を計算 | `1 + 2 //期待される答えは3` |
| `-` | **減算**: 2つの数値の差を計算 | `1 - 2 //期待される答えは-1` |
| `*` | **乗算**: 2つの数値の積を計算 | `1 * 2 //期待される答えは2` |
| `/` | **除算**: 2つの数値の商を計算 | `1 / 2 //期待される答えは0.5` |
| `%` | **剰余**: 2つの数値の除算から得られる余りを計算 | `1 % 2 //期待される答えは1` |
| 記号 | 説明 | 例 |
| ------ | ---------------------------------------------------------------------- | -------------------------------- |
| `+` | **加算**: 2つの数値の合計を計算します | `1 + 2 //期待される答えは3` |
| `-` | **減算**: 2つの数値の差を計算します | `1 - 2 //期待される答えは-1` |
| `*` | **乗算**: 2つの数値の積を計算します | `1 * 2 //期待される答えは2` |
| `/` | **除算**: 2つの数値の商を計算します | `1 / 2 //期待される答えは0.5` |
| `%` | **剰余**: 2つの数値の除算から得られる余りを計算します | `1 % 2 //期待される答えは1` |
✅ 試してみましょう!ブラウザのコンソールで算術演算を試してみてください。結果に驚きましたか?
@ -153,7 +153,7 @@ const MY_VARIABLE = 123;
### 文字列のフォーマット
文字列はテキストであり、時フォーマットが必要になります。
文字列はテキストであり、時にはフォーマットが必要になります。
2つ以上の文字列を**結合**するには、`+`演算子を使用します。
@ -169,7 +169,7 @@ myString1 + ", " + myString2 + "!"; //Hello, World!
✅ なぜJavaScriptでは`1 + 1 = 2`ですが、`'1' + '1' = 11`になるのでしょう?考えてみてください。では`'1' + 1`はどうでしょう?
**テンプレートリテラル**は文字列をフォーマットするもう一つの方法で、クォートの代わりにバックティックを使用します。プレーンテキスト以外のものはすべて`${ }`の中に入れる必要があります。これには文字列である可能性のある変数も含まれます。
**テンプレートリテラル**は文字列をフォーマットするもう一つの方法で、クォートの代わりにバックティックを使用します。プレーンテキスト以外のものはすべて`${ }`内に配置する必要があります。これには文字列である可能性のある変数も含まれます。
```javascript
let myString1 = "Hello";
@ -179,35 +179,37 @@ let myString2 = "World";
`${myString1}, ${myString2}!` //Hello, World!
```
どちらの方法でもフォーマットの目を達成できますが、テンプレートリテラルはスペースや改行を尊重します。
どちらの方法でもフォーマットの目を達成できますが、テンプレートリテラルはスペースや改行を尊重します。
✅ テンプレートリテラルとプレーン文字列を使い分けるのはどんな場合でしょう?
### ブール値
ブール値は`true`または`false`の2つの値のみを持つことができます。ブール値は、特定の条件が満たされた場合にどのコード行を実行するかを決定するのに役立ちます。多くの場合、[演算子](../../../../2-js-basics/1-data-types)がブール値の設定を助け、変数が初期化されたりその値が更新されたりする際に演算子が頻繁に使用されることに気付くでしょう
ブール値は`true`または`false`の2つの値のみを持つことができます。ブール値は、特定の条件が満たされた場合にどのコード行を実行するかを決定するのに役立ちます。多くの場合、[演算子](../../../../2-js-basics/1-data-types)がブール値の設定を助け、変数が初期化されたりその値が更新されたりする際に頻繁に使用されます
- `let myTrueBool = true`
- `let myFalseBool = false`
✅ 変数は、ブール値`true`に評価される場合「truthy」と見なされます。興味深いことに、JavaScriptでは[すべての値はfalsyと定義されない限りtruthyです](https://developer.mozilla.org/docs/Glossary/Truthy)。
✅ 変数は、ブール値`true`に評価される場合「truthy」と見なされます。興味深いことに、JavaScriptでは[明示的にfalsyと定義されていない限り、すべての値はtruthy](https://developer.mozilla.org/docs/Glossary/Truthy)です
---
## 🚀 チャレンジ
JavaScriptは時折データ型を扱う際に驚くべき挙動を示すことで有名です。これらの「落とし穴」について少し調べてみましょう。例えば: 大文字小文字の区別に注意!コンソールで次を試してみてください: `let age = 1; let Age = 2; age == Age` (結果は`false` -- なぜでしょう?)。他にどんな落とし穴が見つかりますか?
JavaScriptは時折、データ型の扱い方が驚くべき方法で知られています。これらの「落とし穴」について少し調べてみましょう。例えば: 大文字小文字の区別が問題になることがあります!コンソールで次を試してみてください: `let age = 1; let Age = 2; age == Age`(結果は`false`になります -- なぜでしょう?)。他にどんな落とし穴が見つかりますか?
## 講義後のクイズ
[講義後のクイズ](https://ff-quizzes.netlify.app/web/quiz/8)
[講義後のクイズ](https://ff-quizzes.netlify.app)
## 復習と自己学習
[JavaScriptの練習問題一覧](https://css-tricks.com/snippets/javascript/)を見て、1つ試してみましょう。何を学びましたか?
[JavaScriptの練習問題リスト](https://css-tricks.com/snippets/javascript/)を見て、1つ試してみてください。何を学びましたか?
## 課題
[データ型の練習](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解について、当社は責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解について、当社は責任を負いません。

@ -1,37 +1,37 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b4612bbb9ace984f374fcc80e3e035ad",
"translation_date": "2025-08-23T22:41:50+00:00",
"original_hash": "92e136090efc4341b1d51c37924c1802",
"translation_date": "2025-08-28T17:54:32+00:00",
"source_file": "2-js-basics/2-functions-methods/README.md",
"language_code": "ja"
}
-->
# JavaScriptの基本: メソッドと関数
![JavaScript Basics - Functions](../../../../sketchnotes/webdev101-js-functions.png)
![JavaScript Basics - Functions](../../../../translated_images/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/9)
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app)
コードを書くとき、常にコードが読みやすいことを意識する必要があります。一見矛盾しているように思えるかもしれませんが、コードは書かれる回数よりも読む回数の方が圧倒的に多いのです。開発者がメンテナンスしやすいコードを書くための重要なツールの1つが**関数**です。
コードを書くとき、常にコードが読みやすいことを心がける必要があります。一見矛盾しているように思えるかもしれませんが、コードは書かれる回数よりも読む回数の方が圧倒的に多いのです。開発者がメンテナンスしやすいコードを書くための重要なツールの1つが**関数**です。
[![Methods and Functions](https://img.youtube.com/vi/XgKsD6Zwvlc/0.jpg)](https://youtube.com/watch?v=XgKsD6Zwvlc "Methods and Functions")
> 🎥 上の画像をクリックすると、メソッドと関数に関する動画が視聴できます。
> このレッスンは[Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon)で受講できます!
> このレッスンは[Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon)で受講できます!
## 関数
関数の基本は、必要に応じて実行できるコードのブロックです。同じタスクを何度も実行する必要がある場合に最適です。ロジックを複数の場所に重複して記述するのではなく後で更新が難しくなります、1か所に集中させて必要なときに呼び出すことができます。さらに、他の関数から関数を呼び出すことも可能です。
関数の基本は、必要に応じて実行できるコードのブロックです。同じタスクを何度も実行する必要がある場合に最適です。ロジックを複数の場所に重複させるのではなく後で更新が必要になったときに困難になります、1つの場所に集中させて必要なときに呼び出すことができます。さらに、関数を他の関数から呼び出すことも可能です。
関数に名前を付けることも重要です。一見些細なことのように思えるかもしれませんが、名前を付けることでコードのセクションを簡単にドキュメント化できます。これはボタンにラベルを付けるようなものです。「タイマーをキャンセル」と書かれたボタンをクリックすれば、時計が停止することがわかります。
関数に名前を付けることも重要です。一見些細なことのように思えるかもしれませんが、名前はコードのセクションを簡単にドキュメント化する方法を提供します。ボタンのラベルのようなものだと考えることができます。「タイマーをキャンセル」と書かれたボタンをクリックすれば、時計の動作が停止することがわかります。
## 関数の作成と呼び出し
関数の構文は次のようになります:
関数の構文は以下のようになります:
```javascript
function nameOfFunction() { // function definition
@ -39,7 +39,7 @@ function nameOfFunction() { // function definition
}
```
例えば、挨拶を表示する関数を作成したい場合、次のようになります
挨拶を表示する関数を作成したい場合、次のようになります:
```javascript
function displayGreeting() {
@ -47,28 +47,28 @@ function displayGreeting() {
}
```
関数を呼び出す(または実行する)ときは、関数名の後に`()`を付けます。関数は定義される前でも後でも呼び出すことができる点に注目してください。JavaScriptのコンパイラがそれを見つけてくれます。
関数を呼び出す(または実行する)場合は、関数名の後に`()`を付けます。関数は定義される前でも後でも呼び出すことができる点に注意してください。JavaScriptコンパイラが関数を見つけてくれます。
```javascript
// calling our function
displayGreeting();
```
> **NOTE:** **メソッド**と呼ばれる特別な種類の関数があります。実は、すでに使っています!例えば、上記のデモで`console.log`を使用したときがそうです。メソッドと関数の違いは、メソッドがオブジェクト(この場合は`console`)に関連付けられているのに対し、関数は自由に存在する点です。多くの開発者がこれらの用語を混同して使うことがあります。
> **NOTE:** 特殊なタイプの関数として**メソッド**があります。実は、すでに使用しています!例えば、上記のデモで`console.log`を使用したときに見ました。メソッドと関数の違いは、メソッドがオブジェクト(この場合は`console`)に付属しているのに対し、関数は自由に存在する点です。多くの開発者がこれらの用語を同じ意味で使うことがあります。
### 関数のベストプラクティス
関数を作成する際に覚えておくべきベストプラクティスがいくつかあります
関数を作成する際に覚えておくべきベストプラクティスがいくつかあります:
- 常にわかりやすい名前を付けて、関数が何をするのかを明確にする
- 複数の単語を組み合わせる場合は**キャメルケース**を使用する
- 関数特定のタスクに集中させる
- 常にわかりやすい名前を使い、関数が何をするのかを明確にする
- **camelCasing**を使用して単語を結合する
- 関数特定のタスクに集中させる
## 関数に情報を渡す
関数をより再利用可能にするために、情報を渡すことがよくあります。上記の`displayGreeting`の例を考えると、**Hello, world!**しか表示しません。これではあまり役に立つ関数とは言えません。例えば、挨拶する相手の名前を指定できるようにしたい場合、**パラメータ**を追加します。パラメータ(**引数**とも呼ばれることがあります)は、関数に送られる追加情報です。
関数をより再利用可能にするために、情報を渡すことがよくあります。上記の`displayGreeting`の例を考えると、**Hello, world!**しか表示しません。あまり役に立つ関数とは言えません。これを少し柔軟にして、挨拶する人の名前を指定できるようにするには、**パラメータ**を追加します。パラメータ(**引数**とも呼ばれることがあります)は、関数に送られる追加情報です。
パラメータは定義部分で括弧内にカンマ区切りで記述します:
パラメータは定義部分の括弧内に記載され、カンマで区切られます:
```javascript
function name(param, param2, param3) {
@ -76,7 +76,7 @@ function name(param, param2, param3) {
}
```
`displayGreeting`を更新して名前を受け取り、それを表示するようにできます。
`displayGreeting`を更新して名前を受け取り、それを表示するようにます。
```javascript
function displayGreeting(name) {
@ -85,7 +85,7 @@ function displayGreeting(name) {
}
```
関数を呼び出してパラメータを渡すときは、括弧内に指定します。
関数を呼び出してパラメータを渡したい場合は、括弧内に指定します。
```javascript
displayGreeting('Christopher');
@ -94,7 +94,7 @@ displayGreeting('Christopher');
## デフォルト値
関数をさらに柔軟にするために、パラメータを増やすことができます。しかし、すべての値を必須にしたくない場合はどうすればよいでしょうか?挨拶の例を続けると、名前は必須(誰に挨拶するのかを知る必要があります)が、挨拶の内容はカスタマイズ可能にしたい場合があります。その場合、デフォルト値を提供します。パラメータにデフォルト値を設定するには、変数に値を設定するのと同じ方法で行います - `parameterName = 'defaultValue'`。完全な例を見てみましょう:
関数をさらに柔軟にするために、パラメータを増やすことができます。しかし、すべての値を指定する必要がない場合はどうすればよいでしょうか?挨拶の例を続けると、名前は必須(誰に挨拶するかを知る必要があります)ですが、挨拶自体は必要に応じてカスタマイズできるようにしたいです。カスタマイズしたくない場合は、代わりにデフォルト値を提供します。パラメータにデフォルト値を設定するには、変数に値を設定するのと同じ方法で行います - `parameterName = 'defaultValue'`。完全な例を以下に示します:
```javascript
function displayGreeting(name, salutation='Hello') {
@ -102,7 +102,7 @@ function displayGreeting(name, salutation='Hello') {
}
```
関数を呼び出すとき、`salutation`の値を設定するかどうかを選択できます。
関数を呼び出す際に、`salutation`の値を設定するかどうかを選択できます。
```javascript
displayGreeting('Christopher');
@ -114,11 +114,11 @@ displayGreeting('Christopher', 'Hi');
## 戻り値
これまでに作成した関数は常に[コンソール](https://developer.mozilla.org/docs/Web/API/console)に出力されます。これは、他のサービスを呼び出す関数を作成する場合には理想的です。しかし、計算を行い、その値を他の場所で使用するために返したい場合はどうすればよいでしょうか?
これまでに作成した関数は常に[console](https://developer.mozilla.org/docs/Web/API/console)に出力されます。これは、他のサービスを呼び出す関数を作成する場合にはまさに求めているものかもしれません。しかし、計算を行い、その値を返して他の場所で使用したい場合はどうすればよいでしょうか?
これを実現するには、**戻り値**を使用します。戻り値は関数から返され、文字列や数値のようなリテラル値と同じように変数に格納できます。
これを実現するには、**戻り値**を使用します。戻り値は関数によって返され、文字列や数値などのリテラル値と同じように変数に格納できます。
関数が何かを返す場合、`return`キーワードを使用します。`return`キーワードは返される値や参照を期待します:
関数が何かを返す場合、キーワード`return`が使用されます。`return`キーワードは返される値や参照を期待します。以下のように:
```javascript
return myVariable;
@ -133,7 +133,7 @@ function createGreetingMessage(name) {
}
```
この関数を呼び出すとき、その値を変数に格納します。これは、静的な値(例: `const name = 'Christopher'`)を変数に設定するのと同じ方法です。
この関数を呼び出す際には、値を変数に格納します。これは、静的な値(例えば`const name = 'Christopher'`)を変数に設定するのとほぼ同じ方法です。
```javascript
const greetingMessage = createGreetingMessage('Christopher');
@ -141,11 +141,11 @@ const greetingMessage = createGreetingMessage('Christopher');
## 関数を関数のパラメータとして使用する
プログラミングのキャリアを進める中で、関数をパラメータとして受け取る関数に出会うことがあります。この便利なトリックは、何かがいつ発生するのか、または完了するのかがわからない場合に、何かに応答して操作を実行する必要があるときによく使われます。
プログラミングのキャリアを進めるにつれて、関数をパラメータとして受け取る関数に出会うことがあります。この便利な技法は、何かが発生するタイミングや完了するタイミングがわからない場合に、応答として操作を実行する必要があるときによく使用されます。
例として、[setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout)を考えてみましょう。これはタイマーを開始し、完了したときにコードを実行します。どのコードを実行するかを指定する必要があります。これは関数にぴったりの仕事です!
例として、[setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout)を考えてみましょう。これはタイマーを開始し、完了したときにコードを実行します。どのコードを実行するかを指定する必要があります。関数を使うのにぴったりの仕事です
以下のコードを実行すると、3秒後に**3 seconds has elapsed**というメッセージが表示されます。
以下のコードを実行すると、3秒後に**3秒が経過しました**というメッセージが表示されます。
```javascript
function displayDone() {
@ -157,11 +157,11 @@ setTimeout(displayDone, 3000);
### 無名関数
作成したコードをもう一度見てみましょう。一度だけ使用される名前付き関数を作成しています。アプリケーションが複雑になるにつれて、一度しか呼び出されない関数をたくさん作成することになるかもしれません。これは理想的ではありません。実は、名前を付ける必要がない場合もあります!
作成したコードをもう一度見てみましょう。一度だけ使用される名前付き関数を作成しています。アプリケーションが複雑になるにつれて、一度しか呼び出されない関数をたくさん作成することが予想されます。これは理想的ではありません。実は、名前を付ける必要がない場合もあります!
関数をパラメータとして渡す場合、事前に作成するのではなく、パラメータの一部として作成することができます。同じ`function`キーワードを使用しますが、パラメータとして構築します。
関数をパラメータとして渡す場合、事前に作成するのを省略し、パラメータの一部として作成することができます。同じ`function`キーワードを使用しますが、パラメータとして構築します。
上記のコードを無名関数を使用するように書き換えてみましょう
上記のコードを無名関数を使用するように書き換えてみましょう:
```javascript
setTimeout(function() {
@ -169,13 +169,13 @@ setTimeout(function() {
}, 3000);
```
新しいコードを実行すると、同じ結果が得られることに気付くでしょう。関数を作成しましたが、名前を付ける必要はありませんでした!
新しいコードを実行すると、同じ結果が得られることがわかります。関数を作成しましたが、名前を付ける必要はありませんでした!
### ファットアロー関数
多くのプログラミング言語JavaScriptを含むで一般的なショートカットとして、**アロー関数**または**ファットアロー関数**と呼ばれるものがあります。これは`=>`という特別な記号を使用します。この記号が矢印のように見えるため、この名前が付けられています!`=>`を使用することで、`function`キーワードを省略できます。
多くのプログラミング言語JavaScriptを含むで一般的なショートカットとして、**アロー**または**ファットアロー**関数と呼ばれるものを使用することができます。これは`=>`という特別な記号を使用し、矢印のように見えるため、この名前が付けられています!`=>`を使用することで、`function`キーワードを省略できます。
もう一度コードを書き換えて、ファットアロー関数を使用してみましょう
もう一度コードを書き換えて、ファットアロー関数を使用してみましょう:
```javascript
setTimeout(() => {
@ -183,9 +183,9 @@ setTimeout(() => {
}, 3000);
```
### 各戦略を使タイミング
### 各戦略を使用するタイミング
関数をパラメータとして渡す方法を3つ見てきましたが、それぞれをいつ使べきか疑問に思うかもしれません。関数を複数回使用することがわかっている場合は、通常通り作成します。1か所でしか使用しない場合は、無名関数を使用するのが一般的です。ファットアロー関数を使うか、従来の`function`構文を使うかは好みの問題ですが、ほとんどの現代の開発者は`=>`を好む傾向があります。
関数をパラメータとして渡す方法を3つ見てきましたが、それぞれをいつ使用するべきか疑問に思うかもしれません。関数を複数回使用することがわかっている場合は、通常通り作成します。1つの場所でのみ使用する場合は、無名関数を使用するのが一般的に最適です。ファットアロー関数を使用するか、従来の`function`構文を使用するかはあなた次第ですが、ほとんどの現代の開発者は`=>`を好む傾向があります。
---
@ -193,16 +193,18 @@ setTimeout(() => {
関数とメソッドの違いを1文で説明できますか挑戦してみてください
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/10)
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app)
## 復習と自己学習
[アロー関数についてもう少し読む](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions)価値があります。コードベースでますます使用されるようになっています。関数を1つ書いてみて、その後この構文で書き直してみてください。
[アロー関数についてもう少し読む](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions)価値があります。コードベースでますます使用されるようになっています。関数を作成し、それをこの構文で書き換える練習をしてみてください。
## 課題
[Fun with Functions](assignment.md)
[関数で遊ぼう](assignment.md)
---
**免責事項**:
この文書はAI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された原文が正式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてご参照ください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は責任を負いません。

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "888609c48329c280ca2477d2df40f2e5",
"translation_date": "2025-08-23T22:38:38+00:00",
"original_hash": "f7009631b73556168ca435120a231c98",
"translation_date": "2025-08-28T17:55:02+00:00",
"source_file": "2-js-basics/3-making-decisions/README.md",
"language_code": "ja"
}
-->
# JavaScriptの基本: 判断を行う
# JavaScriptの基本: 判断をする
![JavaScript Basics - Making decisions](../../../../sketchnotes/webdev101-js-decisions.png)
![JavaScript Basics - Making decisions](../../../../translated_images/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
@ -21,15 +21,15 @@ CO_OP_TRANSLATOR_METADATA:
[![Making Decisions](https://img.youtube.com/vi/SxTp8j-fMMY/0.jpg)](https://youtube.com/watch?v=SxTp8j-fMMY "Making Decisions")
> 🎥 上の画像をクリックすると、判断を行う方法についての動画が再生されます。
> 🎥 上の画像をクリックすると、判断についての動画が再生されます。
> このレッスンは[Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-if-else/?WT.mc_id=academic-77807-sagibbon)で受講できます!
## Booleanの簡単な復習
Booleanは`true`または`false`の2つの値しか持ちません。Booleanは、特定の条件が満たされた場合にどのコードを実行するかを判断するのに役立ちます。
Booleanは`true`または`false`の2つの値しか持ちません。Booleanは、特定の条件が満たされた場合にどのコードを実行するかを判断するのに役立ちます。
Booleanを`true`または`false`に設定するには、以下のように記述します:
Booleanを`true`または`false`に設定する方法は以下の通りです:
`let myTrueBool = true`
`let myFalseBool = false`
@ -38,16 +38,16 @@ Booleanを`true`または`false`に設定するには、以下のように記述
## 比較演算子とBoolean
演算子は条件を評価し、Boolean値を生成するために使用されます。以下はよく使用される演算子の一覧です。
演算子は条件を評価し、比較を行うことでBoolean値を生成します。以下はよく使用される演算子の一覧です。
| 記号 | 説明 | 例 |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- |
| `<` | **より小さい**: 2つの値を比較し、左側の値が右側より小さい場合に`true`を返します | `5 < 6 // true` |
| `<=` | **以下**: 2つの値を比較し、左側の値が右側以下の場合に`true`を返します | `5 <= 6 // true` |
| `>` | **より大きい**: 2つの値を比較し、左側の値が右側より大きい場合に`true`を返します | `5 > 6 // false` |
| `>=` | **以上**: 2つの値を比較し、左側の値が右側以上の場合に`true`を返します | `5 >= 6 // false` |
| `===` | **厳密な等価性**: 2つの値を比較し、値が等しく、かつデータ型も同じ場合に`true`を返します | `5 === 6 // false` |
| `!==` | **不等価**: 2つの値を比較し、厳密な等価性演算子が返す値の逆を返します | `5 !== 6 // true` |
| 記号 | 説明 | 例 |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `<` | **より小さい**: 左側の値が右側より小さい場合に`true`を返します | `5 < 6 // true` |
| `<=` | **以下**: 左側の値が右側以下の場合に`true`を返します | `5 <= 6 // true` |
| `>` | **より大きい**: 左側の値が右側より大きい場合に`true`を返します | `5 > 6 // false` |
| `>=` | **以上**: 左側の値が右側以上の場合に`true`を返します | `5 >= 6 // false` |
| `===` | **厳密な等価性**: 左右の値が等しく、かつ同じデータ型の場合に`true`を返します | `5 === 6 // false` |
| `!==` | **不等価**: 厳密な等価性演算子が返す値の逆のBoolean値を返します | `5 !== 6 // true` |
✅ ブラウザのコンソールでいくつかの比較を書いてみて、返されるデータに驚くことがあるか確認してください。
@ -61,7 +61,7 @@ if (condition) {
}
```
論理演算子は、条件を形成するためによく使用されます。
条件を形成するために論理演算子がよく使用されます。
```javascript
let currentMoney;
@ -90,7 +90,7 @@ if (currentMoney >= laptopPrice) {
}
```
✅ このコードと以下のコードをブラウザのコンソールで実行して理解を深めてください。`currentMoney``laptopPrice`変数の値を変更して、`console.log()`の結果を変えてみましょう。
✅ このコードと以下のコードをブラウザのコンソールで実行して理解を深めてください。`currentMoney``laptopPrice`変数の値を変更して、`console.log()`の結果を変えてみましょう。
## Switch文
@ -133,11 +133,11 @@ console.log(`The value is ${a}`);
判断には複数の比較が必要な場合があり、論理演算子を使ってBoolean値を生成することができます。
| 記号 | 説明 | 例 |
| ------ | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `&&` | **論理AND**: 2つのBoolean式を比較します。両方が`true`の場合のみ`true`を返します | `(5 > 6) && (5 < 6 ) //片方はfalse、もう片方はtrue。結果はfalse` |
| `\|\|` | **論理OR**: 2つのBoolean式を比較します。少なくとも片方が`true`の場合に`true`を返します | `(5 > 6) \|\| (5 < 6) //片方はfalse、もう片方はtrue。結果はtrue` |
| `!` | **論理NOT**: Boolean式の値を反転して返します | `!(5 > 6) // 5は6より大きくないが、"!"はtrueを返します` |
| 記号 | 説明 | 例 |
| ------ | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `&&` | **論理AND**: 2つのBoolean式を比較します。両方が`true`の場合のみ`true`を返します | `(5 > 6) && (5 < 6 ) //片方はfalse、もう片方はtrue。結果はfalse` |
| `\|\|` | **論理OR**: 2つのBoolean式を比較します。片方でも`true`の場合に`true`を返します | `(5 > 6) \|\| (5 < 6) //片方はfalse、もう片方はtrue。結果はtrue` |
| `!` | **論理NOT**: Boolean式の値を反転して返します | `!(5 > 6) // 5は6より大きくないが、"!"はtrueを返します` |
## 論理演算子を使った条件と判断
@ -159,7 +159,7 @@ if (currentMoney >= laptopPrice || currentMoney >= laptopDiscountPrice) {
### 否定演算子
これまでに`if...else`文を使って条件付きロジックを作成する方法を見てきました。`if`に入るものはすべて`true`または`false`に評価される必要があります。`!`演算子を使用することで、式を反転(否定)することができます。以下のように記述します:
これまでに`if...else`文を使って条件付きロジックを作成する方法を見てきました。`if`に入るものはすべて`true`または`false`に評価される必要があります。`!`演算子を使用することで、式を反転(否定)することができます。以下のようになります:
```javascript
if (!condition) {
@ -171,7 +171,7 @@ if (!condition) {
### 三項演算子
`if...else`判断ロジックを表現する唯一の方法ではありません。三項演算子と呼ばれるものを使用することもできます。その構文は以下のようになります:
`if...else`条件ロジックを表現する唯一の方法ではありません。三項演算子と呼ばれるものを使用することもできます。その構文は以下のようになります:
```javascript
let variable = condition ? <return this if true> : <return this if false>
@ -191,7 +191,7 @@ let biggestNumber = firstNumber > secondNumber ? firstNumber : secondNumber;
- `firstNumber`が`secondNumber`より大きい場合
- `firstNumber`を`biggestNumber`に代入する
- そうでない場合は`secondNumber`を代入する
- そうでない場合は`secondNumber`を代入する
三項演算子は以下のコードを簡潔に書く方法です:
@ -226,5 +226,7 @@ Josh Comeauの素晴らしい[演算子検索ツール](https://joshwcomeau.com/
[Operators](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確さが含まれる可能性があります。元の言語で記載された原文が公式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳をお勧めします。本翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。

@ -1,21 +1,21 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "3f7f87871312cf6cc12662da7d973182",
"translation_date": "2025-08-23T22:44:45+00:00",
"original_hash": "9029f96b0e034839c1799f4595e4bb66",
"translation_date": "2025-08-28T17:56:02+00:00",
"source_file": "2-js-basics/4-arrays-loops/README.md",
"language_code": "ja"
}
-->
# JavaScript 基礎: 配列とループ
# JavaScriptの基本: 配列とループ
![JavaScript Basics - Arrays](../../../../sketchnotes/webdev101-js-arrays.png)
![JavaScript Basics - Arrays](../../../../translated_images/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/13)
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/13)
このレッスンでは、ウェブ上でインタラクティブ性を提供する言語であるJavaScriptの基礎を学びます。このレッスンでは、データを操作するために使用される配列とループについて学びます。
このレッスンでは、ウェブ上でインタラクティブな機能を提供するJavaScriptの基本について学びます。このレッスンでは、データを操作するために使用される配列とループについて学びます。
[![配列](https://img.youtube.com/vi/1U4qTyq02Xw/0.jpg)](https://youtube.com/watch?v=1U4qTyq02Xw "配列")
@ -23,13 +23,13 @@ CO_OP_TRANSLATOR_METADATA:
> 🎥 上記の画像をクリックすると、配列とループに関する動画が視聴できます。
> このレッスンは [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-arrays/?WT.mc_id=academic-77807-sagibbon) 受講できます!
> このレッスンは[Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-arrays/?WT.mc_id=academic-77807-sagibbon)で受講できます!
## 配列
データを扱うことはどのプログラミング言語でも一般的なタスクであり、配列のような構造化された形式でデータが整理されていると、作業がはるかに簡単になります。配列を使うと、リストのような構造でデータを保存できます。配列の大きな利点の1つは、1つの配列に異なる種類のデータを保存できることです。
データを扱うことはどのプログラミング言語でも一般的な作業であり、配列のような構造化された形式でデータが整理されていると、作業が非常に簡単になります。配列を使用すると、リストに似た構造でデータを保存できます。配列の大きな利点は、1つの配列に異なる種類のデータを保存できることです。
✅ 配列は私たちの身の回りにたくさんあります!例えば、ソーラーパネルの配列のような実生活の例を思い浮かべられますか?
✅ 配列は私たちの周りにたくさんあります!例えば、太陽光パネルの配列のような実生活の例を思い浮かべられますか?
配列の構文は、角括弧のペアです。
@ -37,55 +37,55 @@ CO_OP_TRANSLATOR_METADATA:
let myArray = [];
```
これは空の配列ですが、配列はデータをすでに格納した状態で宣言することもできます。配列内の複数の値はカンマで区切られます。
これは空の配列ですが、配列はすでにデータが入った状態で宣言することもできます。配列内の複数の値はコンマで区切られます。
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
```
配列の値には**インデックス**と呼ばれる一意の値が割り当てられます。インデックスは配列の先頭からの距離に基づいて割り当てられる整数です。上記の例では、文字列値 "Chocolate" のインデックスは0で、"Rocky Road" のインデックスは4です。インデックスを角括弧とともに使用して、配列の値を取得、変更、または挿入できます。
配列の値には**インデックス**と呼ばれる一意の値が割り当てられます。インデックスは配列の先頭からの距離に基づいて割り当てられる整数です。上記の例では、文字列値「Chocolate」のインデックスは0で、「Rocky Road」のインデックスは4です。インデックスを角括弧とともに使用して、配列の値を取得、変更、または挿入できます。
✅ 配列がゼロインデックスから始まることに驚きましたか一部のプログラミング言語では、インデックスは1から始まります。この歴史については[Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering) で読むことができます。
✅ 配列がゼロインデックスから始まることに驚きましたか一部のプログラミング言語では、インデックスは1から始まります。この歴史については[Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering)で読むことができます。
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
iceCreamFlavors[2]; //"Vanilla"
```
インデックスを利用して値を変更することもできます。例えば、次のようにします:
インデックスを利用して値を変更することができます。例えば以下のように:
```javascript
iceCreamFlavors[4] = "Butter Pecan"; //Changed "Rocky Road" to "Butter Pecan"
```
また、指定したインデックスに新しい値を挿入することもできます
また、指定したインデックスに新しい値を挿入することもできます
```javascript
iceCreamFlavors[5] = "Cookie Dough"; //Added "Cookie Dough"
```
✅ 配列に値を追加するより一般的な方法は、array.push() のような配列演算子を使用することです。
✅ 配列に値を追加するより一般的な方法は、array.push()のような配列演算子を使用することです。
配列内の項目数を調べるには、`length` プロパティを使用します。
配列内の項目数を調べるには、`length`プロパティを使用します。
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
iceCreamFlavors.length; //5
```
✅ 自分で試してみましょう!ブラウザのコンソールを使て、自分で作成した配列を操作してみてください。
✅ 自分で試してみましょう!ブラウザのコンソールを使用して、自分で作成した配列を操作してみてください。
## ループ
ループを使用すると、繰り返しまたは**反復的**なタスクを実行でき、時間とコードを大幅に節約できます。各反復では変数、値、条件が異なる場合があります。JavaScriptにはさまざまな種類のループがあり、それぞれに小さな違いがありますが、本質的には同じことを行います:データをループすることです。
ループを使用すると、繰り返しまたは**反復**的な作業を行うことができ、時間とコードを大幅に節約できます。各反復では変数、値、条件が異なる場合があります。JavaScriptにはさまざまな種類のループがあり、それぞれに小さな違いがありますが、基本的には同じことを行います: データをループすることです。
### Forループ
`for` ループは、反復するために次の3つの部分が必要です
`for`ループは反復するために3つの部分が必要です:
- `counter` 通常、反復回数を数えるために数値で初期化される変数
- `condition` 比較演算子を使用して、`false` になったときにループを停止させる式
- `condition` 比較演算子を使用して`false`になるとループを停止させる式
- `iteration-expression` 各反復の最後に実行され、通常はカウンター値を変更するために使用される
```javascript
// Counting up to 10
for (let i = 0; i < 10; i++) {
@ -93,11 +93,11 @@ for (let i = 0; i < 10; i++) {
}
```
✅ このコードをブラウザのコンソールで実行してみてください。カウンター、条件、または反復式を少し変更するとどうなりますか?逆方向に実行してカウントダウンを作成できますか?
✅ このコードをブラウザのコンソールで実行してみましょう。カウンター、条件、または反復式を少し変更するとどうなりますか?逆方向に動作させてカウントダウンを作成できますか?
### Whileループ
`for` ループの構文とは異なり、`while` ループは条件だけを必要とし、その条件が `false` になるとループが停止します。ループ内の条件は通常、カウンターのような他の値に依存し、ループ中に管理する必要があります。カウンターの初期値はループの外で作成する必要があり、条件を満たすための式(カウンターの変更を含む)はループ内で維持する必要があります。
`for`ループの構文とは異なり、`while`ループは条件だけを必要とし、その条件が`false`になるとループを停止します。ループ内の条件は通常、カウンターなどの他の値に依存し、ループ中に管理する必要があります。カウンターの初期値はループの外で作成する必要があり、条件を満たすための式やカウンターの変更はループ内で維持する必要があります。
```javascript
//Counting up to 10
@ -108,11 +108,11 @@ while (i < 10) {
}
```
✅ なぜforループを選ぶのか、またはwhileループを選ぶのか17,000人の視聴者がStackOverflowで同じ質問をしました。その意見のいくつかは[こちらで興味深く読めます](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript)。
✅ なぜforループではなくwhileループを選ぶのでしょうかStackOverflowでは17K人の視聴者が同じ質問をしており、いくつかの意見が[興味深いかもしれません](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript)。
## ループと配列
配列はループと一緒に使用されることが多いです。ほとんどの条件はループを停止するために配列の長さを必要とし、インデックスもカウンター値として使用できます。
配列はループと一緒に使用されることが多いです。ほとんどの条件は配列の長さを使用してループを停止し、インデックスはカウンター値としても使用できます。
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
@ -122,24 +122,26 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
} //Ends when all flavors are printed
```
✅ 自分で作成した配列をブラウザのコンソールでループしてみてください
✅ 自分で作成した配列をブラウザのコンソールでループしてみましょう
---
## 🚀 チャレンジ
forやwhileループ以外にも配列をループする方法があります。[forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)、[for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of)、[map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map) などです。これらの技術の1つを使って、配列ループを書き直してみましょう。
配列をループする方法はforループやwhileループだけではありません。[forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)、[for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of)、[map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map)などがあります。これらの技術のいずれかを使用して、配列ループを書き直してみましょう。
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/14)
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/14)
## 復習と自己学習
JavaScriptの配列には、データ操作に非常に便利な多くのメソッドが付属しています。[これらのメソッドについて調べる](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) とともに、push、pop、slice、spliceなど自分で作成した配列で試してみてください
JavaScriptの配列には、データ操作に非常に便利な多くのメソッドが付属しています。[これらのメソッドについて読む](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)とともに、作成した配列でいくつか試してみてください例えばpush、pop、slice、spliceなど
## 課題
[配列をループする](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。元の言語で記載された文書が公式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "46a0639e719b9cf1dfd062aa24cad639",
"translation_date": "2025-08-23T22:25:36+00:00",
"original_hash": "89f7f9f800ce7c9f149e98baaae8491a",
"translation_date": "2025-08-28T17:56:25+00:00",
"source_file": "3-terrarium/1-intro-to-html/README.md",
"language_code": "ja"
}
-->
# テラリウムプロジェクト パート1: HTMLの紹介
![HTMLの紹介](../../../../sketchnotes/webdev101-html.png)
![HTMLの紹介](../../../../translated_images/webdev101-html.4389c2067af68e98280c1bde52b6c6269f399eaae3659b7c846018d8a7b0bbd9.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前クイズ
@ -21,17 +21,17 @@ CO_OP_TRANSLATOR_METADATA:
>
> [![GitとGitHubの基本動画](https://img.youtube.com/vi/1TvxJKBzhyQ/0.jpg)](https://www.youtube.com/watch?v=1TvxJKBzhyQ)
### 紹介
### はじめに
HTMLHyperText Markup Languageはウェブの「骨格」です。CSSがHTMLを「装飾」し、JavaScriptが命を吹き込むなら、HTMLはウェブアプリケーションの「体」です。HTMLの構文はそのアイデアを反映しており、「head」、「body」、「footer」タグが含まれています。
HTMLHyperText Markup Languageはウェブの「骨格」です。CSSがHTMLを「装飾」し、JavaScriptが命を吹き込むなら、HTMLはウェブアプリケーションの「体」です。HTMLの構文はその考えを反映しており、「head」、「body」、「footer」タグが含まれています。
このレッスンでは、HTMLを使って仮想テラリウムのインターフェースの「骨格」をレイアウトします。タイトルと3つの列を持つインターフェースを作成します。右と左の列にはドラッグ可能な植物が配置され、中央のエリアは実際のガラスのようなテラリウムになります。このレッスンの終わりには、列に植物が表示されますが、インターフェースは少し奇妙に見えるかもしれません。心配しないでください。次のセクションでCSSスタイルを追加してインターフェースを改善します。
このレッスンでは、HTMLを使って仮想テラリウムのインターフェースの「骨格」をレイアウトします。タイトルと3つの列を持つ構造を作ります。右と左の列にはドラッグ可能な植物が配置され、中央のエリアが実際のガラスのようなテラリウムになります。このレッスンの終わりには、列に植物が表示されますが、インターフェースは少し奇妙に見えるかもしれません。心配しないでください。次のセクションでCSSスタイルを追加してインターフェースを改善します。
### タスク
コンピュータ上で「terrarium」というフォルダを作成し、その中に「index.html」というファイルを作成してください。Visual Studio Codeを使用してフォルダを作成した後、新しいVS Codeウィンドウを開き、「フォルダを開く」をクリックして新しいフォルダに移動します。エクスプローラペインの小さな「ファイル」ボタンをクリックして新しいファイルを作成ます。
コンピュータ上で「terrarium」というフォルダを作成し、その中に「index.html」というファイルを作成してください。Visual Studio Codeで新しいウィンドウを開き、「フォルダを開く」をクリックして新しいフォルダに移動しエクスプローラペインの小さな「ファイル」ボタンをクリックして新しいファイルを作成できます。
![VS Codeのエクスプローラ](../../../../3-terrarium/1-intro-to-html/images/vs-code-index.png)
![VS Codeのエクスプローラ](../../../../translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.ja.png)
または
@ -41,44 +41,44 @@ Git Bashで以下のコマンドを使用してください:
* `touch index.html`
* `code index.html` または `nano index.html`
> index.htmlファイルはブラウザにフォルダ内のデフォルトファイルであることを示します。例えば、`https://anysite.com/test`のようなURLは、`test`というフォルダとその中の`index.html`ファイルを使用して構築される可能性があります。URLには`index.html`が表示される必要はありません。
> index.htmlファイルはブラウザにフォルダ内のデフォルトファイルであることを示します。例えば、`https://anysite.com/test`のようなURLは、`test`というフォルダとその中の`index.html`を含むフォルダ構造で構築されている可能性があります。URLには`index.html`が表示される必要はありません。
---
## DocTypeとhtmlタグ
HTMLファイルの最初の行はDocTypeです。この行をファイルの最上部に配置する必要があるのは少し驚きですが、これは古いブラウザに現在のHTML仕様に従ってページを標準モードでレンダリングする必要があることを伝えます。
HTMLファイルの最初の行はDocTypeです。この行をファイルの最上部に配置する必要があるのは少し驚きですが、古いブラウザに現在のHTML仕様に従ってページを標準モードでレンダリングする必要があることを伝えます。
> ヒント: VS Codeでは、タグにカーソルを合わせるとMDNリファレンスガイドからその使用に関する情報を取得できます。
> ヒント: VS Codeでは、タグにカーソルを合わせるとMDNリファレンスガイドからその使用方法に関する情報を取得できます。
2行目には`<html>`タグの開始タグが続き、その後すぐに終了タグ`</html>`が続きます。これらのタグはインターフェースのルート要素です。
2行目には`<html>`タグの開始タグを記述し、その後すぐに終了タグ`</html>`を記述します。これらのタグはインターフェースのルート要素です。
### タスク
`index.html`ファイルの最上部に以下の行を追加してください:
以下の行を`index.html`ファイルの最上部に追加してください:
```HTML
<!DOCTYPE html>
<html></html>
```
✅ DocTypeをクエリ文字列で設定することで決定されるいくつかの異なるモードがあります: [Quirks ModeとStandards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode)。これらのモードは通常使用されない非常に古いブラウザNetscape Navigator 4やInternet Explorer 5をサポートしていました。標準のDocType宣言を使用してください
✅ DocTypeをクエリ文字列で設定することで決定されるいくつかの異なるモードがあります: [Quirks ModeとStandards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode)。これらのモードは通常使用されない古いブラウザNetscape Navigator 4やInternet Explorer 5をサポートしていました。標準のDocType宣言を使用することをお勧めします
---
## ドキュメントの「head」
HTMLドキュメントの「head」エリアには、ウェブページに関する重要な情報、いわゆる[メタデータ](https://developer.mozilla.org/docs/Web/HTML/Element/meta)が含まれています。私たちの場合、このページがレンダリングされるウェブサーバーに以下の4つの情報を伝えます:
HTMLドキュメントの「head」エリアには、ウェブページに関する重要な情報、いわゆる[メタデータ](https://developer.mozilla.org/docs/Web/HTML/Element/meta)が含まれています。ここでは、レンダリングされるウェブサーバーに以下の4つの情報を伝えます:
- ページのタイトル
- ページのメタデータ:
- 使用される文字エンコーディングを示す「文字セット」
- ブラウザ情報(`x-ua-compatible`を含む)、これはIE=edgeブラウザがサポートされていることを示しま
- ビューポートが読み込まれる際の動作に関する情報。ビューポートの初期スケールを1に設定することで、ページが最初に読み込まれる際のズームレベルを制御します。
- ブラウザ情報(`x-ua-compatible`を含む、IE=edgeブラウザがサポートされていることを示す
- ページが読み込まれたときのビューポートの動作に関する情報。ビューポートの初期スケールを1に設定することで、ページが最初に読み込まれたときのズームレベルを制御します。
### タスク
`<html>`タグの開始タグと終了タグの間に「head」ブロックを追加してください。
開いている`<html>`タグと閉じている`</html>`タグの間に「head」ブロックを追加してください。
```html
<head>
@ -89,7 +89,7 @@ HTMLドキュメントの「head」エリアには、ウェブページに関す
</head>
```
✅ ビューポートメタタグを次のように設定した場合、何が起こるでしょうか: `<meta name="viewport" content="width=600">`? [ビューポート](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag)についてさらに詳しく読んでください。
✅ ビューポートメタタグを次のように設定した場合、何が起こるでしょうか: `<meta name="viewport" content="width=600">`? [ビューポート](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag)についてさらにんでください。
---
@ -97,7 +97,7 @@ HTMLドキュメントの「head」エリアには、ウェブページに関す
### HTMLタグ
HTMLでは、.htmlファイルにタグを追加してウェブページの要素を作成します。各タグは通常、開始タグと終了タグを持ちます。例えば、`<p>hello</p>`は段落を示します。`<html>`タグペアの内側に`<body>`タグを追加してインターフェースの本文を作成してください。現在のマークアップは次のようになります:
HTMLでは、.htmlファイルにタグを追加してウェブページの要素を作成します。各タグは通常、次のように開始タグと終了タグを持ちます: `<p>hello</p>`(段落を示します)。インターフェースのボディを作成するには、`<html>`タグペアの内側に`<body>`タグを追加します。これでマークアップは次のようになります:
### タスク
@ -114,17 +114,17 @@ HTMLでは、.htmlファイルにタグを追加してウェブページの要
</html>
```
これでページを構築し始めることができます。通常、ページ内の個別の要素を作成するために`<div>`タグを使用します。画像を含む一連の`<div>`要素を作成します。
これでページを構築し始めることができます。通常、ページ内の個別の要素を作成するために`<div>`タグを使用します。一連の`<div>`要素を作成し、それらに画像を含めます。
### 画像
閉じタグを必要としないHTMLタグの1つは`<img>`タグです。これは`src`要素を持ち、ページがアイテムをレンダリングするために必要なすべての情報を含んでいます。
閉じタグを必要としないHTMLタグの1つは`<img>`タグです。このタグには`src`要素があり、ページがアイテムをレンダリングするために必要な情報がすべて含まれています。
アプリ内に`images`というフォルダを作成し、その中に[ソースコードフォルダ](../../../../3-terrarium/solution/images)にあるすべての画像を追加してください。植物の画像が14枚あります
### タスク
`<body></body>`タグの間にこれらの植物画像を2つの列に追加してください:
以下の植物画像を`<body></body>`タグの間に2つの列として追加してください:
```html
<div id="page">
@ -177,27 +177,27 @@ HTMLでは、.htmlファイルにタグを追加してウェブページの要
</div>
```
> 注: SpansとDivs。Divsは「ブロック」要素と見なされ、Spansは「インライン」です。これらのdivをspanに変換した場合、何が起こるでしょうか
> 注: SpansとDivs。Divsは「ブロック」要素と見なされ、Spansは「インライン」です。これらのdivをspanに変換した場合、何が起こるでしょうか
このマークアップにより、植物が画面に表示されます。ただし、まだCSSでスタイルが設定されていないため、見た目はかなり悪いです。次のレッスンでCSSを使用してスタイルを設定します。
各画像には、画像が表示されない場合でも表示されるaltテキストがあります。これはアクセシビリティのために含める重要な属性です。アクセシビリティについては今後のレッスンでさらに学びますが、alt属性は画像を表示できない場合に代替情報を提供します(接続が遅い場合、src属性にエラーがある場合、またはユーザーがスクリーンリーダーを使用している場合など)。
各画像には、画像が表示されない場合でも表示されるaltテキストがあります。これはアクセシビリティのために重要な属性です。アクセシビリティについては今後のレッスンでさらに学びますが、alt属性は画像を表示できない場合接続が遅い、src属性にエラーがある、またはスクリーンリーダーを使用している場合などに代替情報を提供します
✅ 各画像に同じaltタグがあることに気きましたか?これは良いプラクティスでしょうか?なぜそうではないのでしょうか?このコードを改善できますか?
✅ 各画像に同じaltタグがあることに気きましたか?これは良いプラクティスでしょうか?なぜそうではないのでしょうか?このコードを改善できますか?
---
## セマンティックマークアップ
一般的に、HTMLを書く際には意味のある「セマンティクス」を使用することが推奨されます。それはどういう意味でしょうかそれは、データやインタラクションの種類に応じて設計されたHTMLタグを使用することを意味します。例えば、ページのメインタイトルテキストには`<h1>`タグを使用するべきです。
一般的に、HTMLを書く際には意味のある「セマンティクス」を使用することが推奨されます。それはどういう意味でしょうかそれは、データやインタラクションの種類を表すために設計されたHTMLタグを使用することを意味します。例えば、ページのメインタイトルテキストには`<h1>`タグを使用するべきです。
`<body>`タグの開始タグのすぐ下に次の行を追加してください:
以下の行を開いている`<body>`タグのすぐ下に追加してください:
```html
<h1>My Terrarium</h1>
```
ヘッダーを`<h1>`にし、順序なしリストを`<ul>`としてレンダリングするなど、セマンティックマークアップを使用することで、スクリーンリーダーがページをナビゲートしやすくなります。一般的に、ボタンは`<button>`として書かれるべきであり、リストは`<li>`として書かれるべきです。特別にスタイル設定された`<span>`要素をクリックハンドラーでボタンのように模倣することは可能ですが、ボタンがページのどこにあるかを判断し、それと対話するために技術を使用することができる障害のあるユーザーにとって、要素がボタンとして表示される方が良いです。この理由から、可能な限りセマンティックマークアップを使用するようにしてください。
ヘッダーを`<h1>`として、順序なしリストを`<ul>`としてレンダリングするなど、セマンティックマークアップを使用することで、スクリーンリーダーがページをナビゲートしやすくなります。一般的に、ボタンは`<button>`として記述し、リストは`<li>`として記述するべきです。特別にスタイル設定された`<span>`要素にクリックハンドラーを追加してボタンを模倣することは可能ですが、ボタンがページのどこにあるかを判断し、それと対話するための技術を使用する障害のあるユーザーにとっては、要素がボタンとして表示される方が良いです。この理由から、可能な限りセマンティックマークアップを使用するようにしてください。
✅ スクリーンリーダーがウェブページとどのように対話するかを[確認してください](https://www.youtube.com/watch?v=OUDV1gqs9GA)。セマンティックでないマークアップがユーザーをどのように苛立たせるかがわかりますか?
@ -207,7 +207,7 @@ HTMLでは、.htmlファイルにタグを追加してウェブページの要
### タスク:
最後の`</div>`タグの上にのマークアップを追加してください:
最後の`</div>`タグの上に以下のマークアップを追加してください:
```html
<div id="terrarium">
@ -235,7 +235,7 @@ HTMLにはまだ遊べる「古い」タグがいくつかありますが、[こ
## 復習と自己学習
HTMLはウェブを今日の姿に成長させた「信頼できる」構築ブロックシステムです。古いタグと新しいタグを学び、その歴史について少し学んでください。なぜ一部のタグが廃止され、一部が追加されたのかを理解できますか?将来どのようなタグが導入される可能性があるでしょうか?
HTMLはウェブを今日の姿に成長させた「信頼できる」構築ブロックシステムです。古いタグと新しいタグについて少し学び、その歴史を調べてください。なぜ一部のタグが廃止され、一部が追加されたのかを理解できますか?将来どのようなタグが導入される可能性があるでしょうか?
ウェブとモバイルデバイス向けのサイト構築についてさらに学ぶには、[Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon)をご覧ください。
@ -243,5 +243,7 @@ HTMLはウェブを今日の姿に成長させた「信頼できる」構築ブ
[HTMLを練習: ブログのモックアップを作成](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。元の言語で記載された文書が公式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e375c2aeb94e2407f2667633d39580bd",
"translation_date": "2025-08-23T22:34:04+00:00",
"original_hash": "acb5ae00cde004304296bb97da8ff4c3",
"translation_date": "2025-08-28T17:56:57+00:00",
"source_file": "3-terrarium/2-intro-to-css/README.md",
"language_code": "ja"
}
-->
# テラリウムプロジェクト パート2: CSS入門
![CSS入門](../../../../sketchnotes/webdev101-css.png)
![CSS入門](../../../../translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前クイズ
@ -18,16 +18,16 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
CSSCascading Style Sheetsは、ウェブ開発における重要な課題、つまりウェブサイトを見栄え良くする方法を解決します。アプリにスタイルを適用することで、使いやすく、見た目も良くなります。また、CSSを使えばレスポンシブウェブデザインRWDを実現でき、どの画面サイズでもアプリが美しく表示されるようになります。CSSは単に見た目を整えるだけでなく、アニメーションや変形を含む仕様もあり、アプリに高度なインタラクションを追加することが可能です。CSSワーキンググループは現在のCSS仕様を維持する役割を担っており、その活動は[World Wide Web Consortiumのサイト](https://www.w3.org/Style/CSS/members)で確認できます。
CSSCascading Style Sheetsは、ウェブ開発における重要な課題、つまりウェブサイトを見栄え良くする方法を解決します。アプリにスタイルを適用することで、使いやすく、見た目も良くなります。また、CSSを使えばレスポンシブウェブデザインRWDを実現でき、どの画面サイズでもアプリが美しく表示されるようになります。CSSは単に見た目を良くするだけでなく、アニメーションや変形を含む仕様もあり、アプリに高度なインタラクションを可能にします。CSSワーキンググループは現在のCSS仕様を維持する役割を担っており、その活動は[World Wide Web Consortiumのサイト](https://www.w3.org/Style/CSS/members)で確認できます。
> [!NOTE]
> CSSはウェブの他の技術と同様に進化する言語であり、すべてのブラウザが最新の仕様をサポートしているわけではありません。[CanIUse.com](https://caniuse.com)を参照して実装を確認することを忘れないでください
> CSSはウェブの他の技術と同様に進化する言語であり、すべてのブラウザが最新の仕様をサポートしているわけではありません。[CanIUse.com](https://caniuse.com)を参照して実装を確認することをお勧めします
このレッスンでは、オンラインテラリウムにスタイルを追加し、CSSのいくつかの概念について学びます。具体的には、カスケード、継承、セレクタの使用、配置、レイアウト構築にCSSを活用する方法について学びます。この過程で、テラリウムのレイアウトを作成し、実際のテラリウムを構築します。
このレッスンでは、オンラインテラリウムにスタイルを追加し、CSSのいくつかの概念について学びます。具体的には、カスケード、継承、セレクタの使用、配置、CSSを使ったレイアウト構築について学びます。この過程で、テラリウムのレイアウトを作成し、実際のテラリウムを構築します。
### 前提条件
テラリウムのHTMLが完成しており、スタイルを適用する準備ができている必要があります
テラリウムのHTMLが構築済みで、スタイルを適用する準備ができていること
> 動画をチェック
@ -36,7 +36,7 @@ CSSCascading Style Sheetsは、ウェブ開発における重要な課題
### タスク
テラリウムフォルダ内に新しいファイル`style.css`を作成し、それを`<head>`セクションにインポートします:
テラリウムフォルダ内に`style.css`という新しいファイルを作成します。そのファイルを`<head>`セクションでインポートします:
```html
<link rel="stylesheet" href="./style.css" />
@ -46,11 +46,11 @@ CSSCascading Style Sheetsは、ウェブ開発における重要な課題
## カスケード
Cascading Style Sheetsカスケーディングスタイルシートは、スタイルが「カスケード」するという考え方を取り入れています。つまり、スタイルの適用はその優先順位によって決まります。ウェブサイトの作成者が設定したスタイルは、ブラウザが設定したスタイルよりも優先されます。また、インラインで設定されたスタイルは、外部スタイルシートで設定されたスタイルよりも優先されます。
Cascading Style Sheetsカスケーディングスタイルシートは、スタイルの適用が優先順位によってガイドされる「カスケード」の概念を取り入れています。ウェブサイトの作者が設定したスタイルは、ブラウザが設定したスタイルよりも優先されます。また、インラインで設定されたスタイルは、外部スタイルシートで設定されたスタイルよりも優先されます。
### タスク
`<h1>`タグにインラインスタイル`color: red`を追加します:
`<h1>`タグにインラインスタイル「color: red」を追加します:
```HTML
<h1 style="color: red">My Terrarium</h1>
@ -64,17 +64,17 @@ h1 {
}
```
✅ あなたのウェブアプリではどの色が表示されますか?なぜですか?スタイルを上書きする方法を見つけられますか?いつ、またはなぜこれを行う必要があるのでしょうか?
✅ あなたのウェブアプリではどの色が表示されますか?なぜですか?スタイルを上書きする方法を見つけられますか?いつ、またはなぜこれを行うべきではないのでしょうか?
---
## 継承
スタイルは、祖先のスタイルから子孫に継承されます。つまり、ネストされた要素は親要素のスタイルを引き継ぎます。
スタイルは、祖先のスタイルから子孫に継承されます。つまり、ネストされた要素は親要素のスタイルを継承します。
### タスク
`body`のフォントを指定し、ネストされた要素のフォントを確認します:
bodyのフォントを指定されたフォントに設定し、ネストされた要素のフォントを確認します:
```CSS
body {
@ -82,11 +82,11 @@ body {
}
```
ブラウザのコンソールを開き、「Elements」タブで`<h1>`のフォントを観察してください。ブラウザ内で指定された通り、`body`からフォントを継承しています。
ブラウザのコンソールを開き、「Elements」タブでH1のフォントを観察します。ブラウザ内で示されているように、H1はbodyからフォントを継承しています。
![継承されたフォント](../../../../3-terrarium/2-intro-to-css/images/1.png)
![継承されたフォント](../../../../translated_images/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.ja.png)
✅ ネストされたスタイルが異なるプロパティを継承するようにできますか?
✅ ネストされたスタイルに異なるプロパティを継承させることはできますか?
---
@ -94,7 +94,7 @@ body {
### タグ
これまでの`style.css`ファイルでは、いくつかのタグにしかスタイルが適用されておらず、アプリの見た目少し奇妙です:
これまでの`style.css`ファイルでは、いくつかのタグにしかスタイルが適用されておらず、アプリの見た目少し奇妙です:
```CSS
body {
@ -107,11 +107,11 @@ h1 {
}
```
このようにタグをスタイリングすることで、特定の要素を制御できますが、テラリウム内の多くの植物のスタイルを制御する必要があります。そのためには、CSSセレクタを活用する必要があります。
このようにタグをスタイリングすることで、ユニークな要素を制御できますが、テラリウム内の多くの植物のスタイルを制御する必要があります。そのためには、CSSセレクタを活用する必要があります。
### ID
左と右のコンテナにスタイルを追加します。マークアップ内で左コンテナと右コンテナはそれぞれ1つしか存在しないため、IDが付けられています。これをスタイリングするには`#`を使用します:
左と右のコンテナをレイアウトするためにスタイルを追加します。マークアップ内で左コンテナと右コンテナはそれぞれ1つしかないため、IDが付けられています。これをスタイリングするには`#`を使用します:
```CSS
#left-container {
@ -135,9 +135,9 @@ h1 {
}
```
ここでは、これらのコンテナを絶対配置で画面の左端と右端に配置し、幅をパーセンテージで指定して、小さなモバイル画面にも対応できるようにしています。
ここでは、これらのコンテナを画面の左端と右端に絶対配置し、幅をパーセンテージで指定して、小さなモバイル画面にも対応できるようにしています。
✅ このコードはかなり繰り返しが多く、「DRY」Don't Repeat Yourself: 繰り返しを避ける)ではありません。マークアップを変更し、CSSをリファクタリングすることで、IDとクラスを組み合わせてより良い方法を見つけられますか
✅ このコードはかなり繰り返しが多く、「DRY」Don't Repeat Yourself: 繰り返しを避けるではありません。IDとクラスを組み合わせてより良いスタイル方法を見つけられますか?マークアップを変更し、CSSをリファクタリングする必要があります:
```html
<div id="left-container" class="container"></div>
@ -145,9 +145,9 @@ h1 {
### クラス
上記の例では、画面上の2つのユニークな要素をスタイリングしました。画面上の多くの要素にスタイルを適用したい場合は、CSSクラスを使用できます。これを使って、左と右のコンテナ内の植物をレイアウトます。
上記の例では、画面上の2つのユニークな要素をスタイリングしました。画面上の多くの要素にスタイルを適用したい場合は、CSSクラスを使用できます。左と右のコンテナ内の植物をレイアウトするためにこれを行います。
HTMLマークアップ内の各植物には、IDとクラスの組み合わせが含まれています。ここでのIDは、後で追加するJavaScriptによってテラリウム内の植物の配置を操作するために使用されます。一方、クラスはすべての植物に特定のスタイルを適用します。
HTMLマークアップ内の各植物には、IDとクラスの組み合わせがあります。ここでのIDは、後で追加するJavaScriptがテラリウムの植物配置を操作するために使用します。一方、クラスはすべての植物に特定のスタイルを適用します。
```html
<div class="plant-holder">
@ -172,29 +172,30 @@ HTMLマークアップ内の各植物には、IDとクラスの組み合わせ
}
```
このスニペットで注目すべき点は、相対配置と絶対配置の組み合わせです。この点については次のセクションで説明します。高さの扱いにパーセンテージを使用している点にも注目してください:
このスニペットで注目すべき点は、相対配置と絶対配置の組み合わせです。高さがパーセンテージで処理されている方法を見てください:
- 植物ホルダーの高さを13%に設定しています。これにより、各垂直コンテナ内すべての植物がスクロールなしで表示されるようになります。
- 植物ホルダーを左に移動させ、植物がコンテナ内でより中央に配置されるようにしています。画像にはドラッグ可能にするための透明な背景が多く含まれているため、画面上でより適切に収まるよう左に寄せる必要があります。
- 植物自体には最大幅150%を設定しています。これにより、ブラウザが縮小されると植物も縮小されます。ブラウザのサイズを変更してみてください。植物はコンテナ内に収まり続け、縮小してフィットします。
- 植物ホルダーの高さを13%に設定しています。これにより、各垂直コンテナ内すべての植物がスクロールなしで表示されるようになります。
- 植物ホルダーを左に移動させ、植物がコンテナ内でより中央に配置されるようにしています。画像にはドラッグ可能にするための透明な背景が多く含まれているため、画面上でより適切にフィットするように左に押し出す必要があります。
- 植物自体には最大幅150%を設定しています。これにより、ブラウザが縮小されると植物も縮小されます。ブラウザのサイズを変更してみてください。植物はコンテナ内に収まりつつ、縮小してフィットします。
また、`z-index`の使用にも注目してください。これは要素の相対的な高さを制御し、植物がコンテナの上に配置され、テラリウム内に収まっているように見せます
また、z-indexの使用も注目すべき点です。これは要素の相対的な高さを制御し植物がコンテナの上に座り、テラリウム内に配置されているように見えるようにします
✅ なぜ植物ホルダーと植物の両方にCSSセレクタが必要なのでしょうか
## CSSの配置
位置プロパティstatic、relative、fixed、absolute、sticky組み合わせるのは少し難しいですが、適切に行うとページ上の要素をうまく制御できます。
位置プロパティstatic、relative、fixed、absolute、sticky混在させるのは少し難しいですが、適切に行うとページ上の要素をうまく制御できます。
絶対配置された要素は、最も近い配置された祖先を基準に配置されます。祖先がない場合は、ドキュメントのボディを基準に配置されます。
絶対配置された要素は、最も近い配置された祖先を基準に配置されます。祖先がない場合は、ドキュメントのボディに基づいて配置されます。
相対配置された要素は、CSSの指示に基づいて元の位置から調整されます。
相対配置された要素は、CSSの指示に基づいて元の位置から離れて配置されます。
このサンプルでは、`plant-holder`は相対配置された要素で、絶対配置されたコンテナ内に配置されています。この結果、サイドバーコンテナは左右に固定され、`plant-holder`はサイドバー内で調整され、植物を縦に並べるスペースを確保します。
このサンプルでは、`plant-holder`は相対配置された要素で、絶対配置されたコンテナ内に配置されています。この結果、サイドバーコンテナは左端とに固定され、`plant-holder`はネストされ、サイドバー内で調整され、植物を縦に並べるスペースを確保します。
> [!NOTE]
> `plant`自体も絶対配置されており、次のレッスンで学ぶようにドラッグ可能にするために必要です。
✅ サイドコンテナと`plant-holder`の配置タイプを切り替えてみてください。何が起こりますか?
✅ サイドコンテナと植物ホルダーの配置タイプを切り替えてみてください。何が起こりますか?
## CSSレイアウト
@ -249,19 +250,19 @@ HTMLマークアップ内の各植物には、IDとクラスの組み合わせ
}
```
ここでのパーセンテージの使用に注目してください。ブラウザを縮小すると、ジャーも縮小する様子がわかります。また、ジャー要素の幅と高さのパーセンテージ、各要素が絶対配置されている方法にも注目してください。これにより、要素がビューの下部に固定され、中央に配置されます。
ここでのパーセンテージの使用に注目してください。ブラウザを縮小すると、ジャーがどのように縮小するかがわかります。また、ジャー要素の幅と高さのパーセンテージ、および各要素が絶対配置されている方法にも注目してください。これにより、ビューポートの下部に固定され、中央に配置されます。
また、`rem`を使用して`border-radius`を設定しています。これはフォント相対の長さです。この種の相対的な測定については、[CSS仕様](https://www.w3.org/TR/css-values-3/#font-relative-lengths)で詳しく読むことができます。
また、`rem`を使用してボーダー半径を指定しています。これはフォント相対の長さです。この種の相対的な測定については、[CSS仕様](https://www.w3.org/TR/css-values-3/#font-relative-lengths)で詳しく読むことができます。
✅ ジャーの色と不透明度を変更してみてください。何が起こりますか?なぜでしょうか?
✅ ジャーの色と不透明度を土の色と比較して変更してみてください。何が起こりますか?なぜでか?
---
## 🚀チャレンジ
ジャーの左下部分に「バブル」のような光沢を追加して、ガラスのように見せてみましょう。`.jar-glossy-long`と`.jar-glossy-short`をスタイリングして、反射した光沢のように見せます。以下のような仕上がりになります:
ジャーの左下部分に「バブル」状の輝きを追加して、ガラスのように見せてみましょう。`.jar-glossy-long`と`.jar-glossy-short`をスタイリングして、反射した輝きのように見せます。完成形は以下のようになります:
![完成したテラリウム](../../../../3-terrarium/2-intro-to-css/images/terrarium-final.png)
![完成したテラリウム](../../../../translated_images/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.ja.png)
講義後のクイズを完了するには、このLearnモジュールを進めてください: [HTMLアプリをCSSでスタイリングする](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
@ -277,5 +278,7 @@ CSSは一見すると簡単そうに見えますが、すべてのブラウザ
[CSSリファクタリング](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された原文が公式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "30f8903a1f290e3d438dc2c70fe60259",
"translation_date": "2025-08-23T22:30:21+00:00",
"original_hash": "61c14b27044861e5e69db35dd52c4403",
"translation_date": "2025-08-28T17:58:08+00:00",
"source_file": "3-terrarium/3-intro-to-DOM-and-closures/README.md",
"language_code": "ja"
}
-->
# テラリウムプロジェクト パート3: DOM操作とクロージャ
![DOMとクロージャ](../../../../sketchnotes/webdev101-js.png)
![DOMとクロージャ](../../../../translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.ja.png)
> スケッチノート: [Tomomi Imura](https://twitter.com/girlie_mac)
## 講義前クイズ
@ -18,36 +18,35 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
DOM"Document Object Model")の操作は、ウェブ開発の重要な側面です。[MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction)によると、「Document Object Model (DOM) は、ウェブ上のドキュメントの構造と内容を構成するオブジェクトのデータ表現です。」DOM操作の課題は、しばしばJavaScriptフレームワークを使用してDOMを管理する理由となっていますが、ここではバニラJavaScriptで対応します!
DOMDocument Object Modelの操作は、ウェブ開発の重要な側面です。[MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction)によると、「Document Object Model (DOM) は、ウェブ上のドキュメントの構造と内容を構成するオブジェクトのデータ表現です。」DOM操作の課題は、しばしばJavaScriptフレームワークを使用してDOMを管理する動機となりますが、ここではバニラJavaScriptを使って自力で管理します!
さらに、このレッスンでは[JavaScriptクロージャ](https://developer.mozilla.org/docs/Web/JavaScript/Closures)の概念を紹介します。クロージャとは、ある関数が別の関数に囲まれており、内側の関数が外側の関数のスコープにアクセスできるようにするものです。
さらに、このレッスンでは[JavaScriptクロージャ](https://developer.mozilla.org/docs/Web/JavaScript/Closures)の概念を紹介します。クロージャとは、ある関数の中に別の関数が閉じ込められており、内側の関数が外側の関数のスコープにアクセスできる仕組みのことです。
> JavaScriptのクロージャは非常に広範で複雑なトピックです。このレッスンでは、基本的なアイデアに触れるだけです。このテラリウムのコード内で、クロージャ(内側の関数と外側の関数が構築され、内側の関数が外側のスコープにアクセスできるようになっているもの)を見つけることができます。詳細については、[詳細なドキュメント](https://developer.mozilla.org/docs/Web/JavaScript/Closures)をご覧ください。
> JavaScriptのクロージャは広範で複雑なトピックです。このレッスンでは、基本的なアイデアに触れるだけです。このテラリウムのコード内で、クロージャ内側の関数と外側の関数が構築され、内側の関数が外側のスコープにアクセスできる仕組み)を見つけることができます。詳細については、[豊富なドキュメント](https://developer.mozilla.org/docs/Web/JavaScript/Closures)をご覧ください。
このレッスンでは、クロージャを使用してDOMを操作します。
このレッスンでは、クロージャを使てDOMを操作します。
DOMを木構造として考えてみてください。これは、ウェブページのドキュメントを操作するためのすべての方法を表しています。さまざまなAPIアプリケーションプログラムインターフェースが作成されており、プログラマーは選択したプログラミング言語を使用してDOMにアクセスし、編集、変更、再配置、その他の管理を行うことができます。
DOMを木構造として考えてみてください。これは、ウェブページのドキュメントを操作するためのすべての方法を表しています。さまざまなAPIアプリケーションプログラムインターフェースが作成されており、プログラマーは選んだプログラミング言語を使ってDOMにアクセスし、編集、変更、再配置、その他の管理を行うことができます。
![DOMツリーの表現](../../../../3-terrarium/3-intro-to-DOM-and-closures/images/dom-tree.png)
![DOMツリーの表現](../../../../translated_images/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.ja.png)
> DOMとそれを参照するHTMLマークアップの表現。[Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)より
このレッスンでは、ページ上の植物を操作できるJavaScriptを作成することで、インタラクティブなテラリウムプロジェクトを完成させます。
このレッスンでは、JavaScriptを作成して、ユーザーがページ上の植物を操作できるようにすることで、インタラクティブなテラリウムプロジェクトを完成させます。
### 前提条件
テラリウムのHTMLとCSSが完成している必要があります。このレッスンの終わりまでに、植物をドラッグしてテラリウムに出し入れできるようになります。
テラリウムのHTMLとCSSを作成済みである必要があります。このレッスンの終わりまでに、植物をドラッグしてテラリウムに出し入れできるようになります。
### タスク
テラリウムフォルダ内に新しいファイル`script.js`を作成します。このファイルを`<head>`セクションでインポートします:
テラリウムフォルダ内に新しいファイル`script.js`を作成します。そのファイルを`<head>`セクションにインポートします:
```html
<script src="./script.js" defer></script>
```
> 注: 外部JavaScriptファイルをHTMLファイルにインポートする際には、`defer`を使用して、HTMLファイルが完全に読み込まれた後にJavaScriptが実行されるようにします。また、`async`属性を使用して、HTMLファイルの解析中にスクリプトを実行することもできますが、今回の場合、ドラッグスクリプトを実行する前にHTML要素が完全に利用可能であることが重要です。
> 注: 外部JavaScriptファイルをHTMLファイルにインポートする際には、`defer`を使用して、HTMLファイルが完全に読み込まれた後にJavaScriptが実行されるようにします。また、`async`属性を使用して、HTMLファイルの解析中にスクリプトを実行することもできますが、今回の場合、ドラッグスクリプトを実行する前にHTML要素が完全に利用可能である必要があります。
---
## DOM要素
@ -73,15 +72,15 @@ dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
```
ここで何が起きているのでしょうかドキュメントを参照し、そのDOMを検索して特定のIdを持つ要素を見つけています。HTMLの最初のレッスンで、各植物画像に個別のId`id="plant1"`)を付けたことを思い出してください。その作業がここで役立ちます。各要素を特定した後、そのアイテムを`dragElement`という関数に渡します。この関数は後で作成します。これにより、HTML内の要素がドラッグ可能になります(または、すぐにドラッグ可能になります)
ここで何が起こっているのでしょうかドキュメントを参照し、そのDOMを調べて特定のIdを持つ要素を見つけています。HTMLの最初のレッスンで、各植物画像に個別のId`id="plant1"`)を付けたことを思い出してください。その作業がここで役立ちます。各要素を特定した後、そを`dragElement`という関数に渡します。この関数は後で作成します。これにより、HTML内の要素がドラッグ可能になります。
✅ なぜ要素をIdで参照するのでしょうかCSSクラスではなくCSSに関する前回のレッスンを参考にして、この質問に答えてみてください。
✅ なぜ要素をIdで参照するのでしょうかCSSクラスで参照するのではなくCSSに関する前回のレッスンを振り返ってみてください。
---
## クロージャ
次に、`dragElement`クロージャを作成します。これは、内側の関数今回の場合は3つを囲む外側の関数です
次に、`dragElement`クロージャを作成します。これは、内側の関数を囲む外側の関数です今回の場合、内側の関数は3つあります
クロージャは、1つ以上の関数が外側の関数のスコープにアクセスする必要がある場合に便利です。以下はその例です
@ -97,7 +96,7 @@ displayCandy();
console.log(candy)
```
この例では、`displayCandy`関数が、既存の配列に新しいキャンディタイプを追加する関数を囲んでいます。このコードを実行すると、`candy`配列は未定義になります。これは、`candy`がローカル変数(クロージャローカル)であるためです。
この例では、`displayCandy`関数が、既存の配列に新しいキャンディタイプを追加する関数を囲んでいます。このコードを実行すると、`candy`配列は未定義になります。これは、`candy`がローカル変数(クロージャ内のローカル)であるためです。
`candy`配列をアクセス可能にするにはどうすればよいでしょうか?配列をクロージャの外側に移動してみてください。これにより、配列はグローバルになり、クロージャのローカルスコープに限定されなくなります。
@ -118,17 +117,17 @@ function dragElement(terrariumElement) {
`dragElement`は、スクリプトの冒頭で宣言された`terrariumElement`オブジェクトを取得します。そして、関数に渡されたオブジェクトのローカル位置を`0`に設定します。これらは、ドラッグ&ドロップ機能を各要素に追加する際に操作されるローカル変数です。テラリウムはこれらのドラッグされた要素によって埋められるため、配置場所を追跡する必要があります。
さらに、この関数に渡された`terrariumElement`は、`pointerdown`イベントを割り当てられます。これは、[ウェブAPI](https://developer.mozilla.org/docs/Web/API)の一部で、DOM管理を支援するために設計されています。`onpointerdown`はボタンが押されたとき、または今回の場合はドラッグ可能な要素がタッチされたときに発火します。このイベントハンドラーは、いくつかの例外を除き、[ウェブおよびモバイルブラウザ](https://caniuse.com/?search=onpointerdown)の両方で動作します。
さらに、この関数に渡された`terrariumElement`は、`pointerdown`イベントを割り当てられます。これは、[ウェブAPI](https://developer.mozilla.org/docs/Web/API)の一部であり、DOM管理を支援するために設計されています。`onpointerdown`はボタンが押されたとき、または今回の場合はドラッグ可能な要素がタッチされたときに発火します。このイベントハンドラは、いくつかの例外を除いて、[ウェブおよびモバイルブラウザ](https://caniuse.com/?search=onpointerdown)の両方で動作します。
✅ [イベントハンドラ`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick)は、クロスブラウザでのサポートがはるかに広範です。なぜここで使用しないのでしょうか?作成しようとしている画面インタラクションの正確なタイプを考えてみてください。
✅ [イベントハンドラ`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick)は、クロスブラウザでのサポートがはるかに多いですが、ここではなぜ使用しないのでしょうか?作成しようとしている画面操作の正確なタイプについて考えてみてください。
---
## Pointerdrag関数
`terrariumElement`はドラッグ可能になりました。`onpointerdown`イベントが発火すると、`pointerDrag`関数が呼び出されます。この関数を次の行の下に追加します:`terrariumElement.onpointerdown = pointerDrag;`
`terrariumElement`はドラッグ可能な状態になりました。`onpointerdown`イベントが発火すると、`pointerDrag`関数が呼び出されます。この関数を次の行の下に追加します:`terrariumElement.onpointerdown = pointerDrag;`
### タスク
### タスク
```javascript
function pointerDrag(e) {
@ -139,28 +138,27 @@ function pointerDrag(e) {
}
```
いくつかのことが起きています。まず、`e.preventDefault();`を使用して、pointerdown時に通常発生するデフォルトイベントを防ぎます。これにより、インターフェースの動作をより細かく制御できます。
いくつかのことが起こります。まず、`e.preventDefault();`を使用して、通常`pointerdown`で発生するデフォルトイベントが発生しないようにします。これにより、インターフェースの動作をより細かく制御できます。
> スクリプトファイルを完全に構築した後、この行を削除してみてください。何が起きるでしょうか?
> スクリプトファイルを完全に構築した後、この行を削除して試してみてください。何が起こるでしょうか?
次に、ブラウザウィンドウで`index.html`を開き、インターフェースを検査します。植物をクリックすると、'e'イベントがどのようにキャプチャされるかがわかります。このイベントを掘り下げて、1回のpointerdownイベントでどれだけの情報が収集されるかを確認してください。
次に、ブラウザウィンドウで`index.html`を開き、インターフェースを検査します。植物をクリックすると、`e`イベントがどのようにキャプチャされるかを見ることができます。このイベントを掘り下げて、1回の`pointerdown`イベントでどれだけの情報が収集されるかを確認してください。
次に、ローカル変数`pos3`と`pos4`が`e.clientX`に設定されていることに注目してください。これらの値は、クリックまたはタッチした瞬間の植物のx座標とy座標をキャプチャします。クリックしてドラッグする際の植物の動作を細かく制御する必要があるため、その座標を追跡します。
次に、ローカル変数`pos3`と`pos4`が`e.clientX`に設定される方法に注目してください。これらの値は、クリックまたはタッチした瞬間の植物のx座標とy座標をキャプチャします。植物をクリックしてドラッグする際の動作を細かく制御する必要があるため、その座標を追跡します。
✅ なぜこのアプリ全体が1つの大きなクロージャで構築されているのか、少しずつ明確になってきましたかもしそうでなければ、14個のドラッグ可能な植物それぞれのスコープをどのように維持するか考えてみてください。
✅ なぜこのアプリ全体が1つの大きなクロージャで構築されているのか、より明確になってきましたかもしそうでなければ、14個のドラッグ可能な植物それぞれのスコープをどのように維持するか考えてみてください。
この初期関数を完成させるために、`pos4 = e.clientY`の下に2つのpointerイベント操作を追加します:
初期関数を完成させるために、`pos4 = e.clientY`の下に2つのポインターイベント操作を追加します:
```html
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
```
これで、ポインタを動かすと植物が一緒にドラッグされ、植物の選択を解除するとドラッグジェスチャが停止するように指定しています。`onpointermove`と`onpointerup`は、`onpointerdown`と同じAPIの一部です。インターフェースは現在エラーをスローしますが、これはまだ`elementDrag`と`stopElementDrag`関数を定義していないためです。次にそれらを構築します。
これで、植物をポインターと一緒にドラッグできるようになり、植物の選択を解除するとドラッグジェスチャーが停止します。`onpointermove`と`onpointerup`は、`onpointerdown`と同じAPIの一部です。インターフェースは現在エラーをスローしますが、これは`elementDrag`と`stopElementDrag`関数がまだ定義されていないためです。次にこれらを構築します。
## elementDragとstopElementDrag関数
クロージャを完成させるために、植物をドラッグしたときとドラッグを停止したときに何が起るかを処理する2つの内部関数を追加します。目指す動作は、いつでもどの植物でもドラッグでき、画面上のどこにでも配置できることです。このインターフェースは非常に自由度が高くドロップゾーンなどはありません、植物を追加、削除、再配置することでテラリウムを自由にデザインできるようにしています。
クロージャを完成させるために、植物をドラッグしたときとドラッグを停止したときに何が起るかを処理する2つの内部関数を追加します。目指す動作は、いつでもどの植物でもドラッグでき、画面上のどこにでも配置できることです。このインターフェースは非常に自由度が高くドロップゾーンなどはありません、植物を追加、削除、再配置することでテラリウムを自由にデザインできます。
### タスク
@ -177,16 +175,15 @@ function elementDrag(e) {
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
}
```
この関数では、冒頭で設定したローカル変数1〜4を大幅に編集します。ここで何が起こっているのでしょうか
この関数では、冒頭で設定したローカル変数14を大幅に編集しています。ここで何が起きているのでしょうか
ドラッグ中に、`pos1`を`pos3`(以前に`e.clientX`として設定)から現在の`e.clientX`値を引いた値に再割り当てします。同様の操作を`pos2`にも行います。その後、`pos3`と`pos4`を要素の新しいX座標とY座標にリセットします。これらの変更をドラッグ中にコンソールで確認できます。その後、植物のCSSスタイルを操作して、新しい位置に基づいて植物の新しい位置を設定します。これには、オフセットとこれらの新しい位置を比較して植物の上部と左側のX座標とY座標を計算します。
ドラッグ中に、`pos1`を`pos3`(以前に`e.clientX`として設定)から現在の`e.clientX`値を引いたものに再割り当てします。同様の操作を`pos2`にも行います。その後、`pos3`と`pos4`を要素の新しいX座標とY座標にリセットします。これらの変更をドラッグ中にコンソールで確認できます。その後、植物のCSSスタイルを操作して、新しい位置に基づいて植物の位置を設定します。これは、`pos1`と`pos2`の新しい位置を比較して植物の上部と左側のX座標とY座標を計算することで行います。
> `offsetTop`と`offsetLeft`は、親要素に基づいて要素の位置を設定するCSSプロパティです。親要素は`static`以外の位置に設定されている必要があります。
> `offsetTop`と`offsetLeft`は、親要素の位置に基づいて要素の位置を設定するCSSプロパティです。親要素は`static`以外の位置指定がされている必要があります。
これらの位置の再計算により、テラリウムとその植物の動作を微調整できます。
これらの位置の再計算により、テラリウムとその植物の動作を細かく調整できます。
### タスク
### タスク
インターフェースを完成させる最後のタスクは、`elementDrag`の閉じ中括弧の後に`stopElementDrag`関数を追加することです:
@ -197,20 +194,19 @@ function stopElementDrag() {
}
```
この小さな関数は、`onpointerup`と`onpointermove`イベントをリセットします。これにより、植物のドラッグを再開したり、新しい植物のドラッグを開始したりできます。
この小さな関数は、`onpointerup`と`onpointermove`イベントをリセットします。これにより、植物の進行を再開するか、新しい植物をドラッグし始めることができます。
✅ これらのイベントをnullに設定しないとどうなるでしょうか
これでプロジェクトが完成しました!
🥇おめでとうございます!美しいテラリウムが完成しました。
![完成したテラリウム](../../../../3-terrarium/3-intro-to-DOM-and-closures/images/terrarium-final.png)
🥇おめでとうございます!美しいテラリウムが完成しました! ![完成したテラリウム](../../../../translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.ja.png)
---
## 🚀チャレンジ
クロージャに新しいイベントハンドラを追加して、植物にさらに何かをさせてみましょう。たとえば、植物をダブルクリックして最前面に移動させるなどです。創造力を発揮してください!
クロージャに新しいイベントハンドラを追加して、植物にさらに何かをさせてみましょう。たとえば、植物をダブルクリックして最前面に持ってくるなどです。創造力を発揮してください!
## 講義後クイズ
@ -218,15 +214,17 @@ function stopElementDrag() {
## 復習と自己学習
画面上の要素をドラッグすることは一見簡単そうに見えますが、目的とする効果によってはさまざまな方法や落とし穴があります。実際、[ドラッグドロップAPI](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API)というものがあり、試してみることができます。このモジュールでは、求める効果が少し異なるため使用しませんでしたが、自分のプロジェクトでこのAPIを試してみてください。
画面上の要素をドラッグするのは一見簡単そうに見えますが、これを実現する方法は多岐にわたり、求める効果によっては多くの落とし穴があります。実際、[ドラッグドロップAPI](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API)というものがあり、試してみることができます。このモジュールでは、求める効果が少し異なるため使用しませんでしたが、自分のプロジェクトでこのAPIを試してみてください。
ポインターイベントに関する詳細は、[W3Cドキュメント](https://www.w3.org/TR/pointerevents1/)や[MDNウェブドキュメント](https://developer.mozilla.org/docs/Web/API/Pointer_events)で確認できます。
常にブラウザの対応状況を[CanIUse.com](https://caniuse.com/)で確認してください。
常に[CanIUse.com](https://caniuse.com/)を使用してブラウザの互換性を確認してください。
## 課題
[DOMを使ったさらなる作業](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。元の言語で記載された文書が公式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e982871b8388c59c22a41b73b5fca70f",
"translation_date": "2025-08-24T00:20:46+00:00",
"original_hash": "1b0aeccb600f83c603cd70cb42df594d",
"translation_date": "2025-08-28T17:59:56+00:00",
"source_file": "4-typing-game/typing-game/README.md",
"language_code": "ja"
}
-->
# イベントを使ったゲーム作成
# イベントを使ったゲーム作成
## 講義前クイズ
@ -15,30 +15,30 @@ CO_OP_TRANSLATOR_METADATA:
## イベント駆動型プログラミング
ブラウザベースのアプリケーションを作成する際、ユーザーが操作するためのグラフィカルユーザーインターフェースGUIを提供します。ブラウザとやり取りする最も一般的な方法は、さまざまな要素をクリックしたり入力したりすることです。しかし、開発者としての課題は、ユーザーがいつこれらの操作を行うのか分からないことです!
ブラウザベースのアプリケーションを作成する際、ユーザーが操作するためのグラフィカルユーザーインターフェースGUIを提供します。ブラウザとの最も一般的なやり取り方法は、さまざまな要素をクリックしたり入力したりすることです。しかし、開発者としての課題は、ユーザーがこれらの操作を「いつ」行うのか分からないことです!
[イベント駆動型プログラミング](https://en.wikipedia.org/wiki/Event-driven_programming)は、GUIを作成するために必要なプログラミングの種類を指します。このフレーズを少し分解すると、核心となる単語は**イベント**です。[イベント](https://www.merriam-webster.com/dictionary/event)は、Merriam-Websterによると「何かが起こること」と定義されています。これは私たちの状況を完璧に説明しています。何かが起こることは分かっていますが、それがいつ起こるのかは分かりません。
[イベント駆動型プログラミング](https://en.wikipedia.org/wiki/Event-driven_programming)は、GUIを作成するために必要なプログラミング手法の名前です。このフレーズを少し分解すると、中心的な単語は**イベント**です。[イベント](https://www.merriam-webster.com/dictionary/event)は、Merriam-Websterによると「何かが起こること」と定義されています。この定義は私たちの状況を完璧に表しています。何かが起こることは分かっていますが、それがいつ起こるのかは分かりません。
コードの特定のセクションを実行したい場合、関数を作成します。[手続き型プログラミング](https://en.wikipedia.org/wiki/Procedural_programming)では、関数は特定の順序で呼び出されます。イベント駆動型プログラミングでも同じことが言えますが、違いは関数が**どのように**呼び出されるかです。
イベント(ボタンのクリックや入力など)を処理するために、**イベントリスナー**を登録します。イベントリスナーは、イベントが発生するのを待ち、それに応じて実行される関数です。イベントリスナーは、UIの更新、サーバーへの呼び出し、またはユーザーのアクションに応じて必要な他の処理を行うことができます。[addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)を使用してイベントリスナーを追加し、実行する関数を提供します。
イベント(ボタンクリック、入力など)を処理するために、**イベントリスナー**を登録します。イベントリスナーは、イベントが発生するのを待ち、それに応じて実行される関数です。イベントリスナーは、UIを更新したり、サーバーにリクエストを送信したり、ユーザーの操作に応じて必要な処理を行ったりします。[addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)を使用してイベントリスナーを追加し、実行する関数を指定します。
> **NOTE:** イベントリスナーを作成する方法は多数あります。無名関数を使用したり、名前付き関数を作成したりできます。また、`click`プロパティを設定したり、`addEventListener`を使用したりするショートカットもあります。この演習では、`addEventListener`と無名関数に焦点を当てます。これはおそらくウェブ開発者が最も一般的に使用する手法であり、最も柔軟性があります。`addEventListener`はすべてのイベントに対応しており、イベント名をパラメータとして提供できます。
> **NOTE:** イベントリスナーを作成する方法は多数あります。無名関数を使用したり、名前付き関数を作成したりできます。また、`click`プロパティを設定したり、`addEventListener`を使用したりするショートカットもあります。この演習では、`addEventListener`と無名関数に焦点を当てます。これはウェブ開発者が最も一般的に使用する手法であり、最も柔軟性があります。`addEventListener`はすべてのイベントに対応しており、イベント名をパラメータとして指定できます。
### 一般的なイベント
### よく使われるイベント
アプリケーションを作成する際にリッスンできる[多数のイベント](https://developer.mozilla.org/docs/Web/Events)があります。基本的に、ユーザーがページ上で行うほぼすべての操作がイベントを発生させます。これにより、ユーザーに望む体験を提供するための大きな力を得ることができます。幸いなことに、通常はほんの一握りのイベントだけを使用すれば十分です。以下は一般的なイベントのいくつかですゲーム作成時に使用する2つを含む
アプリケーションを作成する際にリッスンできる[多数のイベント](https://developer.mozilla.org/docs/Web/Events)があります。基本的に、ユーザーがページ上で行う操作はすべてイベントを発生させます。これにより、ユーザーに望む体験を提供するための大きな力を得ることができます。ただし、通常はほんの一握りのイベントだけを使用することがほとんどです。以下は、一般的なイベントのいくつかですゲーム作成時に使用する2つも含まれます
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): ユーザーが何かをクリックした(通常はボタンやハイパーリンク)
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): ユーザーがボタンやリンクをクリックした
- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): ユーザーが右クリックした
- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): ユーザーがテキストを選択した
- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): ユーザーがテキストを入力した
## ゲームの作成
## ゲームを作成する
JavaScriptのイベントの仕組みを探るためにゲームを作成します。このゲームは、プレイヤーのタイピングスキルをテストします。タイピングスキルは、すべての開発者が持つべき最も過小評価されているスキルの1つです。私たちは皆、タイピングを練習するべきですゲームの全体的な流れは次のようになります:
JavaScriptのイベントの仕組みを学ぶために、ゲームを作成します。このゲームでは、プレイヤーのタイピングスキルをテストします。タイピングスキルは、すべての開発者が持つべき非常に重要なスキルの1つです。私たちは皆、タイピングを練習すべきですゲームの全体的な流れは以下のようになります:
- プレイヤーがスタートボタンをクリックすると、入力するための引用文が表示される
- プレイヤーがスタートボタンをクリックすると、入力する引用文が表示される
- プレイヤーは引用文をできるだけ早くテキストボックスに入力する
- 各単語が完了すると、次の単語がハイライトされる
- プレイヤーがタイプミスをすると、テキストボックスが赤くなる
@ -48,7 +48,7 @@ JavaScriptのイベントの仕組みを探るためにゲームを作成しま
### ファイル構成
合計で3つのファイルが必要です:**index.html**、**script.js**、**style.css**。これらをセットアップして作業を簡単にしましょう。
必要なファイルは合計で3つです**index.html**、**script.js**、**style.css**。これらをセットアップして作業を簡単にしましょう。
- コンソールまたはターミナルウィンドウを開き、以下のコマンドを実行して新しいフォルダを作成します:
@ -66,23 +66,23 @@ md typing-game && cd typing-game
code .
```
- Visual Studio Codeでフォルダに以下の名前の3つのファイルを追加します
- Visual Studio Codeで以下の名前の3つのファイルをフォルダに追加します:
- index.html
- script.js
- style.css
## ユーザーインターフェースの作成
## ユーザーインターフェースを作成する
要件を確認すると、HTMLページにいくつかの要素が必要であることが分かります。これはレシピのようなもので、いくつかの材料が必要です
- ユーザーが入力するための引用文を表示する場所
- ユーザーが入力する引用文を表示する場所
- 成功メッセージなどのメッセージを表示する場所
- 入力用のテキストボックス
- スタートボタン
これらの要素には、JavaScriptで操作するためのIDが必要です。また、作成するCSSファイルとJavaScriptファイルへの参照も追加します。
これらの要素には、それぞれIDを付けてJavaScriptで操作できるようにします。また、作成するCSSファイルとJavaScriptファイルへの参照も追加します。
**index.html**という名前の新しいファイルを作成し、以下のHTMLを追加します
**index.html**という名前の新しいファイルを作成し、以下のHTMLを追加してください
```html
<!-- inside index.html -->
@ -105,26 +105,26 @@ code .
</html>
```
### アプリケーションの起動
### アプリケーションを起動する
開発中は、見た目を確認するために反復的に作業するのが最善です。アプリケーションを起動してみましょう。Visual Studio Codeには、[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon)という素晴らしい拡張機能があります。この拡張機能は、アプリケーションをローカルでホストし、保存するたびにブラウザを更新してくれます。
開発は常に反復的に行い、見た目を確認するのがベストです。アプリケーションを起動してみましょう。Visual Studio Codeには、[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)という素晴らしい拡張機能があります。この拡張機能を使うと、アプリケーションをローカルでホストし、保存するたびにブラウザをリフレッシュしてくれます。
- [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon)をインストールします。リンクをクリックして**Install**を選択してください。
- ブラウザからVisual Studio Codeを開くように求められ、その後Visual Studio Codeからインストールを実行するように求められます。
- [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)をインストールします。リンクをクリックして**Install**を選択してください。
- ブラウザからVisual Studio Codeを開くように求められ、Visual Studio Codeからインストールを実行するように求められます。
- 必要に応じてVisual Studio Codeを再起動してください。
- インストール後、Visual Studio CodeでCtrl-Shift-PまたはCmd-Shift-Pを押してコマンドパレットを開きます。
- **Live Server: Open with Live Server**と入力します。
- Live Serverがアプリケーションをホストします。
- ブラウザを開き、**https://localhost:5500**に移動します。
- ブラウザを開き、**https://localhost:5500**にアクセスします。
- 作成したページが表示されるはずです!
次に、機能を追加していきましょう。
それでは、機能を追加していきましょう。
## CSSの追加
## CSSを追加する
HTMLが作成できたので、コアスタイリングのためのCSSを追加します。プレイヤーが入力すべき単語をハイライトし、入力が間違っている場合にテキストボックスを色付けします。これを2つのクラスで実現します。
HTMLが作成できたので、コアスタイリングのためのCSSを追加します。プレイヤーが入力すべき単語をハイライトし、入力内容が間違っている場合にテキストボックスを色付けします。これを2つのクラスで実現します。
**style.css**という名前の新しいファイルを作成し、以下の構文を追加します
**style.css**という名前の新しいファイルを作成し、以下の構文を追加してください
```css
/* inside style.css */
@ -148,17 +148,17 @@ HTMLが作成できたので、コアスタイリングのためのCSSを追加
UIが作成できたので、次はロジックを提供するJavaScriptに注目します。これをいくつかのステップに分けて進めます
- [定数の作成](../../../../4-typing-game/typing-game)
- [ゲーム開始のイベントリスナー](../../../../4-typing-game/typing-game)
- [タイピングのイベントリスナー](../../../../4-typing-game/typing-game)
- [定数を作成する](../../../../4-typing-game/typing-game)
- [ゲーム開始のイベントリスナーを追加する](../../../../4-typing-game/typing-game)
- [タイピングのイベントリスナーを追加する](../../../../4-typing-game/typing-game)
まず、**script.js**という名前の新しいファイルを作成します
まず、**script.js**という名前の新しいファイルを作成してください
### 定数の追加
### 定数を追加する
プログラミングを簡単にするために、いくつかのアイテムが必要です。これもレシピのようなもので、以下が必要です:
- すべての引用文を含む配列
- すべての引用文のリストを含む配列
- 現在の引用文のすべての単語を格納する空の配列
- プレイヤーが現在入力している単語のインデックスを格納するスペース
- プレイヤーがスタートをクリックした時間
@ -192,21 +192,21 @@ const messageElement = document.getElementById('message');
const typedValueElement = document.getElementById('typed-value');
```
✅ ゲームにもっと引用文を追加してみましょう
✅ ゲームにもっと多くの引用文を追加してみましょう
> **NOTE:** `document.getElementById`を使用して、コード内でいつでも要素を取得できます。これらの要素を定期的に参照するため、文字列リテラルのタイプミスを避けるために定数を使用します。[Vue.js](https://vuejs.org/)や[React](https://reactjs.org/)のようなフレームワークは、コードの集中管理をより効率的に行うのに役立ちます。
> **NOTE:** `document.getElementById`を使用して、コード内でいつでも要素を取得できます。これらの要素を頻繁に参照するため、文字列リテラルによるタイプミスを避けるために定数を使用します。[Vue.js](https://vuejs.org/)や[React](https://reactjs.org/)などのフレームワークを使用すると、コードの集中管理がより簡単になります。
`const`、`let`、`var`の使用方法についてのビデオを見てみましょう。
`const`、`let`、`var`の使い方に関する動画を見てみましょう。
[![変数の種類](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "変数の種類")
> 🎥 上の画像をクリックすると、変数についてのビデオが再生されます。
> 🎥 上の画像をクリックすると、変数に関する動画が再生されます。
### ゲーム開始ロジックの追加
### ゲーム開始ロジックを追加する
ゲームを開始するには、プレイヤーがスタートをクリックします。当然ながら、プレイヤーがいつスタートをクリックするかは分かりません。ここで[イベントリスナー](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)が役立ちます。イベントリスナーは、何かが発生するのを待ち、それに応じてコードを実行します。この場合、ユーザーがスタートをクリックしたときにコードを実行したいです。
ゲームを開始するには、プレイヤーがスタートをクリックします。もちろん、プレイヤーがいつスタートをクリックするかは分かりません。ここで[イベントリスナー](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)が役立ちます。イベントリスナーを使用すると、何かが発生するのを待ち、それに応じてコードを実行できます。この場合、ユーザーがスタートをクリックしたときにコードを実行したいです。
ユーザーが**スタート**をクリックしたとき、引用文を選択し、ユーザーインターフェースを設定し、現在の単語とタイミングの追跡を設定する必要があります。以下は追加する必要のあるJavaScriptです。スクリプトブロックの後に説明します。
ユーザーが**スタート**をクリックすると、引用文を選択し、ユーザーインターフェースをセットアップし、現在の単語とタイミングの追跡をセットアップする必要があります。以下は追加するJavaScriptです。スクリプトブロックの後にコードを説明します。
```javascript
// at the end of script.js
@ -243,25 +243,25 @@ document.getElementById('start').addEventListener('click', () => {
コードを分解してみましょう!
- 単語の追跡を設定
- 単語の追跡をセットアップ
- [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`配列に変換して、プレイヤーが現在入力している単語を追跡します
- `quote`を`words`配列に変換して、プレイヤーが現在入力している単語を追跡できるようにします
- プレイヤーが最初の単語から始めるため、`wordIndex`を0に設定します
- UIを設定
- 各単語を`span`要素内に含む`spanWords`配列を作成します
- UIをセットアップ
- `spanWords`配列を作成し、各単語を`span`要素内に格納します
- これにより、表示される単語をハイライトできます
- 配列を`join`して、`quoteElement`の`innerHTML`を更新するための文字列を作成します
- 配列を`join`して文字列を作成し、`quoteElement`の`innerHTML`を更新します
- これにより、引用文がプレイヤーに表示されます
- 最初の`span`要素の`className`を`highlight`に設定して、黄色でハイライトします
- `messageElement`の`innerText`を`''`に設定してクリアします
- テキストボックスを設定
- テキストボックスをセットアップ
- 現在の`typedValueElement`の`value`をクリアします
- `typedValueElement``focus`を設定します
- タイマーを`getTime`で開始します
- `typedValueElement`フォーカスを設定します
- タイマーを開始するために`getTime`を呼び出します
### タイピングロジックの追加
### タイピングロジックを追加する
プレイヤーが入力すると、`input`イベントが発生します。このイベントリスナーは、プレイヤーが単語を正しく入力しているかを確認し、ゲームの現在の状態を処理します。**script.js**に戻り、以下のコードを末尾に追加します。その後、詳細を説明します。
プレイヤーが入力すると、`input`イベントが発生します。このイベントリスナーは、プレイヤーが単語を正しく入力しているかを確認し、ゲームの現在の状態を処理します。**script.js**に戻り、以下のコードを末尾に追加してください。その後、コードを分解して説明します。
```javascript
// at the end of script.js
@ -300,25 +300,25 @@ typedValueElement.addEventListener('input', () => {
});
```
コードを分解してみましょう!まず、現在の単語とプレイヤーがこれまでに入力した値を取得します。その後、ウォーターフォールロジックを使用して、引用文が完了したか、単語が完了したか、単語が正しいか、またはエラーがあるかを確認します。
コードを分解してみましょう!まず、現在の単語とプレイヤーがこれまでに入力した値を取得します。その後、ウォーターフォールロジックを使用して、引用文が完了しているか、単語が完了しているか、単語が正しいか、またはエラーがあるかを確認します。
- 引用文が完了した場合(`typedValue`が`currentWord`と等しく、`wordIndex`が`words`の`length`より1少ない場合)
- 引用文が完了している場合(`typedValue`が`currentWord`と等しく、`wordIndex`が`words`の`length`の1つ前と等しい場合)
- 現在の時間から`startTime`を引いて`elapsedTime`を計算します
- `elapsedTime`を1,000で割ってミリ秒秒に変換します
- `elapsedTime`を1,000で割ってミリ秒から秒に変換します
- 成功メッセージを表示します
- 単語が完了し場合(`typedValue`がスペースで終わり、`typedValue`が`currentWord`と等しい場合)
- 次の単語を入力できるように`typedElement`の`value`を`''`に設定します
- `wordIndex`をインクリメントして次の単語に移動します
- 単語が完了している場合(`typedValue`がスペースで終わり、`typedValue`が`currentWord`と等しい場合)
- 次の単語を入力できるようにするために、`typedElement`の`value`を`''`に設定します
- 次の単語に移動するために`wordIndex`をインクリメントします
- `quoteElement`のすべての`childNodes`をループして`className`を`''`に設定し、デフォルト表示に戻します
- 現在の単語の`className`を`highlight`に設定して、次に入力すべき単語としてフラグを立てます
- 現在の単語が正しく入力されている場合(ただし完了していない場合)、`currentWord`が`typedValue`で始まる
- 現在の単語の`className`を`highlight`に設定して、次に入力す単語としてフラグを立てます
- 現在の単語が正しく入力されている場合(ただし完了していない場合)、`currentWord`が`typedValue`で始まる場合
- `typedValueElement`をデフォルト表示にするために`className`をクリアします
- ここまで到達した場合、エラーがあ
- ここまで到達した場合、エラーがあります
- `typedValueElement`の`className`を`error`に設定します
## アプリケーションのテスト
## アプリケーションをテストする
こまで来ました!最後のステップは、アプリケーションが動作することを確認することです。試してみてください!エラーがあっても心配しないでください。**すべての開発者**がエラーを経験します。メッセージを確認し、必要に応じてデバッグしてください。
れで完成です!最後のステップは、アプリケーションが動作することを確認することです。試してみてください!エラーがあっても心配しないでください。**すべての開発者**がエラーを経験します。メッセージを確認し、必要に応じてデバッグしてください。
**スタート**をクリックして、タイピングを始めてみましょう!以下のアニメーションのように動作するはずです。
@ -328,24 +328,25 @@ typedValueElement.addEventListener('input', () => {
## 🚀 チャレンジ
さらに機能を追加してみましょう
さらに機能を追加してみましょう
- 完了時に`input`イベントリスナーを無効化し、ボタンがクリックされたときに再有効化する
- 完了時に`input`イベントリスナーを無効化し、ボタンがクリックされたときに再有効化する
- プレイヤーが引用文を完了したときにテキストボックスを無効化する
- 成功メッセージを表示するモーダルダイアログボックスを追加する
- [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) を使用してハイスコアを保存する
- 成功メッセージをモーダルダイアログボックスで表示する
- [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)を使用してハイスコアを保存する
## 講義後のクイズ
[講義後のクイズ](https://ff-quizzes.netlify.app/web/quiz/22)
## 復習と自己学習
ウェブブラウザを通じて開発者が利用できる[すべてのイベント](https://developer.mozilla.org/docs/Web/Events)について調べ、それぞれのイベントをどのようなシナリオで使用するかを考えてみてください。
ウェブブラウザを通じて開発者が利用できる[すべてのイベント](https://developer.mozilla.org/docs/Web/Events)について調べ、それぞれのイベントを使用するシナリオを考えてみてください。
## 課題
[新しいキーボードゲームを作成する](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な表現が含まれる可能性があります。元の言語で記載された原文が公式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解について、当社は責任を負いません。

@ -1,111 +1,111 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "0bb55e0b98600afab801eea115228873",
"translation_date": "2025-08-23T23:43:50+00:00",
"original_hash": "2326d04e194a10aa760b51f5e5a1f61d",
"translation_date": "2025-08-28T17:48:51+00:00",
"source_file": "5-browser-extension/1-about-browsers/README.md",
"language_code": "ja"
}
-->
# ブラウザ拡張プロジェクト パート1: ブラウザについて
![ブラウザのスケッチノート](../../../../sketchnotes/browser.jpg)
![ブラウザのスケッチノート](../../../../translated_images/browser.60317c9be8b7f84adce43e30bff8d47a1ae15793beab762317b2bc6b74337c1a.ja.jpg)
> スケッチノート: [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob)
## 講義前クイズ
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/23)
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/23)
### はじめに
ブラウザ拡張機能は、ブラウザに追加の機能を提供します。しかし、拡張機能を作成する前に、ブラウザがどのように動作するかを少し学ぶ必要があります。
ブラウザ拡張機能は、ブラウザに追加の機能を提供します。しかし、拡張機能を作成する前に、まずブラウザがどのように動作するかを少し学ぶ必要があります。
### ブラウザについて
このレッスンシリーズでは、Chrome、Firefox、Edgeブラウザで動作するブラウザ拡張機能の作成方法を学びます。このパートでは、ブラウザの仕組みを理解し、ブラウザ拡張機能の要素を構築していきます。
このレッスンシリーズでは、Chrome、Firefox、Edgeブラウザで動作するブラウザ拡張機能の作成方法を学びます。このパートでは、ブラウザがどのように動作するかを理解し、ブラウザ拡張機能の要素を構築していきます。
では、ブラウザとは何でしょうか?ブラウザは、エンドユーザーがサーバーからコンテンツを取得し、それをウェブページ上に表示するためのソフトウェアアプリケーションです。
そもそもブラウザとは何でしょうか? ブラウザは、エンドユーザーがサーバーからコンテンツを取得し、それをウェブページとして表示するためのソフトウェアアプリケーションです。
✅ 少し歴史を振り返ると、最初のブラウザは「WorldWideWeb」と呼ばれ、1990年にティモシー・バーナーズ=リー卿によって作られました。
✅ 少し歴史を振り返ると、最初のブラウザは「WorldWideWeb」と呼ばれ、1990年にティ・バーナーズ=リー卿によって作られました。
![初期のブラウザ](../../../../5-browser-extension/1-about-browsers/images/earlybrowsers.jpg)
> 初期のブラウザの一部: [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
![初期のブラウザ](../../../../translated_images/earlybrowsers.d984b711cdf3a42ddac919d46c4b5ca7232f68ccfbd81395e04e5a64c0015277.ja.jpg)
> 初期のブラウザのいくつか, via [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
ユーザーがURLUniform Resource Locatorアドレスを使用してインターネットに接続するとき、通常は`http`または`https`アドレスを介してHypertext Transfer Protocolを使用します。ブラウザはウェブサーバーと通信し、ウェブページを取得します。
ユーザーがURLUniform Resource Locatorアドレスを使用してインターネットに接続するとき、通常は`http`または`https`アドレスを介してハイパーテキスト転送プロトコルを使用します。このとき、ブラウザはウェブサーバーと通信し、ウェブページを取得します。
この時点で、ブラウザのレンダリングエンジンがウェブページをユーザーのデバイス(スマートフォン、デスクトップ、またはノートパソコンなど)に表示します。
その後、ブラウザのレンダリングエンジンがそれをユーザーのデバイス(スマートフォン、デスクトップ、またはノートパソコンなど)に表示します。
ブラウザは、コンテンツをキャッシュして毎回サーバーから取得する必要がないようにしたり、ユーザーの閲覧履歴を記録したり、「クッキー」と呼ばれる小さなデータを保存してユーザーの活動情報を保持したりすることできます。
ブラウザは、コンテンツをキャッシュして毎回サーバーから取得する必要がないようにする機能もあります。また、ユーザーの閲覧履歴を記録したり、「クッキー」と呼ばれる小さなデータを保存してユーザーの活動情報を保持したりすることできます。
ブラウザについて重要な点は、すべてのブラウザが同じではないということです!各ブラウザにはそれぞれの強みと弱みがあり、プロのウェブ開発者はウェブページをクロスブラウザでうまく動作させる方法を理解する必要があります。これには、スマートフォンのような小さなビューポートや、オフラインのユーザーへの対応が含まれます。
重要な点として、すべてのブラウザが同じではありません! 各ブラウザには長所と短所があり、プロのウェブ開発者はウェブページをクロスブラウザでうまく動作させる方法を理解する必要があります。これには、スマートフォンのような小さなビューポートや、オフライン状態のユーザーへの対応も含まれます。
ウェブページを作成する際に非常に役立つウェブサイトとして、[caniuse.com](https://www.caniuse.com)があります。このサイトでは、サポートされている技術のリストを確認でき、ユーザーを最適にサポートするために役立ちます。
非常に便利なウェブサイトとして、[caniuse.com](https://www.caniuse.com)があります。ウェブページを作成する際には、caniuseのサポートされている技術のリストを使用することで、ユーザーを最適にサポートすることができます。
✅ あなたのウェブサイトのユーザー層で最も人気のあるブラウザをどうやって知ることができますか?分析ツールをインストールすることで、ウェブ開発プロセスの一環として、どのブラウザが最も使用されているかを確認できます。
✅ あなたのウェブサイトのユーザーがどのブラウザを最も使用しているかを知るにはどうすればよいでしょうか? 分析ツールを確認してください。ウェブ開発プロセスの一環としてさまざまな分析ツールをインストールすることで、どのブラウザが最も使用されているかを知ることができます。
## ブラウザ拡張機能
なぜブラウザ拡張機能を作成したいのでしょうか?繰り返し行うタスクにすばやくアクセスするためにブラウザに追加する便利なツールだからです。例えば、さまざまなウェブページで色を確認する必要がある場合、カラーピッカーのブラウザ拡張機能をインストールするかもしれません。パスワードを覚えるのが苦手な場合は、パスワード管理のブラウザ拡張機能を使用するかもしれません。
なぜブラウザ拡張機能を作成したいのでしょうか? 繰り返し行うタスクにすばやくアクセスする必要がある場合に便利だからです。たとえば、さまざまなウェブページで色を確認する必要がある場合、カラーピッカーのブラウザ拡張機能をインストールするかもしれません。パスワードを覚えるのが苦手な場合は、パスワード管理のブラウザ拡張機能を使用するかもしれません。
ブラウザ拡張機能の開発は楽しいものです。通常、限られた数のタスクを効率的に管理することに特化しています。
ブラウザ拡張機能の開発は楽しいものです。通常、特定のタスクを効率的に管理するために設計されています。
✅ あなたのお気に入りのブラウザ拡張機能は何ですか?それらはどのようなタスクを実行しますか?
✅ あなたのお気に入りのブラウザ拡張機能は何ですか? それらはどのようなタスクを実行しますか?
### 拡張機能のインストール
作成を始める前に、ブラウザ拡張機能の構築と展開のプロセスを確認してください。各ブラウザによってこのタスクの管理方法は少し異なりますが、ChromeやFirefoxと同様に、Edgeでの例は以下のようになります
作成を始める前に、ブラウザ拡張機能の構築とデプロイのプロセスを見てみましょう。各ブラウザでこのタスクの管理方法は少し異なりますが、ChromeやFirefoxでのプロセスは、Edgeでの以下の例と似ています。
![Edgeブラウザのスクリーンショット。edge://extensionsページと設定メニューが開いている。](../../../../5-browser-extension/1-about-browsers/images/install-on-edge.png)
![Edgeブラウザのスクリーンショット。edge://extensionsページと設定メニューが開いている。](../../../../translated_images/install-on-edge.d68781acaf0b3d3dada8b7507cde7a64bf74b7040d9818baaa9070668e819f90.ja.png)
> 注: 開発者モードをオンにし、他のストアからの拡張機能を許可してください。
> 注: 開発者モードをオンにし、他のストアからの拡張機能を許可することを忘れないでください。
基本的なプロセスは以下のようになります:
基本的なプロセスは以下の通りです:
- `npm run build`を使用して拡張機能をビルドする
- ブラウザで「設定とその他」ボタン(右上の`...`アイコン)を使用して拡張機能のペインに移動する
- 新しいインストールの場合、`load unpacked`を選択してビルドフォルダ(この場合は`/dist`)から新しい拡張機能をアップロードする
- または、すでにインストールされている拡張機能を再ロードする場合は`reload`をクリックする
- ブラウザで右上の「設定とその他」ボタン(`...`アイコン)を使用して拡張機能のペインに移動する
- 新しいインストールの場合、`load unpacked`を選択してビルドフォルダ(この場合は`/dist`)から新しい拡張機能をアップロードする
- 既にインストールされている場合は、`reload`をクリックして拡張機能を再読み込みする
✅ これらの手順は自分で作成した拡張機能に関するものです。各ブラウザに関連するブラウザ拡張機能ストアでリリースされた拡張機能をインストールするには、それらの[ストア](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home)に移動して、好きな拡張機能をインストールしてください。
✅ これらの手順は、自分で作成した拡張機能に適用されます。各ブラウザに関連付けられたブラウザ拡張機能ストアでリリースされた拡張機能をインストールするには、それらの[ストア](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home)に移動して、好きな拡張機能をインストールしてください。
### 始めましょう
あなたは、地域の炭素排出量を表示するブラウザ拡張機能を作成します。この拡張機能は、地域のエネルギー使用量とエネルギーの供給源を表示します。拡張機能には、APIキーを収集するフォームがあり、CO2 SignalのAPIにアクセスできます。
あなたは、自分の地域のカーボンフットプリントを表示するブラウザ拡張機能を作成します。この拡張機能は、地域のエネルギー使用量とエネルギーの供給源を表示します。また、CO2 SignalのAPIにアクセスするためのAPIキーを収集するフォームを備えています。
**必要なもの:**
- [APIキー](https://www.co2signal.com/) - このページのボックスにメールアドレスを入力すると、APIキーが送信されます
- [地域コード](http://api.electricitymap.org/v3/zones) - [Electricity Map](https://www.electricitymap.org/map)に対応するコード(例えば、ボストンでは「US-NEISO」を使用します
- [地域コード](http://api.electricitymap.org/v3/zones) - [Electricity Map](https://www.electricitymap.org/map)に対応するコード(例: ボストンでは「US-NEISO」を使用
- [スターターコード](../../../../5-browser-extension/start) - `start`フォルダをダウンロードし、このフォルダ内のコードを完成させます
- [NPM](https://www.npmjs.com) - NPMはパッケージ管理ツールです。ローカルにインストールすると、`package.json`ファイルに記載されているパッケージがウェブアセットで使用できるようになります
- [NPM](https://www.npmjs.com) - NPMはパッケージ管理ツールです。ローカルにインストールすると、`package.json`ファイルに記載されたパッケージがウェブアセットで使用できるようにインストールされます
✅ パッケージ管理についてもっと学びたい場合は、この[優れた学習モジュール](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)を参照してください。
コードベースを確認してみましょう:
コードベースをざっと見てみましょう:
dist
-|manifest.json (デフォルト設定はこちら)
-|index.html (フロントエンドのHTMLマークアップはこちら)
-|background.js (バックグラウンドJSはこちら)
-|main.js (ビルド済みJS)
-|manifest.json (デフォルト設定)
-|index.html (フロントエンドのHTMLマークアップ)
-|background.js (バックグラウンドJS)
-|main.js (ビルドされたJS)
src
-|index.js (あなたのJSコードはこちら)
-|index.js (ここにJSコードを記述)
✅ APIキーと地域コードを準備したら、それらをメモに保存しておきましょう。
✅ APIキーと地域コードを手元に用意したら、それらをメモに保存しておきましょう。
### 拡張機能のHTMLを作成する
この拡張機能には2つのビューがあります。1つはAPIキーと地域コードを収集するためのもの
![完成した拡張機能のスクリーンショット。フォームに地域名とAPIキーの入力欄が表示されている。](../../../../5-browser-extension/1-about-browsers/images/1.png)
![完成した拡張機能のスクリーンショット。フォームに地域名とAPIキーの入力欄が表示されている。](../../../../translated_images/1.b6da8c1394b07491afeb6b2a8e5aca73ebd3cf478e27bcc9aeabb187e722648e.ja.png)
もう1つは地域の炭素使用量を表示するためのもの
もう1つは地域のカーボン使用量を表示するためのものです
![完成した拡張機能のスクリーンショット。US-NEISO地域の炭素使用量と化石燃料の割合が表示されている。](../../../../5-browser-extension/1-about-browsers/images/2.png)
![完成した拡張機能のスクリーンショット。US-NEISO地域のカーボン使用量と化石燃料の割合が表示されている。](../../../../translated_images/2.1dae52ff0804224692cd648afbf2342955d7afe3b0101b617268130dfb427f55.ja.png)
まず、フォームを作成し、CSSでスタイリングします。
`/dist`フォルダ内で、フォームと結果表示エリアを作成します。`index.html`ファイル内で、指定されたフォームエリアを埋めます:
`/dist`フォルダ内で、フォームと結果表示エリアを作成します。`index.html`ファイル内で、フォームエリアを以下のように記述します:
```HTML
<form class="form-data" autocomplete="on">
@ -123,7 +123,7 @@ src
<button class="search-btn">Submit</button>
</form>
```
れは保存された情報が入力され、ローカルストレージに保存されるフォームです。
のフォームは、保存された情報を入力し、ローカルストレージに保存するためのものです。
次に、結果表示エリアを作成します。最後のフォームタグの下にいくつかのdivを追加します
@ -146,29 +146,29 @@ src
npm install
```
このコマンドはnpmNode Package Managerを使用して、拡張機能のビルドプロセスに必要なwebpackをインストールします。ビルドプロセスの出力は`/dist/main.js`で確認できます。コードがバンドルされていることがわかります
このコマンドは、Node Package Managernpmを使用して、拡張機能のビルドプロセスに必要なwebpackをインストールします。このプロセスの出力は、`/dist/main.js`で確認できます。コードがバンドルされているのがわかるでしょう
現時点では、拡張機能をビルドし、Edgeに拡張機能として展開すると、フォームがきれいに表示されるはずです。
現時点では、拡張機能をビルドし、Edgeに拡張機能としてデプロイすれば、フォームがきれいに表示されるはずです。
おめでとうございます!ブラウザ拡張機能の作成に向けた最初のステップを踏み出しました。次のレッスンでは、さらに機能的で便利なものにしていきます。
おめでとうございます! ブラウザ拡張機能の作成に向けた最初のステップを踏み出しました。次のレッスンでは、これをさらに機能的で便利なものにしていきます。
---
## 🚀 チャレンジ
ブラウザ拡張機能ストアを見て、1つをブラウザにインストールしてみましょう。そのファイルを興味深い方法で調べることができます。何を発見しましたか?
ブラウザ拡張機能ストアを見て、1つインストールしてみましょう。そのファイルを調べてみると、興味深い発見があるかもしれません。何を見つけましたか?
## 講義後クイズ
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/24)
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/24)
## 復習と自己学習
このレッスンでは、ウェブブラウザの歴史について少し学びました。この機会に、ワールドワイドウェブの発明者がその使用方法をどのように考えていたかについて、さらに学んでみましょう。役立つサイトには以下があります:
このレッスンでは、ウェブブラウザの歴史について少し学びました。この機会に、ワールドワイドウェブの発明者たちがその利用をどのように想定していたかについて、さらに学んでみましょう。役立つサイトには以下があります:
[ウェブブラウザの歴史](https://www.mozilla.org/firefox/browsers/browser-history/)
[The History of Web Browsers](https://www.mozilla.org/firefox/browsers/browser-history/)
[ウェブの歴史](https://webfoundation.org/about/vision/history-of-the-web/)
[History of the Web](https://webfoundation.org/about/vision/history-of-the-web/)
[ティム・バーナーズ=リーとのインタビュー](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want)
@ -176,5 +176,7 @@ npm install
[拡張機能をリスタイルする](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は責任を負いません。

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e10f168beac4e7b05e30e0eb5c92bf11",
"translation_date": "2025-08-23T23:39:48+00:00",
"original_hash": "a7587943d38d095de8613e1b508609f5",
"translation_date": "2025-08-28T17:51:13+00:00",
"source_file": "5-browser-extension/2-forms-browsers-local-storage/README.md",
"language_code": "ja"
}
-->
# ブラウザ拡張プロジェクト パート2: APIの呼び出しとローカルストレージの
# ブラウザ拡張プロジェクト パート2: APIの呼び出しとローカルストレージの使
## 講義前クイズ
@ -15,15 +15,15 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
このレッスンでは、ブラウザ拡張のフォームを使ってAPIを呼び出し、その結果を拡張内に表示する方法を学びます。また、ブラウザのローカルストレージにデータを保存し、後で参照・用する方法についても学びます。
このレッスンでは、ブラウザ拡張のフォームを送信してAPIを呼び出し、その結果をブラウザ拡張内に表示する方法を学びます。また、ブラウザのローカルストレージにデータを保存し、後で参照・使用する方法についても学びます。
✅ 適切なファイル内の番号付きセグメントに従ってコードを配置してください。
### 拡張で操作する要素を設定する
### 拡張機能で操作する要素を設定する
ここまでで、ブラウザ拡張のフォームと結果を表示する`<div>`のHTMLを作成しました。これ以降は、`/src/index.js`ファイルで作業を進め、拡張を少しずつ構築していきます。プロジェクトのセットアップやビルドプロセスについては[前回のレッスン](../1-about-browsers/README.md)を参照してください。
ここまでで、ブラウザ拡張のフォームと結果を表示する`<div>`のHTMLを作成しました。これ以降は、`/src/index.js`ファイルで作業を進め、拡張機能を少しずつ構築していきます。プロジェクトのセットアップやビルドプロセスについては[前回のレッスン](../1-about-browsers/README.md)を参照してください。
`index.js`ファイルで作業を開始し、まず各フィールドに関連付けられた値を保持するための`const`変数を作成します。
`index.js`ファイルで作業を開始し、まず各フィールドに関連付けられた値を保持するための`const`変数を作成します。
```JavaScript
// form fields
@ -45,7 +45,7 @@ const clearBtn = document.querySelector('.clear-btn');
### リスナーを追加する
次に、フォームとリセットボタンにイベントリスナーを追加します。これにより、ユーザーがフォームを送信したりリセットボタンをクリックしたりすると何かが起こります。また、ファイルの末尾にアプリを初期化する呼び出しを追加します。
次に、フォームとリセットボタンにイベントリスナーを追加します。これにより、ユーザーがフォームを送信したりリセットボタンをクリックしたりすると何かが起こります。また、ファイルの末尾にアプリを初期化する呼び出しを追加します。
```JavaScript
form.addEventListener('submit', (e) => handleSubmit(e));
@ -53,11 +53,11 @@ clearBtn.addEventListener('click', (e) => reset(e));
init();
```
✅ フォーム送信やクリックイベントをリスニングする際の省略形に注目してください。このイベントは`handleSubmit`や`reset`関数に渡されます。この省略形を長い形式で書き換えることはできますか?どちらの形式が好みですか?
✅ フォーム送信やクリックイベントをリスニングするための簡略化された記述方法に注目してください。このイベントがhandleSubmitやreset関数に渡される仕組みを確認できます。この簡略化された記述を長い形式で書き換えることはできますか?どちらの形式が好みですか?
### `init()`関数と`reset()`関数を構築する
### init()関数とreset()関数を構築する
次に、拡張を初期化する関数`init()`を構築します。
次に、拡張機能を初期化する関数であるinit()を構築します。
```JavaScript
function init() {
@ -95,32 +95,32 @@ function reset(e) {
この関数には興味深いロジックがあります。内容を読み解いてみてください。
- ユーザーがローカルストレージにAPIキーと地域コードを保存しているかどうかを確認するための2つの`const`が設定されます。
- どちらかが`null`の場合、フォームのスタイルを変更して表示します(`display: 'block'`
- 結果、ローディング、`clearBtn`を非表示にし、エラーテキストを空文字列に設定します。
- 2つの`const`が設定され、ユーザーがローカルストレージにAPIKeyと地域コードを保存しているかどうかを確認します。
- どちらかがnullの場合、フォームのスタイルを変更して表示を'block'にします
- 結果、ローディング、clearBtnを非表示にし、エラーテキストを空文字列に設定します。
- キーと地域が存在する場合、以下のルーチンを開始します:
- APIを呼び出して炭素使用量データを取得する
- 結果エリアを非表示にする
- フォームを非表示にする
- リセットボタンを表示する
- APIを呼び出して炭素使用量データを取得
- 結果エリアを非表示
- フォームを非表示
- リセットボタンを表示
次に進む前に、ブラウザで利用可能な非常に重要な概念について学ぶが役立ちます:[LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)。LocalStorageは、ブラウザ内で文字列を`key-value`ペアとして保存する便利な方法です。このタイプのウェブストレージは、JavaScriptを使用してブラウザ内のデータを管理するために操作できます。LocalStorageは期限切れになりませんが、もう一つのウェブストレージであるSessionStorageは、ブラウザを閉じるとクリアされます。これらのストレージの種類には、それぞれ利点と欠点があります。
次に進む前に、ブラウザで利用可能な非常に重要な概念について学ぶことが役立ちます:[LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)。LocalStorageは、ブラウザ内で文字列を`key-value`ペアとして保存する便利な方法です。このタイプのウェブストレージは、JavaScriptを使用してブラウザ内のデータを管理するために操作できます。LocalStorageは期限切れになりませんが、もう一つの種類であるSessionStorageはブラウザを閉じるとクリアされます。これらのストレージの種類には、それぞれ利点と欠点があります。
> 注意 - ブラウザ拡張には独自のローカルストレージがあります。メインブラウザウィンドウは別のインスタンスであり、別々に動作します。
APIキーを文字列値として設定すると、Edgeで「ウェブページを検査」ブラウザを右クリックして検査し、ストレージを確認することで設定されていることがわかります。
APIKeyを文字列値として設定すると、Edgeで「ウェブページを検査」することで確認できますブラウザを右クリックして検査を選択。その後、アプリケーションタブに移動してストレージを確認します。
![ローカルストレージペイン](../../../../5-browser-extension/2-forms-browsers-local-storage/images/localstorage.png)
![ローカルストレージペイン](../../../../translated_images/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.ja.png)
✅ LocalStorageにデータを保存したくない状況について考えてみてください。一般的に、APIキーをLocalStorageに保存するのは良くないアイデアですその理由がわかりますか今回の場合、アプリは学習目的のみ使用され、アプリストアに公開されることはないため、この方法を使用します。
✅ LocalStorageにデータを保存しない方が良い状況について考えてみてください。一般的に、APIキーをLocalStorageに保存するのは良くないアイデアですその理由がわかりますか今回の場合、アプリは学習目的のみ使用され、アプリストアに公開されることはないため、この方法を使用します。
LocalStorageを操作するには、Web APIを使用して`getItem()`、`setItem()`、または`removeItem()`を使用します。これらはほとんどのブラウザで広くサポートされています。
Web APIを使用してLocalStorageを操作するには、`getItem()`、`setItem()`、または`removeItem()`を使用します。これらはほとんどのブラウザで広くサポートされています。
`displayCarbonUsage()`関数を構築する前に、初期フォーム送信を処理する機能を構築しましょう。
### フォーム送信を処理する
イベント引数`(e)`を受け取る`handleSubmit`関数を作成します。このイベントが伝播するのを止め(この場合、ブラウザのリフレッシュを止めたい)、新しい関数`setUpUser`を呼び出し、`apiKey.value`と`region.value`の引数を渡します。この方法で、適切なフィールドが入力された際に初期フォームから取得された2つの値を使用します。
イベント引数`(e)`を受け取る`handleSubmit`という関数を作成します。このイベントが伝播するのを止め(この場合、ブラウザのリフレッシュを止めたい)、新しい関数`setUpUser`を呼び出し、`apiKey.value`と`region.value`の引数を渡します。この方法で、適切なフィールドが入力された際に初期フォームから取得された2つの値を使用します。
```JavaScript
function handleSubmit(e) {
@ -129,11 +129,11 @@ function handleSubmit(e) {
}
```
✅ 復習 - 前回のレッスンで設定したHTMLには、`value`がキャプチャされる2つの入力フィールドがあり、これらはファイルの冒頭で設定した`const`によって取得されます。また、両方とも`required`属性が設定されているため、ブラウザはユーザーが`null`値を入力するのを防ぎます。
✅ 復習 - 前回のレッスンで設定したHTMLには、`value`がキャプチャされる2つの入力フィールドがあり、これらはファイルの冒頭で設定した`const`によって取得されます。また、両方とも`required`属性が設定されているため、ブラウザはユーザーがnull値を入力するのを防ぎます。
### ユーザーを設定する
次に進み、`setUpUser`関数を作成します。ここでは、APIキーと地域名のローカルストレージ値を設定します。新しい関数を追加します
次に進み、`setUpUser`関数を構築します。ここでは、apiKeyとregionNameのローカルストレージ値を設定します。新しい関数を追加します。
```JavaScript
function setUpUser(apiKey, regionName) {
@ -151,19 +151,19 @@ function setUpUser(apiKey, regionName) {
### 炭素使用量を表示する
いよいよAPIをクエリする時です
いよいよAPIをクエリする時が来ました
進む前に、APIについて話しましょう。API、つまり[アプリケーションプログラミングインターフェース](https://www.webopedia.com/TERM/A/API.html)は、ウェブ開発者のツールボックスにおける重要な要素です。APIは、プログラム同士が標準的な方法で相互作用し、インターフェースを提供する手段を提供します。例えば、データベースをクエリする必要があるウェブサイトを構築している場合、誰かが使用可能なAPIを作成しているかもしれません。APIには多くの種類がありますが、最も人気のあるものの一つが[REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/)です。
進む前に、APIについて話しましょう。API、つまり[アプリケーションプログラミングインターフェース](https://www.webopedia.com/TERM/A/API.html)は、ウェブ開発者のツールボックスにおける重要な要素です。APIは、プログラム同士が標準的な方法で相互作用し、インターフェースを提供する仕組みを提供します。例えば、データベースをクエリする必要があるウェブサイトを構築している場合、誰かが使用するためのAPIを作成しているかもしれません。APIには多くの種類がありますが、その中でも人気があるのが[REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/)です。
✅ 'REST'は'Representational State Transfer'の略で、さまざまに構成されたURLを使用してデータを取得する特徴があります。開発者が利用可能なさまざまな種類のAPIについて少し調べてみてください。どの形式が魅力的に感じますか?
✅ 'REST'という用語は'Representational State Transfer'を意味し、さまざまに構成されたURLを使用してデータを取得する特徴があります。開発者が利用可能なAPIのさまざまな種類について少し調べてみてください。どの形式が魅力的に感じますか?
この関数について重要な点があります。まず、[`async`キーワード](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)に注目してください。関数を非同期的に動作させることで、データが返されるなどのアクションが完了するまで待機してから処理を続行します。
この関数について重要な点をいくつか挙げます。まず、[`async`キーワード](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)に注目してください。関数を非同期的に動作させることで、データが返されるなどのアクションが完了するまで待機してから処理を続行します。
こちらは`async`についての簡単な動画です:
`async`についての簡単な動画はこちらです:
[![非同期処理とAwaitによるPromise管理](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "非同期処理とAwaitによるPromise管理")
> 🎥 上の画像をクリックすると、`async/await`に関する動画が再生されます。
> 🎥 上の画像をクリックすると、async/awaitに関する動画が再生されます。
C02Signal APIをクエリする新しい関数を作成します
@ -207,14 +207,14 @@ async function displayCarbonUsage(apiKey, region) {
この関数は大きなものです。何が行われているのでしょうか?
- ベストプラクティスに従い、`async`キーワードを使用してこの関数を非同期的に動作させます。この関数には`try/catch`ブロックが含まれており、APIがデータを返すとPromiseを返します。APIの応答速度を制御することはできないため応答しない可能性もあります!)、非同期的に呼び出すことでこの不確実性を処理します。
- ベストプラクティスに従い、`async`キーワードを使用してこの関数を非同期的に動作させます。この関数には`try/catch`ブロックが含まれており、APIがデータを返すとPromiseを返します。APIの応答速度を制御することはできないため応答しない場合もあります)、非同期的に呼び出すことでこの不確実性を処理します。
- co2signal APIをクエリして地域のデータを取得し、APIキーを使用します。このキーを使用するには、ヘッダーのパラメータで認証を行う必要があります。
- APIが応答すると、その応答データのさまざまな要素を画面の設定された部分に割り当てます。
- APIが応答すると、その応答データのさまざまな要素を画面の対応する部分に割り当てます。
- エラーが発生した場合や結果がない場合は、エラーメッセージを表示します。
✅ 非同期プログラミングパターンを使用することは、ツールボックスにおける非常に有用なツールの一つです。[さまざまな構成方法](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)について読んでみてください。
おめでとうございます!拡張をビルド(`npm run build`)し、拡張ペインでリフレッシュすると、動作する拡張が完成します!唯一動作していないのはアイコンで、次のレッスンで修正します。
おめでとうございます!拡張機能をビルド(`npm run build`)して拡張機能ペインでリフレッシュすると、動作する拡張機能が完成します!唯一動作していないのはアイコンで、次のレッスンで修正します。
---
@ -228,11 +228,13 @@ async function displayCarbonUsage(apiKey, region) {
## 復習と自己学習
このレッスンでは、LocalStorageとAPIについて学びました。どちらもプロフェッショナルなウェブ開発者にとって非常に有用です。これら2つがどのように連携するかについて考えてみてください。APIを使用するウェブサイトを設計する際に、どのようにアイテムを保存するかを考えてみましょう。
このレッスンでは、LocalStorageとAPIについて学びました。どちらもプロフェッショナルなウェブ開発者にとって非常に有用です。これら2つがどのように連携するかについて考えてみてください。APIを使用するためにアイテムを保存するウェブサイトをどのように設計するかを考えてみましょう。
## 課題
[APIを採用する](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された原文が公式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f198c6b817b4b2a99749f4662e7cae98",
"translation_date": "2025-08-23T23:46:53+00:00",
"original_hash": "49b58721a71cfda824e2f3e1f46908c6",
"translation_date": "2025-08-28T17:50:03+00:00",
"source_file": "5-browser-extension/3-background-tasks-and-performance/README.md",
"language_code": "ja"
}
@ -15,59 +15,59 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
このモジュールの前回の2つのレッスンでは、APIから取得したデータを表示するためのフォームと表示エリアを作成する方法を学びました。これは、ウェブ上でウェブプレゼンスを作成する非常に標準的な方法です。また、非同期でデータを取得する方法も学びました。これでブラウザ拡張機能はほぼ完成です。
このモジュールの前回の2つのレッスンでは、APIから取得したデータを表示するためのフォームと表示エリアを作成する方法を学びました。これは、ウェブ上で存在感を示す非常に標準的な方法です。また、非同期でデータを取得する方法も学びました。これでブラウザ拡張機能はほぼ完成です。
残る課題は、拡張機能のアイコンの色を更新するなどのバックグラウンドタスクを管理することです。このタイミングで、ブラウザがこの種のタスクをどのように管理するかについて考えるのは良い機会です。ウェブ資産を構築する際に、これらのブラウザタスクをパフォーマンスの観点から考えてみましょう。
残る課題は、拡張機能のアイコンの色を更新するなどのバックグラウンドタスクを管理することです。このタイミングで、ブラウザがこの種のタスクをどのように管理するかについて考えるのは良い機会です。これらのブラウザタスクを、ウェブ資産のパフォーマンスの観点から考えてみましょう。
## ウェブパフォーマンスの基本
> 「ウェブサイトのパフォーマンスは2つのことに関するものです: ページの読み込み速度と、その上で動作するコードの速度。」 -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
> 「ウェブサイトのパフォーマンスは2つのことに関するものです: ページがどれだけ速く読み込まれるか、そしてその上でコードがどれだけ速く実行されるか。」 -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
ウェブサイトをあらゆるデバイス、あらゆるユーザー、あらゆる状況で驚くほど高速にする方法についての話題は、当然ながら広範です。標準的なウェブプロジェクトやブラウザ拡張機能を構築する際に覚えておくべきポイントを以下に示します。
ウェブサイトをあらゆるデバイス、あらゆるユーザー、あらゆる状況で驚くほど速くする方法についての話題は、当然ながら広範です。標準的なウェブプロジェクトやブラウザ拡張機能を構築する際に覚えておくべきポイントを以下に示します。
サイトが効率的に動作していることを確認するために最初に行うべきことは、そのパフォーマンスに関するデータを収集することです。これを行う最初の場所は、ウェブブラウザの開発者ツールです。Edgeでは、「設定とその他」ボタン(ブラウザ右上の三点アイコン)を選択し、[その他のツール] > [開発者ツール] に移動してパフォーマンスタブを開きます。Windowsでは `Ctrl` + `Shift` + `I`、Macでは `Option` + `Command` + `I` のキーボードショートカットを使用して開発者ツールを開くこともできます。
サイトが効率的に動作していることを確認するために最初に行うべきことは、そのパフォーマンスに関するデータを収集することです。これを行う最初の場所は、ウェブブラウザの開発者ツールです。Edgeでは、ブラウザ右上の「設定とその他」ボタン(三点アイコン)を選択し、「その他のツール > 開発者ツール」に移動して「パフォーマンス」タブを開きます。Windowsでは`Ctrl` + `Shift` + `I`、Macでは`Option` + `Command` + `I`のキーボードショートカットでも開発者ツールを開くことができます。
パフォーマンスタブにはプロファイリングツールが含まれています。ウェブサイトを開き(例えば [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon) を試してみてください)、「記録」ボタンをクリックしてサイトを更新します。記録をいつでも停止すると、サイトを「スクリプト」、「レンダー」、「ペイント」するために生成されたルーチンを確認できます。
「パフォーマンス」タブにはプロファイリングツールがあります。ウェブサイトを開き(例: [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon))、「記録」ボタンをクリックしてサイトを更新します。記録をいつでも停止すると、サイトを「スクリプト」、「レンダー」、「ペイント」するために生成されたルーチンを見ることができます。
![Edge プロファイラー](../../../../5-browser-extension/3-background-tasks-and-performance/images/profiler.png)
![Edge プロファイラー](../../../../translated_images/profiler.5a4a62479c5df01cfec9aab74173dba13f91d2c968e1a1ae434c26165792df15.ja.png)
✅ [Microsoft Documentation](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) のEdgeのパフォーマンスタブについての情報を確認してください。
✅ [Microsoft Documentation](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon)でEdgeの「パフォーマンス」パネルについて学びましょう
> ヒント: サイトの起動時間を正確に測定するには、ブラウザのキャッシュをクリアしてください
> ヒント: サイトの起動時間を正確に測定するには、ブラウザのキャッシュをクリアしてください
プロファイルタイムラインの要素を選択して、ページの読み込み中に発生するイベントをズームインして確認します。
プロファイルタイムラインの要素を選択して、ページが読み込まれる間に発生するイベントをズームインして確認します。
プロファイルタイムラインの一部を選択して、ページのパフォーマンスのスナップショットを取得し、概要ペインを確認します。
![Edge プロファイラー スナップショット](../../../../5-browser-extension/3-background-tasks-and-performance/images/snapshot.png)
![Edge プロファイラー スナップショット](../../../../translated_images/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.ja.png)
イベントログペインを確認して、15ms以上かかったイベントがあるかどうかを確認します。
![Edge イベントログ](../../../../5-browser-extension/3-background-tasks-and-performance/images/log.png)
![Edge イベントログ](../../../../translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.ja.png)
プロファイラーを使いこなしてください!このサイトで開発者ツールを開き、ボトルネックがあるかどうか確認してください。最も遅い読み込み資産は何ですか?最も速いものは?
✅ このサイトで開発者ツールを開き、ボトルネックがあるかどうか確認してみましょう。最も遅く読み込まれる資産は何ですか?最も速いものは?
## プロファイリングチェック
一般的に、ウェブ開発者がサイトを構築する際に注意すべき「問題領域」がいくつかあります。これにより、プロダクションにデプロイする際の予期せぬ問題を回避できます。
**資産サイズ**: 過去数年間でウェブは「重く」、したがって遅くなっています。この重さの一部は画像の使用に関連しています。
**資産サイズ**: 過去数年間でウェブは「重く」なり、その結果遅くなりました。この重さの一部は画像の使用に関連しています。
✅ [Internet Archive](https://httparchive.org/reports/page-weight) を見て、ページの重さの歴史的な変化やその他の情報を確認してください
✅ [Internet Archive](https://httparchive.org/reports/page-weight)を見て、ページの重さの歴史的な変化やその他の情報を確認しましょう
良いプラクティスとして、画像を最適化し、ユーザーに適したサイズと解像度で配信することを確認してください
良いプラクティスとして、画像を最適化し、ユーザーに適したサイズと解像度で配信することを心がけましょう
**DOMのトラバーサル**: ブラウザは、あなたが書いたコードに基づいてDocument Object Modelを構築する必要があります。そのため、タグを最小限に抑え、ページが必要とするものだけを使用してスタイリングすることが、良いページパフォーマンスのために重要です。この点で、ページに関連する過剰なCSSは最適化されるべきです。例えば、特定のページでのみ使用されるスタイルは、メインのスタイルシートに含める必要はありません。
**DOMのトラバーサル**: ブラウザは、あなたが書いたコードに基づいてDocument Object Modelを構築する必要があります。そのため、タグを最小限に抑え、ページが必要とするものだけを使用してスタイリングすることが、良いページパフォーマンスのために重要です。この点で、ページに関連する余分なCSSは最適化されるべきです。例えば、特定のページでのみ使用されるスタイルは、メインのスタイルシートに含める必要はありません。
**JavaScript**: すべてのJavaScript開発者は、DOMがトラバーサルされてブラウザにペイントされる前に読み込まれる必要がある「レンダーブロッキング」スクリプトに注意する必要があります。インラインスクリプトで `defer` を使用することを検討してくださいTerrariumモジュールで行われているように
**JavaScript**: すべてのJavaScript開発者は、DOMがトラバーサルされてブラウザにペイントされる前にロードされる必要がある「レンダーブロッキング」スクリプトに注意を払うべきです。インラインスクリプトに`defer`を使用することを検討してくださいTerrariumモジュールで行われているように
✅ [サイト速度テストウェブサイト](https://www.webpagetest.org/) を試して、サイトパフォーマンスを判断するために行われる一般的なチェックについて学んでください
✅ [Site Speed Test website](https://www.webpagetest.org/)でいくつかのサイトを試して、サイトパフォーマンスを判断するために行われる一般的なチェックについて学びましょう
ブラウザが送信する資産をレンダリングする方法について理解したところで、拡張機能を完成させるために必要な最後のいくつかのことを見てみましょう。
ブラウザが送信された資産をどのようにレンダリングするかについての理解が深まったところで、拡張機能を完成させるために必要な最後のいくつかのことを見てみましょう。
### 色を計算する関数を作成する
`/src/index.js` で、DOMにアクセスするために設定した一連の `const` 変数の後に、`calculateColor()` という関数を追加します。
`/src/index.js`で、DOMにアクセスするために設定した一連の`const`変数の後に、`calculateColor()`という関数を追加します。
```JavaScript
function calculateColor(value) {
@ -88,19 +88,19 @@ function calculateColor(value) {
}
```
ここで何が起こっているのでしょうか前回のレッスンで完了したAPIコールから値(炭素強度)を渡し、その値がcolors配列に提示されたインデックスにどれだけ近いかを計算します。そして、その最も近い色の値をchrome runtimeに送信します。
ここで何が起こっているのでしょうか前回のレッスンで完了したAPI呼び出しから炭素強度の値を渡し、その値がcolors配列に提示されたインデックスにどれだけ近いかを計算します。そして、その最も近い色の値をchrome runtimeに送信します。
chrome.runtimeには、さまざまなバックグラウンドタスクを処理する[API](https://developer.chrome.com/extensions/runtime)があります。あなたの拡張機能はこれを活用しています。
> 「chrome.runtime APIを使用して、バックグラウンドページを取得し、マニフェストの詳細を返し、アプリまたは拡張機能のライフサイクル内のイベントをリッスンして応答します。また、このAPIを使用して、URLの相対パスを完全修飾URLに変換することもできます。」
✅ Edge用にこのブラウザ拡張機能を開発している場合、chrome APIを使用していることに驚くかもしれません。新しいEdgeブラウザバージョンはChromiumブラウザエンジン上で動作るため、これらのツールを活用できます。
✅ Edge用にこのブラウザ拡張機能を開発している場合、chrome APIを使用していることに驚くかもしれません。新しいEdgeブラウザバージョンはChromiumブラウザエンジン上で動作しているため、これらのツールを活用できます。
> 注意: ブラウザ拡張機能をプロファイリングする場合、拡張機能自体から開発者ツールを起動してください。拡張機能は独自のブラウザインスタンスとして動作します。
### デフォルトのアイコン色を設定する
次に、`init()` 関数内で、chromeの `updateIcon` アクションを再度呼び出して、アイコンを最初汎用的な緑色に設定します。
次に、`init()`関数内で、chromeの`updateIcon`アクションを再度呼び出して、アイコンを最初汎用的な緑色に設定します。
```JavaScript
chrome.runtime.sendMessage({
@ -111,16 +111,16 @@ chrome.runtime.sendMessage({
});
```
### 関数を呼び出し、APIコールを実行する
### 関数を呼び出し、API呼び出しを実行する
次に、前回作成した関数を、C02Signal APIから返されるプロミスに追加して呼び出します。
次に、前回作成した関数をC02Signal APIから返されるPromiseに追加して呼び出します。
```JavaScript
//let CO2...
calculateColor(CO2);
```
最後に、`/dist/background.js` で、これらのバックグラウンドアクションコールのリスナーを追加します。
最後に、`/dist/background.js`で、これらのバックグラウンドアクション呼び出しをリッスンするリスナーを追加します。
```JavaScript
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
@ -142,11 +142,11 @@ function drawIcon(value) {
}
```
このコードでは、バックエンドタスクマネージャーに送信されるメッセージのリスナーを追加しています。メッセージが「updateIcon」と呼ばれる場合、次のコードが実行され、Canvas APIを使用して適切な色のアイコンを描画します。
このコードでは、バックエンドタスクマネージャーに送信されるメッセージをリッスンしています。メッセージが「updateIcon」と呼ばれる場合、次のコードが実行され、Canvas APIを使用して適切な色のアイコンを描画します。
Canvas APIについては、[スペースゲームのレッスン](../../6-space-game/2-drawing-to-canvas/README.md)でさらに学ぶことができます
[Space Game lessons](../../6-space-game/2-drawing-to-canvas/README.md)でCanvas APIについてさらに学びましょう
次に拡張機能を再構築します(`npm run build`)、拡張機能を更新して起動し、色の変化を確認します。今が買い物や皿洗いをするのに良いタイミングかどうかがわかりますね!
次に拡張機能を再構築します(`npm run build`)、拡張機能を更新して起動し、色の変化を確認します。今がちょっとした用事を済ませたり皿洗いをするのに良いタイミングかもしれませんね!これでわかります。
おめでとうございます!便利なブラウザ拡張機能を構築し、ブラウザの動作やそのパフォーマンスをプロファイリングする方法についてさらに学びました。
@ -154,7 +154,7 @@ function drawIcon(value) {
## 🚀 チャレンジ
長い間存在しているオープンソースウェブサイトを調査し、そのGitHub履歴に基づいて、パフォーマンスのためにどのように最適化されたかを確認してください。最も一般的な問題点は何ですか?
長い間存在しているオープンソースウェブサイトを調査し、そのGitHub履歴に基づいて、パフォーマンスのためにどのように最適化されてきたかを特定できるか試してみましょう。最も一般的な問題点は何ですか?
## 講義後クイズ
@ -164,11 +164,13 @@ function drawIcon(value) {
[パフォーマンスニュースレター](https://perf.email/)に登録することを検討してください。
ブラウザがウェブパフォーマンスを評価する方法について、ウェブツールのパフォーマンスタブを調査してください。大きな違いは見つかりますか?
ブラウザがウェブパフォーマンスをどのように評価するかについて、ウェブツールのパフォーマンスタブを調査してみましょう。大きな違いは見つかりますか?
## 課題
[サイトのパフォーマンスを分析する](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当は責任を負いません。

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "d9da6dc61fb712b29f65e108c79b8a5d",
"translation_date": "2025-08-23T23:05:31+00:00",
"original_hash": "979cfcce2413a87d9e4c67eb79234bc3",
"translation_date": "2025-08-28T17:54:00+00:00",
"source_file": "6-space-game/1-introduction/README.md",
"language_code": "ja"
}
@ -17,30 +17,30 @@ CO_OP_TRANSLATOR_METADATA:
### ゲーム開発における継承とコンポジション
以前のレッスンでは、作成したアプリの設計アーキテクチャについてあまり気にする必要はありませんでした。プロジェクトの規模が非常に小さかったからです。しかし、アプリケーションの規模や範囲が大きくなるにつれて、アーキテクチャの決定が重要な課題となります。JavaScriptで大規模なアプリケーションを作成するには、主に2つのアプローチがあります*コンポジション*または*継承*です。それぞれに利点と欠点がありますが、ゲームの文脈で説明してみましょう。
これまでのレッスンでは、作成したアプリの設計アーキテクチャについてあまり考える必要はありませんでした。なぜなら、プロジェクトの規模が非常に小さかったからです。しかし、アプリケーションの規模や範囲が大きくなるにつれて、アーキテクチャの決定が重要な課題となります。JavaScriptで大規模なアプリケーションを作成するには、主に2つのアプローチがあります*コンポジション* または *継承*。どちらにも長所と短所がありますが、ゲームの文脈で説明してみましょう。
最も有名なプログラミング書籍の1つは[デザインパターン](https://en.wikipedia.org/wiki/Design_Patterns)に関するものです。
プログラミングに関する最も有名な本の1つは、[デザインパターン](https://en.wikipedia.org/wiki/Design_Patterns)に関するものです。
ゲームでは、`ゲームオブジェクト`という画面上に存在するオブジェクトがあります。これらはデカルト座標系上の位置を持ち、`x`座標と`y`座標で特徴付けられます。ゲームを開発していくと、すべてのゲームオブジェクトが標準的なプロパティを持っていることに気づくでしょう。これは、作成するすべてのゲームに共通する要素であり、以下のようなものです:
ゲームでは、`ゲームオブジェクト`という画面上に存在するオブジェクトがあります。これらはデカルト座標系上の位置を持ち、`x`座標と`y`座標で特徴付けられます。ゲームを開発していくと、すべてのゲームオブジェクトが標準的なプロパティを持っていることに気づくでしょう。それは、以下のような要素です:
- **位置ベース** ほとんどのゲーム要素は位置ベースです。つまり、`x`と`y`の位置を持っています。
- **移動可能** 新しい位置に移動できるオブジェクトです。通常、ヒーロー、モンスター、NPC非プレイヤーキャラクターなどが該当しますが、例えば木のような静的オブジェクトは該当しません。
- **自己破壊** これらのオブジェクトは一定期間だけ存在し、その後削除される準備をします。通常、`dead`や`destroyed`というブール値で表され、ゲームエンジンにこのオブジェクトを描画しないように指示します。
- **クールダウン** 'クールダウン'は短命のオブジェクトに共通するプロパティです。典型的な例としては、数ミリ秒だけ表示されるテキストや爆発のようなグラフィカルエフェクトがあります。
- **移動可能** 新しい位置に移動できるオブジェクトです。通常、ヒーロー、モンスター、またはNPC非プレイヤーキャラクターが該当しますが、例えば木のような静的オブジェクトは該当しません。
- **自己破壊** 一定期間だけ存在し、その後削除されるオブジェクトです。通常、`dead`や`destroyed`というブール値で表され、ゲームエンジンにそのオブジェクトを描画しないよう指示します。
- **クールダウン** 短命なオブジェクトに共通するプロパティです。典型的な例としては、数ミリ秒だけ表示されるテキストや爆発のようなグラフィカルエフェクトがあります。
✅ パックマンのようなゲームを考えてみましょう。このゲームで上記の4つのオブジェクトタイプを特定できますか
✅ パックマンのようなゲームを考えてみてください。このゲームで上記の4つのオブジェクトタイプを特定できますか
### 振る舞いの表現
上記で説明したのは、ゲームオブジェクトが持つ可能性のある振る舞いです。それをどのようにコード化するのでしょうか?これらの振る舞いは、クラスやオブジェクトに関連付けられたメソッドとして表現できます。
上記で説明したのは、ゲームオブジェクトが持つ可能性のある振る舞いです。それでは、これらをどのようにコード化するのでしょうか?これらの振る舞いは、クラスやオブジェクトに関連付けられたメソッドとして表現できます。
**クラス**
`クラス`を使用して、`継承`と組み合わせることで、特定の振る舞いをクラスに追加することができます。
`クラス`と`継承`を組み合わせて、特定の振る舞いをクラスに追加する方法があります。
✅ 継承は重要な概念です。[MDNの継承に関する記事](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)でさらに学びましょう。
✅ 継承は理解すべき重要な概念です。[MDNの継承に関する記事](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)でさらに学びましょう。
コードで表現すると、ゲームオブジェクトは通常以下のようになります:
コードで表現すると、ゲームオブジェクトは通常のようになります:
```javascript
@ -88,11 +88,11 @@ hero.moveTo(5,5);
const tree = new Tree();
```
数分間、パックマンのヒーロー(例えばインキー、ピンキー、ブリンキーを再構想し、それをJavaScriptでどのように記述するか考えてみましょう
✅ パックマンのヒーロー例えばインキー、ピンキー、ブリンキーを再構想し、それをJavaScriptでどのように記述するか考えてみてください
**コンポジション**
オブジェクトの継承を処理する別の方法として、*コンポジション*を使用することがあります。この場合、オブジェクトは以下のように振る舞いを表現します:
オブジェクトの継承を扱う別の方法として、*コンポジション*を使用する方法があります。この場合、オブジェクトは次のように振る舞いを表現します:
```javascript
//create a constant gameObject
@ -143,17 +143,17 @@ const tree = createStatic(0,0, 'Tree');
--
ゲーム開発で一般的なもう1つのパターンは、ゲームのユーザーエクスペリエンスとパフォーマンスを理する問題に対処するものです。
ゲーム開発で一般的なもう1つのパターンは、ゲームのユーザーエクスペリエンスとパフォーマンスを理する問題に対処するものです。
## Pub/subパターン
✅ Pub/Subは「パブリッシュ-サブスクライブ」の略です。
✅ Pub/Subは「publish-subscribe発行-購読)」の略です。
このパターンは、アプリケーションの異なる部分が互いを知らないようにするというアイデアに対処します。なぜそれが重要なのでしょうか?アプリケーションの各部分が分離されていると、全体の状況を把握しやすくなります。また、必要に応じて振る舞いを突然変更するのも簡単になります。これをどうやって実現するのでしょうか?以下の概念を確立することで実現します:
このパターンは、アプリケーションの異なる部分がお互いを知らないようにするという考え方に基づいています。なぜそうするのでしょうか?アプリケーションの各部分が分離されていると、全体の状況を把握しやすくなります。また、必要に応じて振る舞いを突然変更するのも簡単になります。これをどのように実現するのでしょうか?以下の概念を確立することで実現します:
- **メッセージ**: メッセージは通常、テキスト文字列とオプションのペイロード(メッセージの内容を明確にするデータ)で構成されます。ゲームでの典型的なメッセージは`KEY_PRESSED_ENTER`です。
- **メッセージ**: メッセージは通常、テキスト文字列と、メッセージの内容を明確にするためのオプションのペイロード(データ片)で構成されます。ゲームでの典型的なメッセージは`KEY_PRESSED_ENTER`です。
- **パブリッシャー**: この要素はメッセージを*発行*し、すべてのサブスクライバーに送信します。
- **サブスクライバー**: この要素は特定のメッセージを*受信*し、そのメッセージを受け取った結果として何らかのタスクを実行します。例えば、レーザーを発射するなどです
- **サブスクライバー**: この要素は特定のメッセージを*受信*し、そのメッセージを受け取った結果として何らかのタスクを実行します(例:レーザーを発射する)
この実装は非常に小規模ですが、非常に強力なパターンです。以下のように実装できます:
@ -204,7 +204,7 @@ window.addEventListener('keyup', (evt) => {
});
```
上記では、キーボードイベント`ArrowLeft`を接続し、`HERO_MOVE_LEFT`メッセージを送信しています。そのメッセージを受信して、結果として`hero`を移動させます。このパターンの強みは、イベントリスナーとヒーローが互いを知らないことです。`ArrowLeft`を`A`キーに再マッピングすることもできます。また、イベントEmitterの`on`関数を少し編集することで、`ArrowLeft`で完全に異なる動作を行うことも可能です:
上記では、キーボードイベント`ArrowLeft`を接続し、`HERO_MOVE_LEFT`メッセージを送信しています。このメッセージをリッスンして、結果として`hero`を移動させます。このパターンの強みは、イベントリスナーとヒーローが互いを知らないことです。`ArrowLeft`を`A`キーに再マッピングすることもできます。また、イベントエミッターの`on`関数を少し編集するだけで、`ArrowLeft`でまったく異なる動作をさせることも可能です:
```javascript
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
@ -212,13 +212,13 @@ eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
});
```
ゲームが成長して複雑になるにつれて、このパターンの複雑さは変わらず、コードはきれいなままです。このパターンを採用することを強くお勧めします。
ゲームが成長して複雑になるにつれて、このパターンの複雑さは変わらず、コードはクリーンなままです。このパターンを採用することを強くお勧めします。
---
## 🚀 チャレンジ
Pub/Subパターンがゲームをどのように強化できるか考えてみましょう。どの部分がイベントを発行すべきで、ゲームはそれにどう反応すべきでしょうか新しいゲームを考え、その部分がどのように振る舞うかを創造的に考えるチャンスです。
Pub/Subパターンがゲームをどのように強化できるか考えてみましょう。どの部分がイベントを発行すべきで、ゲームはそれにどう反応すべきでしょうか新しいゲームを考え、そのパーツがどのように振る舞うかを創造的に考えるチャンスです。
## 講義後クイズ
@ -226,11 +226,13 @@ Pub/Subパターンがゲームをどのように強化できるか考えてみ
## 復習と自己学習
Pub/Subについてさらに学ぶには、[こちらの記事を読む](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber/?WT.mc_id=academic-77807-sagibbon)ことをお勧めします
Pub/Subについてさらに学ぶには、[こちらを読んでください](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber/?WT.mc_id=academic-77807-sagibbon)。
## 課題
[ゲームをモックアップする](assignment.md)
[ゲームのモックアップを作成する](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確さが含まれる可能性があります。元の言語で記載された原文が公式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当社は一切の責任を負いません。

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "41be8d35e7f30aa9dad10773c35e89c4",
"translation_date": "2025-08-23T22:59:07+00:00",
"original_hash": "056641280211e52fd0adb81b6058ec55",
"translation_date": "2025-08-28T17:53:20+00:00",
"source_file": "6-space-game/2-drawing-to-canvas/README.md",
"language_code": "ja"
}
@ -15,17 +15,17 @@ CO_OP_TRANSLATOR_METADATA:
## キャンバス
キャンバスはHTMLの要素で、デフォルトでは何も内容がありません。真っ白な状態です。描画することで内容を追加します。
キャンバスはデフォルトではコンテンツがないHTML要素で、まっさらな状態です。描画することで内容を追加します。
✅ [Canvas APIについてもっと読む](https://developer.mozilla.org/docs/Web/API/Canvas_API) (MDN)
✅ [Canvas APIについてもっと読む](https://developer.mozilla.org/docs/Web/API/Canvas_API)MDN
通常、キャンバスはページのbody部分で以下のように宣言されます:
通常、キャンバスはページのbody部分で以下のように宣言されます
```html
<canvas id="myCanvas" width="200" height="100"></canvas>
```
上記では`id`、`width`、`height`を設定しています。
上記では`id`、`width`、`height`を設定しています。
- `id`: キャンバスにアクセスして操作するための参照を取得するために設定します。
- `width`: 要素の幅を指定します。
@ -35,16 +35,16 @@ CO_OP_TRANSLATOR_METADATA:
キャンバスはデカルト座標系を使用して描画を行います。そのため、x軸とy軸を使って位置を表現します。座標`0,0`は左上の位置を示し、右下はキャンバスの幅と高さで指定した位置になります。
![キャンバスのグリッド](../../../../6-space-game/2-drawing-to-canvas/canvas_grid.png)
![キャンバスのグリッド](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.ja.png)
> 画像提供: [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes)
キャンバス要素に描画するには、以下の手順を踏む必要があります:
キャンバス要素に描画するには、以下の手順を踏む必要があります
1. **キャンバス要素の参照を取得**する。
1. **キャンバス上のコンテキスト要素の参照を取得**する。
1. **キャンバス要素上のコンテキスト要素の参照を取得**する。
1. **コンテキスト要素を使って描画操作を実行**する。
上記の手順を実現するコードは通常以下のようになります:
上記の手順をコードで表すと以下のようになります:
```javascript
// draws a red rectangle
@ -63,17 +63,17 @@ ctx.fillRect(0,0, 200, 200) // x,y,width, height
✅ Canvas APIは主に2D図形に焦点を当てていますが、Webサイトに3D要素を描画することも可能です。その場合は[WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API)を使用します。
Canvas APIを使えば、以下のようなものを描画できます:
Canvas APIを使えば以下のようなものを描画できます:
- **幾何学的な図形**: すでに長方形の描画方法を紹介しましたが、他にも多くの図形を描画できます。
- **テキスト**: 任意のフォントや色でテキストを描画できます。
- **画像**: 例えば.jpgや.pngなどの画像アセットを基に画像を描画できます。
- **画像**: .jpgや.pngなどの画像アセットを基に画像を描画できます。
✅ 試してみましょう長方形の描き方を学びましたが、円をページに描画できますかCodePenで興味深いCanvasの描画例を見てみましょう。[特に印象的な例はこちら](https://codepen.io/dissimulate/pen/KrAwx)。
✅ 試してみましょう長方形の描き方を学びましたが、円をページに描画できますかCodePenで興味深いCanvasの描画例を見てみましょう。こちらは[特に印象的な例](https://codepen.io/dissimulate/pen/KrAwx)です
## 画像アセットを読み込んで描画する
画像アセットを読み込むには、`Image`オブジェクトを作成し、その`src`プロパティを設定します。その後、`load`イベントを監視して使用可能になったことを確認します。コードは以下のようになります:
画像アセットを読み込むには、`Image`オブジェクトを作成し、その`src`プロパティを設定します。その後、`load`イベントを監視して使用可能になったことを確認します。コードは以下のようになります
### アセットの読み込み
@ -87,7 +87,7 @@ img.onload = () => {
### アセット読み込みのパターン
上記を以下のような構造にラップすることを推奨します。これにより使いやすくなり、完全に読み込まれた後でのみ操作を試みることができます:
上記を以下のような構造にラップすることを推奨します。これにより使いやすくなり、完全に読み込まれた後にのみ操作を試みることができます:
```javascript
function loadAsset(path) {
@ -110,7 +110,7 @@ async function run() {
```
ゲームアセットを画面に描画するコードは以下のようになります:
ゲームアセットを画面に描画するコードは以下のようになります
```javascript
async function run() {
@ -128,19 +128,19 @@ async function run() {
### 作るもの
キャンバス要素を含むWebページを作成します。`1024*768`の黒い画面を描画します。以下の2つの画像を提供しています:
キャンバス要素を含むWebページを作成します。`1024*768`の黒い画面をレンダリングする必要があります。以下の2つの画像を提供しています
- ヒーローの船
![ヒーローの船](../../../../6-space-game/2-drawing-to-canvas/solution/assets/player.png)
![ヒーローの船](../../../../translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.ja.png)
- 5*5のモンスター
![モンスターの船](../../../../6-space-game/2-drawing-to-canvas/solution/assets/enemyShip.png)
![モンスターの船](../../../../translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.ja.png)
### 開発を始めるための推奨手順
`your-work`サブフォルダに作成されたファイルを見つけてください。以下の内容が含まれているはずです:
`your-work`サブフォルダに作成されたファイルを見つけてください。このフォルダには以下が含まれているはずです:
```bash
-| assets
@ -151,9 +151,9 @@ async function run() {
-| package.json
```
このフォルダのコピーをVisual Studio Codeで開きます。ローカル開発環境をセットアップする必要があります。理想的には、Visual Studio CodeとNPM、Nodeがインストールされている状態です。コンピュータに`npm`がセットアップされていない場合は、[こちらで設定方法を確認してください](https://www.npmjs.com/get-npm)。
Visual Studio Codeでこのフォルダのコピーを開きます。ローカル開発環境がセットアップされている必要があります。推奨される環境は、Visual Studio Code、NPM、Nodeがインストールされていることです。コンピュータに`npm`がセットアップされていない場合は、[こちらで設定方法を確認してください](https://www.npmjs.com/get-npm)。
プロジェクトを開始するには、`your_work`フォルダに移動します:
プロジェクトを開始するには、`your_work`フォルダに移動します
```bash
cd your-work
@ -166,10 +166,10 @@ npm start
### コードを追加する
以下を解決するために`your-work/app.js`に必要なコードを追加してください:
以下を解決するために`your-work/app.js`に必要なコードを追加してください
1. **キャンバスを黒い背景で描画する**
> ヒント: `/app.js`の適切なTODOの下に2行追加し、`ctx`要素を黒に設定し、左上の座標を`0,0`に、キャンバスの幅と高さをキャンバスのサイズに等しく設定します。
1. **キャンバスを描画**して黒い背景を設定する
> ヒント: `/app.js`の適切なTODOの下に2行追加し、`ctx`要素を黒に設定し、左上の座標を0,0に、キャンバスの高さと幅をキャンバスのサイズに等しく設定します。
2. **テクスチャを読み込む**
> ヒント: `await loadTexture`を使用して画像パスを渡し、プレイヤーと敵の画像を追加します。まだ画面には表示されません!
3. **画面の下半分の中央にヒーローを描画する**
@ -177,7 +177,7 @@ npm start
4. **5*5のモンスターを描画する**
> ヒント: 敵を画面に描画するコードをコメント解除します。その後、`createEnemies`関数に移動して構築します。
まず、いくつかの定数を設定します:
まず、いくつかの定数を設定します
```javascript
const MONSTER_TOTAL = 5;
@ -186,7 +186,7 @@ npm start
const STOP_X = START_X + MONSTER_WIDTH;
```
次に、モンスターの配列を画面に描画するループを作成します:
次に、モンスターの配列を画面に描画するループを作成します
```javascript
for (let x = START_X; x < STOP_X; x += 98) {
@ -198,9 +198,9 @@ npm start
## 結果
完成した結果は以下のようになります:
完成した結果は以下のようになります
![黒い画面にヒーローと5*5のモンスター](../../../../6-space-game/2-drawing-to-canvas/partI-solution.png)
![黒い画面にヒーローと5*5のモンスター](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.ja.png)
## 解答
@ -218,11 +218,13 @@ npm start
## 復習と自己学習
Canvas APIについてもっと学ぶには、[こちらを読んでください](https://developer.mozilla.org/docs/Web/API/Canvas_API)。
Canvas APIについてもっと学ぶには、[こちらを読](https://developer.mozilla.org/docs/Web/API/Canvas_API)のがおすすめです
## 課題
[Canvas APIで遊んでみよう](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。元の言語で記載された文書が公式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤った解釈について、当社は責任を負いません。

@ -1,32 +1,32 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "23f088add24f0f1fa51014a9e27ea280",
"translation_date": "2025-08-23T22:56:34+00:00",
"original_hash": "a9a161871de7706cb0e23b1bd0c74559",
"translation_date": "2025-08-28T17:51:46+00:00",
"source_file": "6-space-game/3-moving-elements-around/README.md",
"language_code": "ja"
}
-->
# 宇宙ゲームを作ろう パート3: 動きを追加する
# スペースゲームを作ろう パート3: 動きを追加する
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/33)
ゲームは、画面上でエイリアンが動き回るようになって初めて面白くなりますこのゲームでは、以下の2種類の動きを使用します:
ゲームは、画面上でエイリアンが動き回るようになって初めて楽しくなりますこのゲームでは、以下の2種類の動きを利用します:
- **キーボード/マウスの動き**: ユーザーがキーボードやマウスを操作して画面上のオブジェクトを動かす場合。
- **ゲームによる動き**: ゲームが一定の時間間隔でオブジェクトを動かす場合。
では、画面上で物を動かすにはどうすればいいのでしょうか?それはすべてデカルト座標に関することです。オブジェクトの位置 (x, y) を変更し、画面を再描画します。
では、画面上で物を動かすにはどうすればいいのでしょうか?それはすべてデカルト座標に関することです。オブジェクトの位置 (x, y) を変更し、その後画面を再描画します。
通常、画面上で「動き」を実現するには以下のステップが必要です:
通常、画面上で「動き」を実現するには以下の手順が必要です:
1. **新しい位置を設定する**: オブジェクトが移動したように見えるために必要です。
2. **画面をクリアする**: 描画の間に画面をクリアする必要があります。背景色で塗りつぶした形を描画することでクリアできます。
3. **新しい位置オブジェクトを再描画する**: これにより、オブジェクトをある位置から別の位置に移動させることができます。
1. **新しい位置を設定する**: オブジェクトが動いたように見せるために必要です。
2. **画面をクリアする**: 描画の間に画面をクリアする必要があります。背景色で塗りつぶした長方形を描画することでクリアできます。
3. **新しい位置オブジェクトを再描画する**: これにより、オブジェクトをある位置から別の位置に移動させることができます。
以下はコードの例です:
以下はコードの例です:
```javascript
//set the hero's location
@ -39,15 +39,15 @@ ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
```
ヒーローを1秒間に何フレームも再描画することで、パフォーマンスコストが発生する理由を考えられますか?[このパターンの代替案](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas)について読んでみましょう
毎秒何フレームもヒーローを再描画すると、パフォーマンスコストが発生する理由を考えられますか?[このパターンの代替案](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas)について読んでみてください
## キーボードイベントを処理する
## キーボードイベントの処理
イベントは特定のコードに紐付けて処理します。キーボードイベントはウィンドウ全体でトリガーされますが、マウスイベント(例えば `click`)は特定の要素をクリックすることに付けることができます。このプロジェクトではキーボードイベントを使用します。
イベントを処理するには、特定のイベントをコードに関連付けます。キーボードイベントはウィンドウ全体でトリガーされますが、マウスイベント(例えば `click`)は特定の要素をクリックすることに関連付けることができます。このプロジェクトではキーボードイベントを使用します。
イベントを処理するには、ウィンドウの `addEventListener()` メソッドを使用し、2つの入力パラメータを提供する必要があります。1つ目のパラメータはイベント名例: `keyup`、2つ目のパラメータはイベントが発生した結果として呼び出されるべき関数です。
イベントを処理するには、ウィンドウの `addEventListener()` メソッドを使用し、2つの入力パラメータを提供する必要があります。1つ目のパラメータはイベント(例: `keyup`、2つ目のパラメータはイベントが発生した結果として呼び出される関数です。
以下は例です:
以下はその例です:
```javascript
window.addEventListener('keyup', (evt) => {
@ -58,16 +58,16 @@ window.addEventListener('keyup', (evt) => {
})
```
キーイベントでは、押されたキーを確認するために使用できる2つのプロパティがあります:
キーイベントでは、押されたキーを確認するためにイベントの2つのプロパティを使用できます:
- `key`: 押されたキーの文字列表現(例: `ArrowUp`
- `keyCode`: 数値表現(例: `37`)、これは `ArrowLeft` に対応します。
- `keyCode`: 数値表現(例: `37`、これは `ArrowLeft` に対応)
✅ キーイベントの操作はゲーム開発以外でも役立ちます。この技術の他の用途を考えてみてください。
✅ キーイベントの操作はゲーム開発以外でも役立ちます。この技術の他の用途を考えられますか?
### 特殊キー: 注意点
ウィンドウに影響を与える*特殊*なキーがあります。つまり、`keyup` イベントを監視していて、これらの特殊キーを使ってヒーローを移動させると、水平スクロールも実行されます。そのため、ゲームを構築する際にはこのブラウザの組み込み動作を*無効化*する必要があります。以下のようなコードが必要です:
ウィンドウに影響を与える*特殊な*キーがあります。例えば、`keyup` イベントをリッスンしている場合、これらの特殊キーを使ってヒーローを移動させると、水平スクロールも実行されます。そのため、ゲームを構築する際にはこのブラウザの組み込み動作を*無効化*する必要があるかもしれません。そのためには以下のようなコードが必要です:
```javascript
let onKeyDown = function (e) {
@ -88,11 +88,11 @@ let onKeyDown = function (e) {
window.addEventListener('keydown', onKeyDown);
```
上記のコードは、矢印キーとスペースキーの*デフォルト*動作を無効化します。この*無効化*メカニズムは、`e.preventDefault()` を呼び出すことで実現されます。
上記のコードは、矢印キーとスペースキーの*デフォルト*の動作を無効化します。この*無効化*の仕組みは、`e.preventDefault()` を呼び出すことで実現されます。
## ゲームによる動き
`setTimeout()``setInterval()` 関数を使用して、一定の時間間隔でオブジェクトの位置を更新することで、物を自動的に動かすことができます。以下はその例です:
`setTimeout()``setInterval()` のようなタイマーを使用して、一定の時間間隔でオブジェクトの位置を更新することで、オブジェクトを自動的に動かすことができます。以下はその例です:
```javascript
let id = setInterval(() => {
@ -103,9 +103,9 @@ let id = setInterval(() => {
## ゲームループ
ゲームループは、定期的に呼び出される関数の概念です。ゲームループと呼ばれるのは、ユーザーに表示されるべきすべてのものがループ内で描画されるためです。ゲームループは、ゲームの一部であるすべてのゲームオブジェクトを使用し、それらを描画します。ただし、何らかの理由でゲームの一部ではなくなった場合は除外されます。例えば、敵がレーザーで撃たれて爆発した場合、その敵は現在のゲームループの一部ではなくなります(これについては後のレッスンで詳しく学びます)。
ゲームループは、定期的に呼び出される関数の概念です。ゲームループと呼ばれるのは、ユーザーに見えるすべてのものがこのループ内で描画されるためです。ゲームループは、ゲームの一部であるすべてのゲームオブジェクトを使用し、それらを描画します。ただし、何らかの理由でゲームの一部ではなくなったオブジェクト(例えば、レーザーで撃たれて爆発した敵)は除外されます(これについては後のレッスンで詳しく学びます)。
以下は典型的なゲームループをコードで表現したものです:
以下は、コードで表現された典型的なゲームループのです:
```javascript
let gameLoopId = setInterval(() =>
@ -119,18 +119,18 @@ let gameLoopId = setInterval(() =>
}, 200);
```
上記のループは、`200` ミリ秒ごとにキャンバスを再描画します。ゲームに最適な間隔を選択することができます。
上記のループは、200ミリ秒ごとにキャンバスを再描画します。ゲームに最適な間隔を選択することができます。
## 宇宙ゲームの続き
## スペースゲームの続き
既存のコードを拡張します。パートIで完成させたコードを使用するか、[パートIIのスターターコード](../../../../6-space-game/3-moving-elements-around/your-work)を使用してください。
- **ヒーローを動かす**: 矢印キーを使用してヒーローを動かせるようにコードを追加します。
- **敵を動かす**: 敵が一定の速度で上から下移動するようにコードを追加します。
- **敵を動かす**: 敵が一定の速度で上から下移動するようにコードを追加します。
## 推奨ステップ
## 推奨手順
`your-work` サブフォルダに作成されたファイルを見つけてください。以下が含まれているはずです:
`your-work` サブフォルダに作成されたファイルを見つけてください。以下の内容が含まれているはずです:
```bash
-| assets
@ -141,22 +141,22 @@ let gameLoopId = setInterval(() =>
-| package.json
```
`your_work` フォルダでプロジェクトを開始するには以下を入力してください
プロジェクトを開始するには、`your_work` フォルダで以下を入力します
```bash
cd your-work
npm start
```
上記のコマンドは、`http://localhost:5000` アドレスでHTTPサーバーを開始します。ブラウザを開き、そのアドレスを入力してください。現在のところ、ヒーローとすべての敵が表示されるはずですが、まだ何も動いていません!
上記のコマンドは、`http://localhost:5000` アドレスでHTTPサーバーを起動します。ブラウザを開いてそのアドレスを入力してください。現在のところ、ヒーローとすべての敵が表示されるはずですが、まだ何も動いていません!
### コードを追加する
### コードを追加
1. **専用のオブジェクトを追加する**: `hero`、`enemy`、`game object` を追加し、それぞれに `x``y` プロパティを持たせます。([継承またはコンポジション](../README.md) の部分を思い出してください)。
1. **専用のオブジェクトを追加**: `hero`、`enemy`、`game object` を追加し、それぞれに `x``y` プロパティを持たせます。([継承またはコンポジション](../README.md) の部分を思い出してください)。
*ヒント* `game object``x``y` を持ち、キャンバスに自分自身を描画する能を持つべきです。
*ヒント*: `game object``x``y` を持ち、キャンバスに自分自身を描画する能を持つべきです。
>ヒント: 以下のようにコンストラクタを定義した新しい GameObject クラスを追加し、キャンバスに描画してください:
> ヒント: 以下のようにコンストラクタを定義した新しい GameObject クラスを追加し、それをキャンバスに描画してみてください:
```javascript
@ -205,11 +205,11 @@ npm start
}
```
2. **キーイベントハンドラを追加する**: キー操作(ヒーローを上下左右に移動)を処理するコードを追加します。
2. **キーイベントハンドラを追加**: キー操作(ヒーローを上下左右に移動)を処理するコードを追加します。
*注意* デカルト座標系では、左上が `0,0` です。また、*デフォルト動作*を停止するコードを追加することを忘れないでください。
*覚えておいてください*: これはデカルト座標系であり、左上が `0,0` です。また、*デフォルト動作*を停止するコードを追加することを忘れないでください。
>ヒント: onKeyDown 関数を作成し、それをウィンドウに紐付けます:
> ヒント: onKeyDown 関数を作成し、それをウィンドウにアタッチします:
```javascript
let onKeyDown = function (e) {
@ -221,13 +221,13 @@ npm start
window.addEventListener("keydown", onKeyDown);
```
この時点でブラウザのコンソールを確認し、キー入力がログに記録されるのを確認してください。
この時点でブラウザのコンソールを確認し、キー入力がログに記録されているか確認してください。
3. **[Pub sub パターン](../README.md) を実装する**: 残りの部分を進める際にコードを整理するためにこれを使用します。
3. **[Pub-Subパターン](../README.md)を実装**: これにより、残りの部分を進める際にコードをクリーンに保つことができます。
この最後の部分を行うには:
この最後の部分を行うには、以下を実行します
1. **ウィンドウにイベントリスナーを追加する**:
1. **ウィンドウにイベントリスナーを追加**:
```javascript
window.addEventListener("keyup", (evt) => {
@ -243,7 +243,7 @@ npm start
});
```
1. **EventEmitter クラスを作成する**: メッセージを発行および購読するために使用します:
1. **EventEmitterクラスを作成**: メッセージを発行および購読するために使用します:
```javascript
class EventEmitter {
@ -266,7 +266,7 @@ npm start
}
```
1. **定数を追加**し、EventEmitter を設定します
1. **定数を追加**し、EventEmitter をセットアップ
```javascript
const Messages = {
@ -285,7 +285,7 @@ npm start
eventEmitter = new EventEmitter();
```
1. **ゲームを初期化する**
1. **ゲームを初期化**:
```javascript
function initGame() {
@ -311,9 +311,9 @@ npm start
}
```
1. **ゲームループを設定する**
1. **ゲームループをセットアップ**
window.onload 関数をリファクタリングしてゲームを初期化し、適切な間隔でゲームループを設定します。また、レーザービームを追加します:
window.onload 関数をリファクタリングしてゲームを初期化し、適切な間隔でゲームループをセットアップします。また、レーザービームを追加します:
```javascript
window.onload = async () => {
@ -334,9 +334,9 @@ npm start
};
```
5. **敵を一定間隔で動かすコードを追加する**
5. **敵を一定間隔で動かすコードを追加**
`createEnemies()` 関数をリファクタリングして敵を作成し、新しい gameObjects クラスに追加します:
`createEnemies()` 関数をリファクタリングして敵を作成し、新しい gameObjects クラスにプッシュします:
```javascript
function createEnemies() {
@ -355,7 +355,7 @@ npm start
}
```
また、ヒーロー用に同様のプロセスを行う `createHero()` 関数を追加します。
そして、ヒーロー用に同様のプロセスを行う `createHero()` 関数を追加します。
```javascript
function createHero() {
@ -368,7 +368,7 @@ npm start
}
```
最後に、描画を開始する `drawGameObjects()` 関数を追加します:
最後に、`drawGameObjects()` 関数を追加して描画を開始します:
```javascript
function drawGameObjects(ctx) {
@ -382,7 +382,7 @@ npm start
## 🚀 チャレンジ
ご覧の通り、関数や変数、クラスを追加していくとコードが「スパゲッティコード」になりがちです。コードをより読みやすくするために、どのように整理すればよいかを考え、スケッチしてみてください。たとえコードが1つのファイルに収まっていても構いません
ご覧の通り、関数や変数、クラスを追加していくとコードが「スパゲッティコード」になりがちです。コードをより読みやすくするために、どのように整理すればよいか考えてみてください。たとえ1つのファイルに収まる場合でも、コードを整理するシステムをスケッチしてみましょう
## 講義後クイズ
@ -390,11 +390,13 @@ npm start
## 復習と自己学習
フレームワークを使用せずにゲームを作成していますが、ゲーム開発のためのJavaScriptベースのキャンバスフレームワークは多数存在します。これらについて[調べてみましょう](https://github.com/collections/javascript-game-engines)。
フレームワークを使用せずにゲームを作成していますが、JavaScriptベースのキャンバスフレームワークはゲーム開発に多く存在します。これらについて[調べてみてください](https://github.com/collections/javascript-game-engines)。
## 課題
[コードにコメントを追加する](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。元の言語で記載された文書が公式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。

@ -1,40 +1,40 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2e83e38c35dc003f046d7cc0bbfd4920",
"translation_date": "2025-08-23T23:01:56+00:00",
"original_hash": "a6ce295ff03bb49df7a3e17e6e7100a0",
"translation_date": "2025-08-28T17:52:53+00:00",
"source_file": "6-space-game/4-collision-detection/README.md",
"language_code": "ja"
}
-->
# 宇宙ゲームを作ろう パート4: レーザーの追加と衝突判定
# 宇宙ゲームを作ろう パート4: レーザーを追加して衝突を検出する
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/35)
このレッスンでは、JavaScriptを使ってレーザーを発射する方法を学びますゲームに以下の2つを追加します
このレッスンでは、JavaScriptを使ってレーザーを撃つ方法を学びますゲームに以下の2つを追加します
- **レーザー**: ヒーローの宇宙船から垂直に上方向へ発射されるレーザー
- **衝突判定**: *撃つ*機能を実装する一環として、以下のようなゲームルールを追加します:
- **レーザーが敵に当たる**: レーザーが敵に当たると敵が消滅
- **レーザーが画面上部に当たる**: レーザーが画面上部に到達すると消滅
- **敵とヒーローが衝突**: 敵とヒーローが衝突すると両方消滅
- **レーザー**: ヒーローの船から垂直に上方向へ発射されるレーザー
- **衝突検出**: *撃つ*機能を実装する一環として、以下のゲームルールを追加します:
- **レーザーが敵に命中**: レーザーが敵に当たると敵が消滅
- **レーザーが画面上部に命中**: レーザーが画面上部に到達すると消滅
- **敵とヒーローが衝突**: 敵とヒーローが衝突すると両方消滅
- **敵が画面下部に到達**: 敵が画面下部に到達すると敵とヒーローが消滅
つまり、あなた -- *ヒーロー* -- は敵が画面下部に到達する前にレーザーで全ての敵を倒す必要があります
つまり、あなた -- *ヒーロー* -- は敵が画面下部に到達する前にレーザーで全ての敵を倒さなければなりません
✅ 最初に作られたコンピュータゲームについて少し調べてみましょう。その機能はどのようなものでしたか?
✅ 最初に作られたコンピュータゲームについて少し調べてみましょう。その機能はどのようなものでしたか?
一緒にヒーローになりましょう!
## 衝突判定
## 衝突検出
衝突判定はどのように行うのでしょうか?ゲームオブジェクトを動く長方形として考える必要があります。なぜかというと、ゲームオブジェクトを描画するために使用される画像は長方形だからです:`x`、`y`、`width`、`height`を持っています。
衝突検出はどうやって行うのでしょうか?ゲームオブジェクトを動く矩形として考える必要があります。なぜかと言うと、ゲームオブジェクトを描画するために使用される画像は矩形だからです。矩形には `x`、`y`、`width`、`height` があります。
もし2つの長方形、例えばヒーローと敵が*交差*した場合、それは衝突が発生したことを意味します。その後に何が起こるべきかはゲームのルール次第です。衝突判定を実装するには以下が必要です:
もし2つの矩形、つまりヒーローと敵が*交差*した場合、それは衝突です。その後に何が起こるべきかはゲームのルール次第です。衝突検出を実装するには以下が必要です:
1. ゲームオブジェクトの長方形表現を取得する方法、例えば以下のようなもの:
1. ゲームオブジェクトの形表現を取得する方法、例えば以下のようなもの:
```javascript
rectFromGameObject() {
@ -60,14 +60,14 @@ CO_OP_TRANSLATOR_METADATA:
## 物を破壊する方法
ゲーム内で物を破壊するには、ゲームループでそのアイテムを描画しないようにする必要があります。これを行う方法の一つは、何かが起こったときにゲームオブジェクトを*死んだ*とマークすることです:
ゲーム内で物を破壊するには、ゲームにそのアイテムを一定間隔でトリガーされるゲームループで描画しないように指示する必要があります。その方法の一つは、何かが起こったときにゲームオブジェクトを*死んだ*とマークすることです。例えば以下のように
```javascript
// collision happened
enemy.dead = true
```
その後、*死んだ*オブジェクトを画面再描画の前に除外することができます
その後、画面を再描画する前に*死んだ*オブジェクトを整理することができます。例えば以下のように
```javascript
gameObjects = gameObject.filter(go => !go.dead);
@ -75,15 +75,15 @@ gameObjects = gameObject.filter(go => !go.dead);
## レーザーを発射する方法
レーザーを発射するには、キーイベントに応答して特定の方向に移動するオブジェクトを作成する必要があります。そのため、以下の手順を実行します:
レーザーを発射するには、キーイベントに応答して特定の方向に移動するオブジェクトを作成することを意味します。そのため、以下の手順を実行する必要があります:
1. **レーザーオブジェクトを作成**: ヒーローの宇宙船の上部から、作成と同時に画面上部に向かって移動を開始します。
2. **キーイベントにコードを紐付ける**: レーザー発射を表すキーボードのキーを選択します。
3. **レーザーのように見えるゲームオブジェクトを作成**: キーが押されたときに表示されるようにします
1. **レーザーオブジェクトを作成**: ヒーローの船の上部から作成され、作成時に画面上部に向かって移動を開始します。
2. **キーイベントにコードを紐付ける**: レーザーを撃つプレイヤーを表すキーボードのキーを選択する必要があります。
3. **レーザーのように見えるゲームオブジェクトを作成**: キーが押されたときに。
## レーザーのクールダウン
レーザーはキー(例えば*スペースキー*を押すたびに発射される必要があります。しかし、短時間で大量のレーザーが生成されるのを防ぐために、*クールダウン*と呼ばれるタイマーを実装します。これにより、レーザーは一定間隔でしか発射されなくなります。以下のように実装できます:
レーザーは例えば*スペースキー*を押すたびに発射される必要があります。しかし、短時間で大量のレーザーが生成されるのを防ぐために修正が必要です。この修正は、いわゆる*クールダウン*、つまりタイマーを実装することで、レーザーが一定間隔でしか発射されないようにすることです。以下の方法で実装できます:
```javascript
class Cooldown {
@ -109,23 +109,23 @@ class Weapon {
}
```
✅ 宇宙ゲームシリーズのレッスン1を参照して、*クールダウン*について復習しましょう
✅ 宇宙ゲームシリーズのレッスン1を参照して、*クールダウン*について思い出してください
## 作成するもの
前回のレッスンで作成したコード整理してリファクタリング済みのものを拡張します。パートIIのコードから始めるか、[パートIIIのスターターコード](../../../../../../../../../your-work)を使用してください。
前回のレッスンで整理してリファクタリングした既存のコードを使用して拡張します。パートIIのコードから始めるか、[Part III- starter](../../../../../../../../../your-work)のコードを使用してください。
> ヒント: 使用するレーザーはすでにアセットフォルダにあり、コードで参照されています。
> ヒント: 作業するレーザーはすでにアセットフォルダにあり、コードで参照されています。
- **衝突判定を追加**: レーザーが何かに衝突したとき、以下のルールが適用されます:
1. **レーザーが敵に当たる**: レーザーが敵に当たると敵が消滅
2. **レーザーが画面上部に当たる**: レーザーが画面上部に到達すると消滅
3. **敵とヒーローが衝突**: 敵とヒーローが衝突すると両方消滅
- **衝突検出を追加**: レーザーが何かに衝突した場合、以下のルールが適用されるべきです:
1. **レーザーが敵に命中**: レーザーが敵に当たると敵が消滅
2. **レーザーが画面上部に命中**: レーザーが画面上部に到達すると消滅
3. **敵とヒーローが衝突**: 敵とヒーローが衝突すると両方消滅
4. **敵が画面下部に到達**: 敵が画面下部に到達すると敵とヒーローが消滅
## 推奨手順
`your-work`サブフォルダに作成されたファイルを見つけてください。以下の内容が含まれているはずです:
`your-work` サブフォルダに作成されたファイルを見つけてください。以下が含まれているはずです:
```bash
-| assets
@ -137,18 +137,18 @@ class Weapon {
-| package.json
```
`your_work`フォルダで以下を入力してプロジェクトを開始します
プロジェクトを開始するには、`your_work` フォルダで以下を入力してください
```bash
cd your-work
npm start
```
上記のコマンドは、アドレス`http://localhost:5000`でHTTPサーバーを起動します。ブラウザを開いてそのアドレスを入力してください。現在のところ、ヒーローと全ての敵が表示されますが、まだ何も動いていません。
上記はHTTPサーバーをアドレス `http://localhost:5000` で開始します。ブラウザを開いてそのアドレスを入力してください。現在はヒーローと全ての敵が表示されるはずですが、まだ動いていません。
### コードを追加
1. **ゲームオブジェクトの長方形表現を設定して衝突を処理** 以下のコードは、`GameObject`の長方形表現を取得する方法を提供します。`GameObject`クラスを編集して拡張してください:
1. **ゲームオブジェクトの矩形表現を設定して衝突を処理する** 以下のコードは `GameObject` の矩形表現を取得する方法を提供します。`GameObject` クラスを編集して拡張してください:
```javascript
rectFromGameObject() {
@ -161,7 +161,7 @@ npm start
}
```
2. **衝突をチェックするコードを追加** これは2つの長方形が交差しているかをテストする新しい関数になります:
2. **衝突をチェックするコードを追加** これは2つの矩形が交差しているかどうかをテストする新しい関数になります:
```javascript
function intersectRect(r1, r2) {
@ -175,7 +175,7 @@ npm start
```
3. **レーザー発射機能を追加**
1. **キーイベントメッセージを追加** *スペースキー*がヒーローの宇宙船のすぐ上にレーザーを作成するようにします。Messagesオブジェクトに以下の3つの定数を追加してください
1. **キーイベントメッセージを追加**。*スペースキー*がヒーローの船のすぐ上にレーザーを作成するべきです。Messagesオブジェクトに3つの定数を追加してください
```javascript
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
@ -183,7 +183,7 @@ npm start
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
```
1. **スペースキーを処理** `window.addEventListener`のkeyup関数を編集してスペースキーを処理します
1. **スペースキーを処理**。`window.addEventListener` のkeyup関数を編集してスペースキーを処理してください
```javascript
} else if(evt.keyCode === 32) {
@ -191,7 +191,7 @@ npm start
}
```
1. **リスナーを追加** `initGame()`関数を編集して、スペースキーが押されたときにヒーローが発射できるようにします
1. **リスナーを追加**。`initGame()` 関数を編集して、スペースキーが押されたときにヒーローが発射できるようにしてください
```javascript
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
@ -200,7 +200,7 @@ npm start
}
```
また、敵がレーザーに衝突したときの動作を確保するために新しい`eventEmitter.on()`関数を追加します
また、敵がレーザーに衝突したときの動作を確保するために新しい `eventEmitter.on()` 関数を追加してください
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -209,7 +209,7 @@ npm start
})
```
1. **オブジェクトを移動** レーザーが徐々に画面上部に移動するようにします。これには、`GameObject`を拡張した新しいLaserクラスを作成します
1. **オブジェクトを移動**。レーザーが徐々に画面上部に移動するようにしてください。これまでと同様に `GameObject` を拡張する新しいLaserクラスを作成します
```javascript
class Laser extends GameObject {
@ -230,7 +230,7 @@ npm start
}
```
1. **衝突を処理** レーザーの衝突ルールを実装します。衝突するオブジェクトをテストする`updateGameObjects()`関数を追加します
1. **衝突を処理**。レーザーの衝突ルールを実装します。衝突するオブジェクトをテストする `updateGameObjects()` 関数を追加してください
```javascript
function updateGameObjects() {
@ -252,11 +252,11 @@ npm start
}
```
`updateGameObjects()`を`window.onload`のゲームループに追加することを忘れないでください。
`updateGameObjects()` `window.onload` のゲームループに追加することを忘れないでください。
4. **レーザーのクールダウンを実装** レーザーが一定間隔でしか発射されないようにします。
4. **レーザーのクールダウンを実装**レーザーが一定間隔でしか発射されないようにします。
最後に、ヒーロークラスを編集してクールダウンを可能にします
最後に、ヒーロークラスを編集してクールダウンできるようにしてください
```javascript
class Hero extends GameObject {
@ -285,13 +285,13 @@ npm start
}
```
これでゲームにいくつかの機能が追加されました!矢印キーで移動し、スペースキーでレーザーを発射し、敵に当たると消滅します。お疲れ様でした
これでゲームにいくつかの機能が追加されました!矢印キーで移動し、スペースキーでレーザーを発射し、敵に命中すると消えるようになりました。お疲れ様です
---
## 🚀 チャレンジ
爆発を追加してみましょう![Space Artリポジトリ](../../../../6-space-game/solution/spaceArt/readme.txt)のゲームアセットを確認し、レーザーがエイリアンに当たったときに爆発を追加してみてください。
爆発を追加してみましょう![Space Art repo](../../../../6-space-game/solution/spaceArt/readme.txt) のゲームアセットを確認して、レーザーがエイリアンに命中したときに爆発を追加してみてください。
## 講義後クイズ
@ -299,11 +299,13 @@ npm start
## 復習と自己学習
これまでのゲームの間隔を調整してみましょう。間隔を変更するとどうなるか試してみてください。[JavaScriptのタイミングイベント](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/)についてさらに学びましょう。
これまでのゲームの間隔を試してみましょう。間隔を変更するとどうなるか確認してください。[JavaScriptのタイミングイベント](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/)についてさらに学びましょう。
## 課題
[衝突を探る](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。

@ -1,23 +1,23 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4e8250db84b027c9ff816b4e4c093457",
"translation_date": "2025-08-23T22:52:59+00:00",
"original_hash": "adda95e02afa3fbee67b6e385b1109e1",
"translation_date": "2025-08-28T17:52:36+00:00",
"source_file": "6-space-game/5-keeping-score/README.md",
"language_code": "ja"
}
-->
# 宇宙ゲームを作ろう パート5: スコアとライフ
## 講義前クイズ
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/37)
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/37)
このレッスンでは、ゲームにスコアを追加し、ライフを計算する方法を学びます。
## 画面にテキストを描画する
ゲームのスコアを画面に表示するには、テキストを画面に配置する方法を知る必要があります。その答えは、canvasオブジェクトの`fillText()`メソッドを使用することです。また、使用するフォントテキストの色、さらにはテキストの配置(左揃え、右揃え、中央揃え)など、他の要素も制御できます。以下は、画面にテキストを描画するコード例です。
ゲームのスコアを画面に表示するには、テキストを画面に配置する方法を知る必要があります。その答えは、キャンバスオブジェクトの`fillText()`メソッドを使用することです。また、使用するフォントテキストの色、さらにはテキストの配置(左揃え、右揃え、中央揃え)なども制御できます。以下は、画面にテキストを描画するコード例です。
```javascript
ctx.font = "30px Arial";
@ -26,18 +26,18 @@ ctx.textAlign = "right";
ctx.fillText("show this on the screen", 0, 0);
```
✅ [キャンバスにテキストを追加する方法](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text)についてさらに学び、自分のテキストをもっと魅力的にしてみましょう!
✅ [キャンバスにテキストを追加する方法](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text)についてさらに詳しく学び、自分のゲームをもっと魅力的にしてみましょう!
## ゲームの概念としてのライフ
## ゲームコンセプトとしてのライフ
ゲームにおけるライフの概念は単なる数字です。宇宙ゲームの文脈では、ダメージを受けるたびに1つずつ減るライフを設定するのが一般的です。数字ではなく、ミニシップやハートのようなグラフィックで表現すると、より視覚的にわかりやすくなります。
ゲームにおけるライフの概念は単なる数字です。宇宙ゲームの文脈では、ダメージを受けるたびに1つずつ減るライフを設定するのが一般的です。数字ではなく、ミニシップやハートのようなグラフィカルな表現を表示すると、より分かりやすくなります。
## 作成するもの
ゲームに以下を追加しましょう:
- **ゲームスコア**: 敵の船を1隻撃破するごとに、ヒーローにポイントが与えられます。1隻につき100ポイントを提案します。ゲームスコアは画面の左下に表示されます。
- **ライフ**: 自分の船には3つのライフがあります。敵の船が衝突するたびにライフが1つ減ります。ライフスコアは画面の右下に表示され、以下のグラフィックで構成されます ![ライフ画像](../../../../6-space-game/5-keeping-score/solution/assets/life.png)。
- **ライフ**: 自分の船には3つのライフがあります。敵の船が衝突するたびにライフが1つ減ります。ライフスコアは画面の右下に表示され、以下のグラフィックで構成されます ![life image](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.ja.png)。
## 推奨手順
@ -53,18 +53,18 @@ ctx.fillText("show this on the screen", 0, 0);
-| package.json
```
`your_work`フォルダでプロジェクトを開始するには、以下を入力します
`your_work`フォルダでプロジェクトを開始するには、以下を入力してください
```bash
cd your-work
npm start
```
上記のコマンドでHTTPサーバーが`http://localhost:5000`で起動します。ブラウザを開き、そのアドレスを入力してください。現在のところ、ヒーローとすべての敵が表示され、左右の矢印キーを押すとヒーローが移動し、敵を撃つことができます。
上記のコマンドでHTTPサーバーが`http://localhost:5000`で起動します。ブラウザを開き、そのアドレスを入力してください。現在の状態では、ヒーローとすべての敵が表示され、左右の矢印キーを押すとヒーローが移動し、敵を撃つことができます。
### コードを追加する
1. **必要なアセットをコピー**します。`solution/assets/`フォルダから`your-work`フォルダに`life.png`アセットを追加します。`window.onload`関数に`lifeImg`を追加してください:
1. **必要なアセットをコピーする**: `solution/assets/`フォルダから`your-work`フォルダに`life.png`アセットをコピーします。`window.onload`関数に`lifeImg`を追加してください:
```javascript
lifeImg = await loadTexture("assets/life.png");
@ -80,9 +80,9 @@ npm start
eventEmitter = new EventEmitter();
```
2. **変数を追加**します。合計スコア0と残りのライフ3を表すコードを追加し、これらのスコアを画面に表示します。
2. **変数を追加する**: 合計スコア0と残りのライフ3を表すコードを追加し、これらのスコアを画面に表示します。
3. **`updateGameObjects()`関数を拡張**します。敵との衝突を処理するように`updateGameObjects()`関数を拡張します:
3. **`updateGameObjects()`関数を拡張する**: `updateGameObjects()`関数を拡張して敵との衝突を処理します:
```javascript
enemies.forEach(enemy => {
@ -93,15 +93,15 @@ npm start
})
```
4. **ライフとポイントを追加**します。
1. **変数を初期化**します。`Hero`クラスの`this.cooldown = 0`の下にライフとポイントを設定します:
4. **ライフとポイントを追加する**:
1. **変数を初期化する**: `Hero`クラスの`this.cooldown = 0`の下にライフとポイントを設定します:
```javascript
this.life = 3;
this.points = 0;
```
1. **変数を画面に描画**します。これらの値を画面に描画します:
1. **変数を画面に描画する**: これらの値を画面に描画します:
```javascript
function drawLife() {
@ -128,18 +128,18 @@ npm start
```
1. **ゲームループにメソッドを追加**します。これらの関数を`window.onload`関数の`updateGameObjects()`の下に追加してください:
1. **ゲームループにメソッドを追加する**: `updateGameObjects()`の下にこれらの関数を`window.onload`関数に追加してください:
```javascript
drawPoints();
drawLife();
```
1. **ゲームルールを実装**します。以下のゲームルールを実装します:
1. **ゲームルールを実装する**: 以下のゲームルールを実装します:
1. **ヒーローと敵の衝突ごとに**、ライフを1つ減らします。
1. **ヒーローと敵の衝突ごとにライフを減らす**:
`Hero`クラスを拡張してこの減算を行います:
`Hero`クラスを拡張してライフを減らす処理を追加します:
```javascript
decrementLife() {
@ -150,9 +150,9 @@ npm start
}
```
2. **レーザーが敵に当たるごとに**、ゲームスコアを100ポイント増やします。
2. **レーザーが敵に当たるごとにゲームスコアを100ポイント増やす**:
`Hero`クラスを拡張してこの加算を行います:
`Hero`クラスを拡張してスコアを増やす処理を追加します:
```javascript
incrementPoints() {
@ -177,7 +177,7 @@ npm start
✅ JavaScript/Canvasで作られた他のゲームを調べてみましょう。それらの共通点は何でしょうか
この作業が終わると、画面の右下に小さな「ライフ」シップが表示され、左下にポイントが表示されます。また、敵と衝突するとライフが減り、敵を撃つとポイントが増えるのが確認できるはずです。よくできました!ゲームはほぼ完成です。
この作業が終わると、画面の右下に小さな「ライフ」シップが表示され、左下にポイントが表示されます。敵と衝突するとライフが減り、敵を撃つとポイントが増えるのが確認できるはずです。よくできました!ゲームはほぼ完成です。
---
@ -185,17 +185,19 @@ npm start
コードはほぼ完成しています。次のステップを想像できますか?
## 講義後クイズ
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/38)
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/38)
## 復習と自己学習
ゲームスコアとライフを増減させる方法をいくつか調べてみましょう。[PlayFab](https://playfab.com)のような興味深いゲームエンジンがあります。これらを使用することでゲームがどのように向上するか考えてみましょう
ゲームスコアとライフを増減させる方法をいくつか調べてみましょう。[PlayFab](https://playfab.com)のような興味深いゲームエンジンがあります。これらを使用することでゲームがどのように向上するか考えてみてください
## 課題
[スコアリングゲームを作る](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解について、当社は責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてご参照ください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "01336cddd638242e99b133614111ea40",
"translation_date": "2025-08-23T23:07:57+00:00",
"original_hash": "05be6c37791668e3719c4fba94566367",
"translation_date": "2025-08-28T17:53:40+00:00",
"source_file": "6-space-game/6-end-condition/README.md",
"language_code": "ja"
}
@ -13,29 +13,29 @@ CO_OP_TRANSLATOR_METADATA:
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/39)
ゲームにおける「終了条件」を表現する方法はいくつかあります。ゲームの制作者であるあなたが、ゲームが終了する理由を決めることができます。これまで作成してきた宇宙ゲームを例にすると、以下のような理由が考えられます:
ゲームの「終了条件」を表現する方法はいくつかあります。ゲームの制作者として、なぜゲームが終了したのかを決めるのはあなた次第です。これまで作ってきた宇宙ゲームを例にすると、以下のような理由が考えられます:
- **`N` 隻の敵船を破壊した場合**: ゲームを異なるレベルに分ける場合、`N` 隻の敵船を破することでレベルをクリアするというのはよくあるパターンです。
- **自分の船が破壊された場合**: 自分の船が破壊されるとゲームオーバーになるゲームもあります。別の一般的な方法として「ライフ」の概念があります。自分の船が破壊されるたびにライフが減り、すべてのライフを失うとゲームオーバーになります。
- **`N` ポイントを獲得した場合**: ポイントを集めることが終了条件になることもあります。ポイントの獲得方法は自由ですが、敵船を破したり、破壊されたアイテムが落とすものを集めたりすることでポイントを得るのが一般的です。
- **レベルをクリアした場合**: これには、`X` 隻の敵船を破壊する、`Y` ポイントを集める、特定のアイテムを集めるなど、複数の条件が含まれる場合があります。
- **`N` 隻の敵船を破**: ゲームをレベルごとに分ける場合、`N` 隻の敵船を破することでレベルをクリアするというのはよくあるパターンです。
- **自分の船が破壊された**: 自分の船が破壊されるとゲームオーバーになるゲームもあります。もう一つの一般的な方法は「ライフ」の概念を導入することです。自分の船が破壊されるたびにライフが減り、すべてのライフを失うとゲームオーバーになります。
- **`N` ポイントを獲得**: ポイントを集めることが終了条件になることもあります。ポイントの獲得方法は自由ですが、敵船を破したり、破壊されたアイテムが落とすものを集めたりすることでポイントを得るのが一般的です。
- **レベルをクリア**: これには、`X` 隻の敵船を撃破、`Y` ポイントを獲得、特定のアイテムを収集するなど、複数の条件が含まれる場合があります。
## 再スタート
ゲームを楽しんでくれる人は、再びプレイしたいと思うでしょう。どのような理由でゲームが終了したとしても、再スタートの選択肢を提供するべきです。
ゲームを楽しんでくれる人がいれば、再プレイしたいと思うはずです。ゲームがどんな理由で終了したとしても、再スタートの選択肢を提供するべきです。
✅ ゲームがどのような条件で終了し、どのように再スタートを促されるかを少し考えてみましょう。
✅ ゲームが終了する条件と、再スタートを促される方法について少し考えてみましょう。
## 作成する内容
以下のルールをゲームに追加します:
1. **ゲームの勝利条件**: すべての敵船を破壊するとゲームに勝利します。また、勝利メッセージを表示します
1. **再スタート**: すべてのライフを失った場合やゲームに勝利した場合、ゲームを再スタートする方法を提供します。注意! ゲームを再初期化し、前回のゲーム状態をクリアする必要があります。
1. **ゲームの勝利条件**: 敵船をすべて撃破するとゲームに勝利します。また、勝利メッセージを表示してください
1. **再スタート**: ライフをすべて失った場合やゲームに勝利した場合、ゲームを再スタートする方法を提供してください。注意!ゲームを再初期化し、以前のゲーム状態をクリアする必要があります。
## 推奨手順
`your-work` サブフォルダに作成済みのファイルを見つけてください。以下の内容が含まれているはずです:
`your-work` サブフォルダに作成されたファイルを確認してください。以下の内容が含まれているはずです:
```bash
-| assets
@ -48,20 +48,20 @@ CO_OP_TRANSLATOR_METADATA:
-| package.json
```
`your_work` フォルダでプロジェクトを開始するには、以下を入力します
プロジェクトを開始するには、`your_work` フォルダで以下を入力してください
```bash
cd your-work
npm start
```
上記のコマンドで、アドレス `http://localhost:5000` でHTTPサーバーが起動します。ブラウザを開き、そのアドレスを入力してください。ゲームがプレイ可能な状態になっているはずです。
上記のコマンドで、`http://localhost:5000` アドレスでHTTPサーバーが起動します。ブラウザを開き、そのアドレスを入力してください。ゲームがプレイ可能な状態になっているはずです。
> ヒント: Visual Studio Codeで警告を避けるに、`window.onload` 関数を編集して `gameLoopId` をそのまま呼び出し(`let` を付けずに)、ファイルの先頭で `let gameLoopId;`独立して宣言してください。
> ヒント: Visual Studio Codeで警告を避けるために、`window.onload` 関数を編集して `gameLoopId` をそのまま呼び出し(`let` を付けずに)、ファイルの先頭で独立して `let gameLoopId;` を宣言してください。
### コードを追加する
### コードを追加
1. **終了条件を追跡する**: 敵の数やヒーロー船が破壊されたかどうかを追跡するコードを追加します。以下の2つの関数を追加してください
1. **終了条件を追跡**: 敵の数やヒーロー船が破壊されたかどうかを追跡するコードを追加します。以下の2つの関数を追加してください
```javascript
function isHeroDead() {
@ -74,7 +74,7 @@ npm start
}
```
1. **メッセージハンドラーにロジックを追加する**: `eventEmitter` を編集して、以下の条件を処理します:
1. **メッセージハンドラーにロジックを追加**: `eventEmitter` を編集してこれらの条件を処理します:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -108,16 +108,16 @@ npm start
});
```
1. **新しいメッセージタイプを追加する**: 以下のメッセージを constants オブジェクトに追加します
1. **新しいメッセージタイプを追加**: 以下のメッセージをconstantsオブジェクトに追加してください
```javascript
GAME_END_LOSS: "GAME_END_LOSS",
GAME_END_WIN: "GAME_END_WIN",
```
2. **再スタートコードを追加する**: 選択したボタンを押すことでゲームを再スタートするコードを追加します。
2. **再スタートコードを追加**: 選択したボタンを押すことでゲームを再スタートするコードを追加します。
1. **`Enter` キーの押下をリッスンする**: ウィンドウの eventListener を編集して、このキー押下をリッスンします:
1. **キー押下 `Enter` を監視**: ウィンドウのeventListenerを編集してこのキー押下を監視します:
```javascript
else if(evt.key === "Enter") {
@ -125,15 +125,15 @@ npm start
}
```
1. **再スタートメッセージを追加する**: 以下のメッセージを Messages 定数に追加します
1. **再スタートメッセージを追加**: 以下のメッセージをMessages定数に追加してください
```javascript
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
```
1. **ゲームルールを実装する**: 以下のゲームルールを実装します:
1. **ゲームルールを実装**: 以下のゲームルールを実装します:
1. **プレイヤーの勝利条件**: すべての敵船が破壊されたとき、勝利メッセージを表示します。
1. **プレイヤーの勝利条件**: 敵船をすべて撃破したら、勝利メッセージを表示します。
1. まず、`displayMessage()` 関数を作成します:
@ -171,7 +171,7 @@ npm start
}
```
1. **再スタートロジック**: すべてのライフを失った場合やプレイヤーがゲームに勝利した場合、再スタート可能であることを表示します。また、再スタートキーが押されたときにゲームを再スタートします(どのキーを再スタートに割り当てるかは自由です)。
1. **再スタートロジック**: ライフをすべて失った場合やプレイヤーがゲームに勝利した場合、再スタート可能であることを表示します。また、再スタートキーが押されたときにゲームを再スタートします(どのキーを再スタートに割り当てるかは自由です)。
1. `resetGame()` 関数を作成します:
@ -194,7 +194,7 @@ npm start
}
```
1. `initGame()` 内で `eventEmitter` を呼び出してゲームをリセットコードを追加します:
1. `initGame()` 内でゲームをリセットするために `eventEmitter` を呼び出すコードを追加します:
```javascript
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
@ -202,7 +202,7 @@ npm start
});
```
1. EventEmitter `clear()` 関数を追加します:
1. EventEmitterに `clear()` 関数を追加します:
```javascript
clear() {
@ -216,7 +216,7 @@ npm start
## 🚀 チャレンジ
音を追加してみましょう!レーザーが命中したとき、ヒーローが死んだとき、または勝利したときに音を追加してゲームプレイを強化できますかJavaScriptで音を再生する方法を学ぶには、この [サンドボックス](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) を見てみましょう
音を追加してみましょう!レーザーが命中したとき、ヒーローが死んだとき、または勝利したときなど、ゲームプレイを盛り上げる音を追加できますかJavaScriptで音を再生する方法については、こちらの [サンドボックス](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) を参考にしてください
## 講義後クイズ
@ -224,11 +224,13 @@ npm start
## 復習と自己学習
新しいサンプルゲームを作成することが課題です。どのようなゲームを作るかを考えるために、興味深いゲームをいくつか探してみましょう。
新しいサンプルゲームを作成する課題がありますので、興味深いゲームをいくつか探索して、どのようなゲームを作るか考えてみましょう。
## 課題
[サンプルゲームを作成する](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された原文が公式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "8da1b5e2c63f749808858c53f37b8ce7",
"translation_date": "2025-08-24T00:08:35+00:00",
"original_hash": "8a07db14e75ac62f013b7de5df05981d",
"translation_date": "2025-08-28T17:48:06+00:00",
"source_file": "7-bank-project/1-template-route/README.md",
"language_code": "ja"
}
-->
# 銀行アプリを作成する Part 1: HTMLテンプレートとWebアプリのルート
# 銀行アプリを作成する Part 1: HTMLテンプレートとWebアプリのルート設定
## 講義前クイズ
@ -15,17 +15,17 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
ブラウザでJavaScriptが登場して以来、ウェブサイトはこれまで以上にインタラクティブで複雑になっています。現在では、ブラウザ内で直接動作する完全な機能を備えたアプリケーション、いわゆる[ウェブアプリケーション](https://en.wikipedia.org/wiki/Web_application)を作成するためにウェブ技術が一般的に使用されています。ウェブアプリは非常にインタラクティブであるため、ユーザーはアクションを実行するたびにページ全体をリロードするのを待ちたくありません。そのため、JavaScriptを使用してDOMを介してHTMLを直接更新し、スムーズなユーザー体験を提供します。
ブラウザでJavaScriptが登場して以来、ウェブサイトはこれまで以上にインタラクティブで複雑になっています。現在では、ブラウザ内で直接動作する完全な機能を備えたアプリケーション、つまり[ウェブアプリケーション](https://en.wikipedia.org/wiki/Web_application)を作成するためにウェブ技術が一般的に使用されています。ウェブアプリは非常にインタラクティブであるため、ユーザーはアクションを実行するたびにページ全体をリロードするのを待ちたくありません。そのため、JavaScriptを使用してDOMを介してHTMLを直接更新し、スムーズなユーザー体験を提供します。
このレッスンでは、HTMLテンプレートを使用して複数の画面を作成し、HTMLページ全体をリロードすることなく表示および更新できる銀行ウェブアプリの基礎を構築します。
### 前提条件
このレッスンで作成するウェブアプリをテストするためにローカルウェブサーバーが必要です。まだインストールしていない場合は、[Node.js](https://nodejs.org)をインストールし、プロジェクトフォルダーで`npx lite-server`コマンドを使用してください。これによりローカルウェブサーバーが作成され、ブラウザでアプリが開きます。
このレッスンで作成するウェブアプリをテストするには、ローカルウェブサーバーが必要です。まだインストールしていない場合は、[Node.js](https://nodejs.org)をインストールし、プロジェクトフォルダーでコマンド `npx lite-server` を使用してください。これによりローカルウェブサーバーが作成され、ブラウザでアプリが開きます。
### 準備
コンピューター上に`bank`という名前のフォルダーを作成し、その中に`index.html`という名前のファイルを作成してください。このHTMLの[ボイラープレート](https://en.wikipedia.org/wiki/Boilerplate_code)から始めます:
コンピュータ上で、`bank`という名前のフォルダーを作成し、その中に`index.html`という名前のファイルを作成してください。以下のHTML[ボイラープレート](https://en.wikipedia.org/wiki/Boilerplate_code)から始めます:
```html
<!DOCTYPE html>
@ -47,14 +47,14 @@ CO_OP_TRANSLATOR_METADATA:
ウェブページに複数の画面を作成したい場合、1つの画面ごとにHTMLファイルを作成するという方法があります。しかし、この方法にはいくつかの不便があります
- 画面を切り替えるたびにHTML全体をリロードする必要があり、これが遅くなる可能性があります。
- 画面を切り替えるたびにHTML全体をリロードする必要があり、これが遅い場合があります。
- 異なる画面間でデータを共有するのが難しいです。
別の方法として、1つのHTMLファイルだけを使用し、`<template>`要素を使用して複数の[HTMLテンプレート](https://developer.mozilla.org/docs/Web/HTML/Element/template)を定義する方法があります。テンプレートはブラウザによって表示されない再利用可能なHTMLブロックであり、JavaScriptを使用して実行時にインスタンス化する必要があります。
### タスク
ログインページとダッシュボードの2つの画面を持つ銀行アプリを作成します。まず、HTMLのボディにアプリの異なる画面をインスタンス化するためのプレースホルダー要素を追加します:
銀行アプリを作成し、ログインページとダッシュボードの2つの画面を用意します。まず、HTMLのボディ内にアプリの異なる画面をインスタンス化するためのプレースホルダー要素を追加します:
```html
<div id="app">Loading...</div>
@ -64,7 +64,7 @@ JavaScriptで後で簡単に見つけられるように`id`を付けています
> ヒント:この要素の内容は置き換えられるため、アプリが読み込まれている間に表示されるローディングメッセージやインジケーターを入れることができます。
次に、ログインページのHTMLテンプレートを追加します。ここではタイトルと、ナビゲーションを実行するためのリンクを含むセクションだけを入れます。
次に、ログインページ用のHTMLテンプレートを追加します。現時点では、タイトルとナビゲーションを実行するためのリンクを含むセクションだけを入れます。
```html
<template id="login">
@ -75,11 +75,11 @@ JavaScriptで後で簡単に見つけられるように`id`を付けています
</template>
```
次に、ダッシュボードページのHTMLテンプレートを追加します。このページには以下のセクションが含まれます
その後、ダッシュボードページ用のHTMLテンプレートを追加します。このページには以下のセクションが含まれます
- タイトルとログアウトリンクを含むヘッダー
- 銀行口座の現在の残高
- トランザクションのリスト(テーブルで表示)
- テーブルで表示される取引のリスト
```html
<template id="dashboard">
@ -114,11 +114,11 @@ JavaScriptで後で簡単に見つけられるように`id`を付けています
現在のHTMLファイルをブラウザで試してみると、`Loading...`の表示で止まってしまいます。これは、HTMLテンプレートをインスタンス化して表示するためのJavaScriptコードが必要だからです。
テンプレートのインスタンス化は通常以下の3ステップで行われます:
テンプレートをインスタンス化する手順は通常以下の3ステップです:
1. DOM内でテンプレート要素を取得す(例:[`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById)を使用)。
2. テンプレート要素を[`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode)を使用して複製す
3. 表示可能な要素の下にテンプレートをDOMに追加する(例:[`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild)を使用)。
1. DOM内でテンプレート要素を取得します(例:[`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById)を使用)。
2. テンプレート要素を[`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode)を使用して複製します。
3. 可視要素の下にテンプレートをDOMに追加します(例:[`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild)を使用)。
✅ なぜテンプレートをDOMに追加する前に複製する必要があるのでしょうかこのステップを省略した場合、何が起こると思いますか
@ -142,9 +142,9 @@ function updateRoute(templateId) {
}
```
ここで行っているのは、上記の3ステップそのものです。`templateId`を持つテンプレートをインスタンス化し、その複製された内容をアプリのプレースホルダー内に配置します。`cloneNode(true)`を使用してテンプレートのサブツリー全体をコピーする必要があることに注意してください
ここで行っているのは、上記の3ステップそのものです。`templateId`を持つテンプレートをインスタンス化し、その複製された内容をアプリのプレースホルダー内に配置します。テンプレート全体のサブツリーをコピーするために`cloneNode(true)`を使用する必要があります
次に、この関数をテンプレートの1つで呼び出し、結果を確認します
次に、この関数をテンプレートの1つで呼び出し、結果を確認してください
```js
updateRoute('login');
@ -170,11 +170,11 @@ https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
```
しかし、今回のウェブアプリではすべての画面を含む単一のHTMLファイルを使用しているため、このデフォルトの動作は役に立ちません。これを手動でマッピングし、JavaScriptを使用して表示されるテンプレートを更新する必要があります。
しかし、今回のウェブアプリではすべての画面を含む単一のHTMLファイルを使用しているため、このデフォルトの動作は役に立ちません。これを手動でマッピングし、JavaScriptを使用して表示されるテンプレートを更新する必要があります。
### タスク
URLパスとテンプレートをマッピングするために、シンプルなオブジェクトを使用します。このオブジェクトを`app.js`ファイルの頭に追加してください。
URLパスとテンプレートをマッピングするために、シンプルなオブジェクトを使用します。このオブジェクトを`app.js`ファイルの頭に追加してください。
```js
const routes = {
@ -183,7 +183,7 @@ const routes = {
};
```
次に、`updateRoute`関数を少し変更します。直接`templateId`を引数として渡すのではなく、まず現在のURLを確認し、その後マップを使用して対応するテンプレートID値を取得します。[`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname)を使用してURLからパスセクションだけを取得できます。
次に、`updateRoute`関数を少し変更します。引数として直接`templateId`を渡す代わりに、まず現在のURLを確認し、その後マップを使用して対応するテンプレートID値を取得します。[`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname)を使用してURLからパスセクションだけを取得できます。
```js
function updateRoute() {
@ -204,16 +204,16 @@ function updateRoute() {
## ナビゲーションの追加
次に、URLを手動で変更することなくページ間を移動できる機能をアプリに追加します。これには以下の2つのことが含まれます:
次に、URLを手動で変更することなくページ間を移動できるようにします。これには以下の2つのことが必要です:
1. 現在のURLを更新する
2. 新しいURLに基づいて表示されるテンプレートを更新する
2番目の部分については`updateRoute`関数で既に対応済みなので、現在のURLを更新する方法を考える必要があります。
2番目の部分については`updateRoute`関数で既に対応しているため、現在のURLを更新する方法を考える必要があります。
JavaScript、特に[`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState)を使用し、HTMLをリロードせずにURLを更新し、ブラウザ履歴に新しいエントリを作成ます。
JavaScript、特に[`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState)を使用します。このメソッドは、HTMLをリロードせずにURLを更新し、ブラウザ履歴に新しいエントリを作成することができます。
> 注HTMLアンカー要素[`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a)は単独で異なるURLへのハイパーリンクを作成できますが、デフォルトでブラウザがHTMLをリロードしてしまいます。カスタムJavaScriptでルーティングを処理する際には、クリックイベントで`preventDefault()`関数を使用してこの動作を防ぐ必要があります。
> 注HTMLアンカー要素[`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a)は単独で異なるURLへのハイパーリンクを作成できますが、デフォルトでブラウザがHTMLをリロードしてしまいます。`preventDefault()`関数をクリックイベントで使用してこの動作を防ぐ必要があります。
### タスク
@ -226,9 +226,9 @@ function navigate(path) {
}
```
このメソッドは、与えられたパスに基づいて現在のURLを最初に更新し、その後テンプレートを更新します。`window.location.origin`プロパティはURLのルートを返し、与えられたパスから完全なURLを再構築することができます。
このメソッドは、与えられたパスに基づいて現在のURLを更新し、その後テンプレートを更新します。`window.location.origin`プロパティはURLのルートを返し、与えられたパスから完全なURLを再構築することができます。
この関数ができたので、パスが定義されたルートに一致しない場合の問題に対処します。`updateRoute`関数を変更し、マッチが見つからない場合に既存のルートの1つにフォールバックするようにします。
この関数ができたので、定義されたルートに一致しないパスがある場合の問題に対処します。`updateRoute`関数を変更し、マッチが見つからない場合に既存のルートの1つにフォールバックするようにします。
```js
function updateRoute() {
@ -265,7 +265,7 @@ function onLinkClick(event) {
[`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick)属性を使用して`click`イベントをJavaScriptコードにバインドします。ここでは`navigate()`関数の呼び出しです。
これらのリンクをクリックしてみてください。アプリの異なる画面間を移動できるようになっているはずです。
これらのリンクをクリックしてみてください。アプリの異なる画面間を移動できるようになっはずです。
`history.pushState`メソッドはHTML5標準の一部であり、[すべての最新ブラウザ](https://caniuse.com/?search=pushState)で実装されています。古いブラウザ向けにウェブアプリを構築する場合、このAPIの代わりに使用できるトリックがありますパスの前に[ハッシュ(`#`](https://en.wikipedia.org/wiki/URI_fragment)を使用することで、通常のアンカーナビゲーションで動作し、ページをリロードしないルーティングを実装できます。このハッシュはページ内の内部リンクを作成する目的で使用されていました。
@ -273,7 +273,7 @@ function onLinkClick(event) {
`history.pushState`を使用すると、ブラウザのナビゲーション履歴に新しいエントリが作成されます。ブラウザの*戻るボタン*を長押しすると、以下のようなものが表示されるはずです:
![ナビゲーション履歴のスクリーンショット](../../../../7-bank-project/1-template-route/history.png)
![ナビゲーション履歴のスクリーンショット](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.ja.png)
戻るボタンを数回クリックしてみると、現在のURLが変更され履歴が更新されますが、同じテンプレートが表示され続けます。
@ -281,7 +281,7 @@ function onLinkClick(event) {
### タスク
ブラウザ履歴が変更されたときに表示されるテンプレートが更新されるようにするため、`updateRoute()`を呼び出す新しい関数を追加します。これを`app.js`ファイルの最後に追加します:
ブラウザ履歴が変更されたときに表示されるテンプレートが更新されるようにするため、`updateRoute()`を呼び出す新しい関数を追加します。これを`app.js`ファイルの末尾に追加します:
```js
window.onpopstate = () => updateRoute();
@ -290,7 +290,7 @@ updateRoute();
> 注:ここでは簡潔さのために[アロー関数](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions)を使用して`popstate`イベントハンドラーを宣言しましたが、通常の関数でも同じように動作します。
アロー関数についての復習動画はこちら:
アロー関数についてのリフレッシュ動画はこちら:
[![アロー関数](https://img.youtube.com/vi/OP6eEbOj2sc/0.jpg)](https://youtube.com/watch?v=OP6eEbOj2sc "アロー関数")
@ -302,7 +302,7 @@ updateRoute();
## 🚀 チャレンジ
このアプリのクレジットを表示する3番目のページ用の新しいテンプレートとルートを追加してください。
このアプリのクレジットを表示するための3番目のページ用の新しいテンプレートとルートを追加してください。
## 講義後クイズ
@ -316,5 +316,7 @@ updateRoute();
[ルーティングを改善する](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてご参照ください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は責任を負いません。

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b667b7d601e2ee19acb5aa9d102dc9f3",
"translation_date": "2025-08-23T23:59:19+00:00",
"original_hash": "8baca047d77a5f43fa4099c0578afa42",
"translation_date": "2025-08-28T17:46:25+00:00",
"source_file": "7-bank-project/2-forms/README.md",
"language_code": "ja"
}
-->
# 銀行アプリを作成する Part 2: ログインと登録フォームを作成
# 銀行アプリを作成する Part 2: ログインと登録フォームを作成する
## 講義前のクイズ
@ -15,13 +15,13 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
ほとんどの現代的なウェブアプリでは、アカウントを作成して自分専用のスペースを持つことができます。複数のユーザーが同時にウェブアプリにアクセスできるため、各ユーザーの個人データを別々に保存し、どの情報を表示するかを選択する仕組みが必要です。[ユーザーの身元を安全に管理する方法](https://en.wikipedia.org/wiki/Authentication)については、非常に広範なトピックであるためここでは扱いませんが、各ユーザーが1つまたは複数の銀行口座をアプリ内で作成できるようにします。
ほとんどの現代的なウェブアプリでは、アカウントを作成して自分専用のスペースを持つことができます。複数のユーザーが同時にウェブアプリにアクセスできるため、各ユーザーの個人データを別々に保存し、表示する情報を選択する仕組みが必要です。[ユーザーの身元を安全に管理する](https://en.wikipedia.org/wiki/Authentication)方法については、非常に広範なトピックであるためここでは扱いませんが、各ユーザーがアプリ内で1つ以上の銀行口座を作成できるようにします。
このパートでは、HTMLフォームを使用してウェブアプリにログインと登録機能を追加します。データをサーバーAPIにプログラム的に送信する方法や、ユーザー入力に対する基本的な検証ルールを定義する方法を学びます。
### 前提条件
このレッスンを進めるには、ウェブアプリの[HTMLテンプレートとルーティング](../1-template-route/README.md)を完了している必要があります。また、[Node.js](https://nodejs.org)をインストールし、[サーバーAPIをローカルで実行](../api/README.md)して、アカウントを作成するためのデータを送信できるようにする必要があります。
このレッスンは、ウェブアプリの[HTMLテンプレートとルーティング](../1-template-route/README.md)を完了している必要があります。また、[Node.js](https://nodejs.org)をインストールし、[サーバーAPIをローカルで実行](../api/README.md)して、アカウントを作成するためのデータを送信できるようにする必要があります。
**注意**
以下の2つのターミナルを同時に実行する必要があります。
@ -43,15 +43,15 @@ curl http://localhost:5000/api
`<form>`要素は、ユーザーがインタラクティブなコントロールを使用してデータを入力および送信できるHTMLドキュメントのセクションをカプセル化します。フォーム内で使用できるユーザーインターフェースUIコントロールはさまざまで、最も一般的なものは`<input>`と`<button>`要素です。
`<input>`には多くの異なる[タイプ](https://developer.mozilla.org/docs/Web/HTML/Element/input)があります。たとえば、ユーザー名を入力するフィールドを作成するには以下のようにします。
`<input>`には多くの異なる[タイプ](https://developer.mozilla.org/docs/Web/HTML/Element/input)があります。たとえば、ユーザー名を入力するフィールドを作成するには以下を使用します。
```html
<input id="username" name="username" type="text">
```
`name`属性は、フォームデータが送信される際プロパティ名として使用されます。`id`属性は、`<label>`をフォームコントロールに関連付けるために使用されます。
`name`属性は、フォームデータが送信される際プロパティ名として使用されます。`id`属性は、`<label>`をフォームコントロールに関連付けるために使用されます。
> [`<input>`タイプ](https://developer.mozilla.org/docs/Web/HTML/Element/input)や[その他のフォームコントロール](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls)のリストを確認して、UIを構築する際に使用できるネイティブUI要素を理解してください。
> [`<input>`タイプ](https://developer.mozilla.org/docs/Web/HTML/Element/input)や[その他のフォームコントロール](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls)のリストを確認して、UIを構築する際に使用できるネイティブUI要素を理解してください。
`<input>`は[空要素](https://developer.mozilla.org/docs/Glossary/Empty_element)であり、対応する閉じタグを追加してはいけません。ただし、自己閉じタグ`<input/>`の記法を使用することはできますが、必須ではありません。
@ -79,12 +79,12 @@ curl http://localhost:5000/api
</template>
```
よく見ると、ここに`<label>`要素も追加されていることがわかります。`<label>`要素は、ユーザー名フィールドのようなUIコントロールに名前を付けるために使用されます。ラベルはフォームの読みやすさを向上させるだけでなく、以下のような追加の利点もあります:
ここで注目すべき点は、`<label>`要素も追加していることです。`<label>`要素は、ユーザー名フィールドのようなUIコントロールに名前を付けるために使用されます。ラベルはフォームの読みやすさを向上させるだけでなく、以下の利点もあります
- ラベルをフォームコントロールに関連付けることで、支援技術(スクリーンリーダーなど)を使用するユーザーがどのデータを提供する必要があるかを理解しやすくなります。
- ラベルをクリックすると、関連付けられた入力に直接フォーカスを当てることができ、タッチスクリーンデバイスでの操作が簡単になります。
> [ウェブアクセシビリティ](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility)は、しばしば見過ごされがちな非常に重要なトピックです。[セマンティックHTML要素](https://developer.mozilla.org/docs/Learn/Accessibility/HTML)を適切に使用すれば、アクセシブルなコンテンツを作成するのは難しくありません。[アクセシビリティについてさらに読む](https://developer.mozilla.org/docs/Web/Accessibility)ことで、一般的なミスを避け、責任ある開発者になることができます。
> [ウェブアクセシビリティ](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility)は非常に重要なトピックですが、しばしば見過ごされがちです。[セマンティックHTML要素](https://developer.mozilla.org/docs/Learn/Accessibility/HTML)を適切に使用すれば、アクセシブルなコンテンツを簡単に作成できます。[アクセシビリティについてさらに読む](https://developer.mozilla.org/docs/Web/Accessibility)ことで、一般的なミスを避け、責任ある開発者になることができます。
次に、登録用の2つ目のフォームを前のフォームの下に追加します
@ -105,7 +105,7 @@ curl http://localhost:5000/api
```
`value`属性を使用して、特定の入力にデフォルト値を定義できます。
また、`balance`の入力が`number`タイプであることに注意してください。他の入力と見た目が異なりますか?試して操作してみてください。
また、`balance`の入力には`number`タイプを使用しています。他の入力と見た目が異なることに気づきましたか?試しに操作してみてください。
✅ キーボードだけでフォームを操作できますか?どうやってそれを行いますか?
@ -113,11 +113,11 @@ curl http://localhost:5000/api
機能的なUIができたので、次のステップはデータをサーバーに送信することです。現在のコードを使用して簡単なテストを行いましょう*Login*または*Register*ボタンをクリックするとどうなりますか?
ブラウザのURLセクションに変化があったことに気づきましたか?
ブラウザのURLセクションに変化があことに気づきましたか?
![Registerボタンをクリックした後のブラウザURLの変化のスクリーンショット](../../../../7-bank-project/2-forms/images/click-register.png)
![Registerボタンをクリックした後のブラウザURLの変化のスクリーンショット](../../../../translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.ja.png)
`<form>`のデフォルトの動作は、現在のサーバーURLにフォームを[GETメソッド](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3)を使用して送信し、フォームデータをURLに直接追加することです。しかし、この方法にはいくつかの欠点があります
`<form>`のデフォルトの動作は、[GETメソッド](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3)を使用してフォームデータを現在のサーバーURLに送信し、フォームデータをURLに直接追加することです。しかし、この方法にはいくつかの欠点があります
- 送信されるデータのサイズが非常に制限されている約2000文字
- データがURLに直接表示されるパスワードには適していない
@ -125,7 +125,7 @@ curl http://localhost:5000/api
そのため、[POSTメソッド](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5)を使用して、フォームデータをHTTPリクエストのボディに送信し、これらの制限を回避することができます。
> POSTはデータ送信に最も一般的に使用されるメソッドですが、[特定のシナリオ](https://www.w3.org/2001/tag/doc/whenToUseGet.html)ではGETメソッドを使用する方が適している場合があります。たとえば、検索フィールドを実装する場合などです。
> POSTはデータ送信に最も一般的に使用されるメソッドですが、[特定のシナリオ](https://www.w3.org/2001/tag/doc/whenToUseGet.html)ではGETメソッドを使用する方が適している場合があります。えば、検索フィールドを実装する場合などです。
### タスク
@ -137,7 +137,7 @@ curl http://localhost:5000/api
次に、自分の名前で新しいアカウントを登録してみてください。*Register*ボタンをクリックすると、以下のような画面が表示されるはずです:
![localhost:5000/api/accountsのアドレスでブラウザウィンドウが表示され、ユーザーデータを含むJSON文字列が表示されている](../../../../7-bank-project/2-forms/images/form-post.png)
![localhost:5000/api/accountsのアドレスでブラウザウィンドウが表示され、ユーザーデータを含むJSON文字列が表示されている](../../../../translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.ja.png)
すべてが正常に動作すれば、サーバーはリクエストに応答し、作成されたアカウントデータを含む[JSON](https://www.json.org/json-en.html)レスポンスを返します。
@ -145,9 +145,9 @@ curl http://localhost:5000/api
## ページをリロードせずにデータを送信する
先ほど使用した方法には少し問題があることに気づいたかもしれませんフォームを送信すると、アプリから離れてブラウザがサーバーURLにリダイレクトしてしまいます。私たちは[シングルページアプリケーションSPA](https://en.wikipedia.org/wiki/Single-page_application)を作成しているため、すべてのページリロードを避けたいと考えています。
先ほど使用した方法には少し問題がありますフォームを送信すると、アプリから離れてブラウザがサーバーURLにリダイレクトしてしまいます。私たちは[シングルページアプリケーションSPA](https://en.wikipedia.org/wiki/Single-page_application)を作成しているため、すべてのページリロードを避けたいと考えています。
ページをリロードせずにフォームデータをサーバーに送信するには、JavaScriptコードを使用する必要があります。`<form>`要素の`action`プロパティにURLを指定する代わりに、`javascript:`文字列を先頭に付けた任意のJavaScriptコードを使用してカスタムアクションを実行できます。この方法を使用すると、ブラウザが自動的に行っていた以下のタスクを自分で実装する必要があります:
ページをリロードせずにフォームデータをサーバーに送信するには、JavaScriptコードを使用する必要があります。`<form>`要素の`action`プロパティにURLを指定する代わりに、`javascript:`文字列を先頭に付けた任意のJavaScriptコードを使用してカスタムアクションを実行できます。これを使用することで、ブラウザが自動的に行っていた以下のタスクを自分で実装する必要があります:
- フォームデータの取得
- フォームデータを適切な形式に変換およびエンコード
@ -191,28 +191,28 @@ async function createAccount(account) {
}
```
この関数は何をしているのでしょうか?まず、ここで`async`キーワードに注目してください。これは、関数内に[**非同期**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)で実行されるコードが含まれていることを意味します。`await`キーワードと組み合わせて使用すると、ここでサーバーの応答を待つなど、非同期コードの実行を待機してから処理を続行できます。
この関数は何をしているのでしょうか?まず、ここで`async`キーワードに注目してください。これは、関数内に[**非同期**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)で実行されるコードが含まれていることを意味します。`await`キーワードと組み合わせて使用すると、ここでサーバーの応答を待つなど、非同期コードの実行を待てから処理を続行できます。
`async/await`の使用方法についての簡単な動画はこちらです:
[![AsyncとAwaitでプロミスを管理する](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "AsyncとAwaitでプロミスを管理する")
[![非同期処理とAwaitの使用方法](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "非同期処理とAwaitの使用方法")
> 🎥 上の画像をクリックすると、async/awaitに関する動画が再生されます。
> 🎥 上の画像をクリックすると、`async/await`に関する動画が再生されます。
`fetch()`APIを使用してJSONデータをサーバーに送信します。このメソッドは2つのパラメータを取ります
- サーバーのURL。ここでは`//localhost:5000/api/accounts`を指定します。
- サーバーのURL。ここでは`//localhost:5000/api/accounts`を再度指定します。
- リクエストの設定。ここでメソッドを`POST`に設定し、リクエストの`body`を提供します。JSONデータをサーバーに送信しているため、`Content-Type`ヘッダーを`application/json`に設定して、サーバーがコンテンツを解釈できるようにします。
サーバーがリクエストにJSONで応答するため、`await response.json()`を使用してJSONコンテンツを解析し、結果のオブジェクトを返します。このメソッドは非同期であるため、解析中のエラーもキャッチできるように`await`キーワードを使用します。
次に、`register`関数に`createAccount()`を呼び出すコードを追加してください
次に、`register`関数にコードを追加して`createAccount()`を呼び出します
```js
const result = await createAccount(jsonData);
```
ここで`await`キーワードを使用しているため、`register`関数の前に`async`キーワードを追加する必要があります:
`await`キーワードを使用しているため、`register`関数の前に`async`キーワードを追加する必要があります:
```js
async function register() {
@ -235,9 +235,9 @@ async function register() {
}
```
少し長くなりましたが、これで完了です![ブラウザの開発者ツール](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools)を開き、新しいアカウントを登録してみてください。ウェブページには変化が見られませんが、コンソールにメッセージが表示され、すべてが正常に動作していることを確認できます。
少し長くなりましたが、これで完了です![ブラウザの開発者ツール](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools)を開き、新しいアカウントを登録してみてください。ウェブページには何も変化がないはずですが、コンソールにメッセージが表示され、すべてが正常に動作していることを確認できます。
![ブラウザコンソールにログメッセージが表示されているスクリーンショット](../../../../7-bank-project/2-forms/images/browser-console.png)
![ブラウザコンソールにログメッセージが表示されているスクリーンショット](../../../../translated_images/browser-console.efaf0b51aaaf67782a29e1a0bb32cc063f189b18e894eb5926e02f1abe864ec2.ja.png)
✅ データは安全にサーバーに送信されていると思いますか?リクエストが傍受された場合はどうなるでしょうか?[HTTPS](https://en.wikipedia.org/wiki/HTTPS)について読んで、安全なデータ通信について学んでください。
@ -250,12 +250,12 @@ async function register() {
- `required`: フィールドが入力されていない場合、フォームを送信できません。
- `minlength`と`maxlength`: テキストフィールドの最小および最大文字数を定義します。
- `min`と`max`: 数値フィールドの最小および最大値を定義します。
- `type`: `number`、`email`、`file`などのデータの種類を定義します。[その他の組み込みタイプ](https://developer.mozilla.org/docs/Web/HTML/Element/input)もあります。この属性はフォームコントロールの視覚的なレンダリングを変更する場合もあります。
- `type`: 期待されるデータの種類を定義します。例えば`number`、`email`、`file`などの[組み込みタイプ](https://developer.mozilla.org/docs/Web/HTML/Element/input)。この属性はフォームコントロールの視覚的なレンダリングを変更する場合もあります。
- `pattern`: [正規表現](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions)パターンを定義して、入力されたデータが有効かどうかをテストします。
ヒント: `:valid` および `:invalid` CSS疑似クラスを使用して、フォームコントロールが有効か無効かに応じて外観をカスタマイズすることができます。
> ヒント: `:valid``:invalid`CSS疑似クラスを使用して、フォームコントロールが有効か無効かに応じて外観をカスタマイズすることができます。
### タスク
新しいアカウントを作成するには、ユーザー名と通貨の2つの必須フィールドが必要です。他のフィールドは任意です。フォームのHTMLを更新し、`required`属性とフィールドラベル内のテキストを使用して次のようにします
新しいアカウントを作成するには、ユーザー名と通貨の2つの必須フィールドが必要です。他のフィールドは任意です。フォームのHTMLを更新し、`required`属性とフィールドラベル内のテキストを使用して以下のようにしてください
```html
<label for="user">Username (required)</label>
@ -265,7 +265,7 @@ async function register() {
<input id="currency" name="currency" type="text" value="$" required>
```
このサーバー実装では、フィールドの最大長に特定の制限を課していませんが、ユーザーが入力するテキストには常に適切な制限を設けるのが良い習慣です。
このサーバー実装では、フィールドの最大長に特定の制限を課していませんが、ユーザーが入力するテキストには適切な制限を設けるのが常に良い習慣です。
テキストフィールドに`maxlength`属性を追加してください:
@ -277,23 +277,23 @@ async function register() {
<input id="description" name="description" type="text" maxlength="100">
```
次に、*登録*ボタンを押して、定義したバリデーションルールに従わないフィールドがある場合、次のようなエラーメッセージが表示されるはずです:
次に、*登録*ボタンを押して、定義したバリデーションルールに違反するフィールドがある場合、以下のようなエラーが表示されるはずです:
![フォーム送信時のバリデーションエラーを示すスクリーンショット](../../../../7-bank-project/2-forms/images/validation-error.png)
![フォーム送信時にバリデーションエラーが発生した際のスクリーンショット](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.ja.png)
このように、データをサーバーに送信する*前に*行われるバリデーションは、**クライアントサイド**バリデーションと呼ばれます。ただし、すべてのチェックをデータを送信せずに行うことは常に可能ではありません。例えば、同じユーザー名のアカウントが既に存在するかどうかは、サーバーにリクエストを送信しないと確認できません。サーバーで行われる追加のバリデーションは、**サーバーサイド**バリデーションと呼ばれます。
このように、データをサーバーに送信する*前に*行われるバリデーションは、**クライアントサイド**バリデーションと呼ばれます。ただし、すべてのチェックをデータを送信せずに行うことは常に可能ではありません。例えば、同じユーザー名のアカウントが既に存在するかどうかを確認するには、サーバーにリクエストを送信しなければなりません。サーバーで追加のバリデーションを行うことは、**サーバーサイド**バリデーションと呼ばれます。
通常、両方を実装する必要があります。クライアントサイドバリデーションは、ユーザーに即時のフィードバックを提供することでユーザー体験を向上させますが、サーバーサイドバリデーションは、操作するユーザーデータが正確で安全であることを保証するために重要です。
通常、クライアントサイドとサーバーサイドの両方のバリデーションを実装する必要があります。クライアントサイドバリデーションは、ユーザーに即時のフィードバックを提供することでユーザー体験を向上させますが、サーバーサイドバリデーションは、操作するユーザーデータが正確で安全であることを保証するために不可欠です。
---
## 🚀 チャレンジ
ユーザーが既に存在する場合、HTMLにエラーメッセージを表示してください。
HTML内で、ユーザーが既に存在する場合にエラーメッセージを表示してください。
以下は、少しスタイリングを加えた後の最終的なログインページの例です:
![CSSスタイルを追加した後のログインページのスクリーンショット](../../../../7-bank-project/2-forms/images/result.png)
![CSSスタイルを追加した後のログインページのスクリーンショット](../../../../translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.ja.png)
## 講義後のクイズ
@ -301,11 +301,13 @@ async function register() {
## 復習と自己学習
開発者たちは、特にバリデーション戦略に関して、フォーム作成に非常に創造的になっています。[CodePen](https://codepen.com)を見て、さまざまなフォームフローについて学んでみてください。興味深く、インスピレーションを与えるフォームを見つけられますか?
開発者たちは、特にバリデーション戦略に関して、フォーム作成において非常に創造的になっています。[CodePen](https://codepen.com)を見て、さまざまなフォームフローについて学んでみてください。興味深く、刺激的なフォームを見つけることができますか?
## 課題
[銀行アプリをスタイリングする](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f587e913e3f7c0b1c549a05dd74ee8e5",
"translation_date": "2025-08-24T00:04:16+00:00",
"original_hash": "89d0df9854ed020f155e94882ae88d4c",
"translation_date": "2025-08-28T17:45:34+00:00",
"source_file": "7-bank-project/3-data/README.md",
"language_code": "ja"
}
-->
# 銀行アプリを作成するパート3: データの取得と使用方法
# 銀行アプリを作成する Part 3: データの取得と利用方法
## 講義前クイズ
@ -15,15 +15,15 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
すべてのウェブアプリケーションの中心には*データ*があります。データはさまざまな形を取りますが、その主な目的は常にユーザーに情報を表示することです。ウェブアプリがますますインタラクティブで複雑になる中で、ユーザーが情報にアクセスし、操作する方法はウェブ開発の重要な部分となっています。
すべてのウェブアプリケーションの中心には*データ*があります。データはさまざまな形を取りますが、その主な目的は常にユーザーに情報を表示することです。ウェブアプリがますますインタラクティブで複雑になるにつれ、ユーザーが情報にアクセスし、操作する方法はウェブ開発の重要な部分となっています。
このレッスンでは、サーバーから非同期でデータを取得し、そのデータを使用してHTMLをリロードせずにウェブページに情報を表示する方法を学びます。
このレッスンでは、サーバーから非同期でデータを取得し、そのデータを使用してHTMLを再読み込みせずにウェブページに情報を表示する方法を学びます。
### 前提条件
このレッスンのためにウェブアプリの[ログインと登録フォーム](../2-forms/README.md)部分を構築している必要があります。また、[Node.js](https://nodejs.org)をインストールし、[サーバーAPI](../api/README.md)をローカルで実行してアカウントデータを取得できるようにする必要があります。
このレッスンのためにウェブアプリの[ログインと登録フォーム](../2-forms/README.md)を作成している必要があります。また、[Node.js](https://nodejs.org)をインストールし、[サーバーAPI](../api/README.md)をローカルで実行してアカウントデータを取得する必要があります。
サーバーが正しく動作しているかを確認するには、ターミナルで次のコマンドを実行してください:
サーバーが正しく動作しているかどうかは、ターミナルで次のコマンドを実行して確認できます。
```sh
curl http://localhost:5000/api
@ -34,21 +34,21 @@ curl http://localhost:5000/api
## AJAXとデータ取得
従来のウェブサイトでは、リンクを選択したりフォームを使用してデータを送信したりすると、HTMLページ全体をリロードして表示内容を更新します。新しいデータを読み込むたびに、ウェブサーバーは新しいHTMLページを返し、ブラウザがそれを処理する必要があります。このプロセスは現在のユーザー操作を中断し、リロード中の操作を制限します。このワークフローは*マルチページアプリケーション*MPAとも呼ばれます。
従来のウェブサイトでは、ユーザーがリンクを選択したりフォームを使用してデータを送信したりすると、HTMLページ全体を再読み込みすることで表示内容を更新します。新しいデータを読み込むたびに、ウェブサーバーは新しいHTMLページを返し、ブラウザがそれを処理する必要があります。このプロセスは現在のユーザー操作を中断し、再読み込み中のインタラクションを制限します。このワークフローは*マルチページアプリケーション (MPA)*とも呼ばれます。
![マルチページアプリケーションの更新ワークフロー](../../../../7-bank-project/3-data/images/mpa.png)
![マルチページアプリケーションの更新ワークフロー](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.ja.png)
ウェブアプリケーションがより複雑でインタラクティブになるにつれて、[AJAXAsynchronous JavaScript and XML](https://en.wikipedia.org/wiki/Ajax_(programming))と呼ばれる新しい技術が登場しました。この技術により、JavaScriptを使用してサーバーから非同期でデータを送受信し、HTMLページをリロードせずに更新することが可能になり、より高速な更新とスムーズなユーザー操作が実現しました。サーバーから新しいデータを受信すると、[DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) APIを使用して現在のHTMLページをJavaScriptで更新できます。このアプローチは進化を遂げ、現在では[*シングルページアプリケーション*SPA](https://en.wikipedia.org/wiki/Single-page_application)と呼ばれています。
ウェブアプリケーションがより複雑でインタラクティブになるにつれ、[AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming))という新しい技術が登場しました。この技術により、ウェブアプリはJavaScriptを使用してサーバーから非同期でデータを送受信し、HTMLページを再読み込みせずに更新を行うことが可能になり、より迅速な更新とスムーズなユーザーインタラクションを実現しました。サーバーから新しいデータを受信すると、現在のHTMLページをJavaScriptを使用して[DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) APIで更新することができます。このアプローチは進化を遂げ、現在では[*シングルページアプリケーション (SPA)*](https://en.wikipedia.org/wiki/Single-page_application)と呼ばれています。
![シングルページアプリケーションの更新ワークフロー](../../../../7-bank-project/3-data/images/spa.png)
![シングルページアプリケーションの更新ワークフロー](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.ja.png)
AJAXが最初に導入されたとき、非同期でデータを取得するために利用可能な唯一のAPIは[`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)でした。しかし、現在のブラウザは、より便利で強力な[`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API)も実装しており、これはPromiseを使用し、JSONデータの操作に適しています。
AJAXが初めて導入された際、非同期でデータを取得するために利用可能な唯一のAPIは[`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)でした。しかし、現在のブラウザは、より便利で強力な[`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API)が実装されており、プロミスを使用し、JSONデータの操作に適しています。
> 現代のすべてのブラウザが`Fetch API`をサポートしていますが、ウェブアプリケーションを古いブラウザやレガシーブラウザで動作させたい場合は、[caniuse.comの互換性表](https://caniuse.com/fetch)を確認することをお勧めします。
> すべての最新ブラウザが`Fetch API`をサポートしていますが、ウェブアプリケーションを古いブラウザで動作させたい場合は、[caniuse.comの互換性表](https://caniuse.com/fetch)を事前に確認することをお勧めします。
### 課題
### タスク
[前回のレッスン](../2-forms/README.md)では、アカウントを作成するための登録フォームを実装しました。今回は既存のアカウントを使用してログインし、そのデータを取得するコードを追加します。`app.js`ファイルを開き、新しい`login`関数を追加してください:
[前回のレッスン](../2-forms/README.md)では、アカウントを作成するための登録フォームを実装しました。今回は既存のアカウントを使用してログインし、そのデータを取得するコードを追加します。`app.js`ファイルを開き、新しい`login`関数を追加してください
```js
async function login() {
@ -57,9 +57,9 @@ async function login() {
}
```
ここでは、`getElementById()`を使用してフォーム要素を取得し、次に`loginForm.user.value`入力からユーザー名を取得します。すべてのフォームコントロールは、HTMLで`name`属性を使用して設定された名前をプロパティとしてフォームからアクセスできます。
ここでは、`getElementById()`を使用してフォーム要素を取得し、次に`loginForm.user.value`を使用して入力からユーザー名を取得します。すべてのフォームコントロールは、HTMLで`name`属性を使用して設定された名前をプロパティとしてフォームからアクセスできます。
登録時と同様に、サーバーリクエストを実行するための別の関数を作成しますが、今回はアカウントデータを取得します:
登録時に行った操作と同様に、サーバーリクエストを実行するための別の関数を作成しますが、今回はアカウントデータを取得するためのものです。
```js
async function getAccount(user) {
@ -72,11 +72,11 @@ async function getAccount(user) {
}
```
`fetch` APIを使用してサーバーから非同期でデータをリクエストしますが、今回はURL以外の追加パラメータは必要ありません。ここではデータをクエリするだけなので、デフォルトで`fetch`は[`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTPリクエストを作成します。
`fetch` APIを使用してサーバーから非同期でデータをリクエストしますが、今回はデータをクエリするだけなので、URL以外の追加パラメータは必要ありません。デフォルトでは、`fetch`は[`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTPリクエストを作成しますが、これが今回求めているものです。
`encodeURIComponent()`はURLの特殊文字をエスケープする関数です。この関数を呼び出さずに`user`値をURLに直接使用した場合、どのような問題が発生する可能性があるでしょうか?
`encodeURIComponent()`はURLの特殊文字をエスケープする関数です。この関数を呼び出さずに直接`user`値をURLに使用すると、どのような問題が発生する可能性があるでしょうか?
次に、`login`関数を更新して`getAccount`を使用します:
次に、`login`関数を更新して`getAccount`を使用します
```js
async function login() {
@ -93,9 +93,9 @@ async function login() {
}
```
まず、`getAccount`が非同期関数であるため、サーバーの結果を待つために`await`キーワードを使用する必要があります。また、サーバーリクエストではエラーケースを処理する必要があります。ここではエラーメッセージをログに表示するだけにしておき、後で戻ってきます。
まず、`getAccount`が非同期関数であるため、サーバーの結果を待つために`await`キーワードを使用する必要があります。サーバーリクエストでは常にエラーケースに対処する必要がありますが、現時点ではエラーメッセージをログに表示するだけにしておき、後で戻ってきます。
次に、データをどこかに保存して、後でダッシュボード情報を表示するために使用できるようにする必要があります。`account`変数がまだ存在しないため、ファイルの先頭にグローバル変数を作成します:
次に、後でダッシュボード情報を表示するためにデータを保存する必要があります。`account`変数がまだ存在しないため、ファイルの先頭にグローバル変数を作成します
```js
let account = null;
@ -103,7 +103,7 @@ let account = null;
ユーザーデータが変数に保存された後、既存の`navigate()`関数を使用して*ログイン*ページから*ダッシュボード*に移動できます。
最後に、ログインフォームが送信されたときに`login`関数を呼び出すようにHTMLを変更します:
最後に、ログインフォームが送信されたときに`login`関数を呼び出す必要があります。HTMLを次のように変更してください。
```html
<form id="loginForm" action="javascript:login()">
@ -111,32 +111,32 @@ let account = null;
新しいアカウントを登録し、同じアカウントを使用してログインを試みることで、すべてが正しく動作していることを確認してください。
次の部分に進む前に、`register`関数を次のコードを追加して完成させることができます:
次の部分に進む前に、`register`関数を完成させるために、関数の最後に次のコードを追加できます。
```js
account = result;
navigate('/dashboard');
```
✅ デフォルトでは、*同じドメインとポート*からのみサーバーAPIを呼び出すことができます。これはブラウザによって強制されるセキュリティメカニズムです。しかし、私たちのウェブアプリは`localhost:3000`で動作しているのに対し、サーバーAPIは`localhost:5000`で動作しています。それでもなぜ動作するのでしょうか?[クロスオリジンリソース共有CORS](https://developer.mozilla.org/docs/Web/HTTP/CORS)と呼ばれる技術を使用することで、サーバーが特定のドメインに対して例外を許可する特別なヘッダーをレスポンスに追加することで、クロスオリジンHTTPリクエストを実行することが可能す。
✅ デフォルトでは、表示しているウェブページと*同じドメインとポート*からのみサーバーAPIを呼び出すことができます。これはブラウザによって強制されるセキュリティメカニズムです。しかし、ウェブアプリは`localhost:3000`で動作しているのに対し、サーバーAPIは`localhost:5000`で動作しているのに、なぜ動作するのでしょうか?[クロスオリジンリソース共有 (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS)という技術を使用することで、サーバーが特定のドメインに対する例外を許可する特別なヘッダーをレスポンスに追加することで、クロスオリジンHTTPリクエストを実行することが可能になります。
> APIについてさらに学ぶには、この[レッスン](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon)を参照してください。
> APIについてさらに学ぶには、この[レッスン](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon)を受講してください。
## HTMLを更新してデータを表示する
ユーザーデータを取得したので、既存のHTMLを更新してそれを表示する必要があります。例えば`document.getElementById()`を使用してDOMから要素を取得する方法はすでに知っています。ベース要素を取得した後、以下のAPIを使用してその内容を変更したり子要素を追加したりできます:
ユーザーデータを取得したので、既存のHTMLを更新して表示する必要があります。例えば`document.getElementById()`を使用してDOMから要素を取得する方法はすでに知っています。ベースとなる要素を取得した後、以下のAPIを使用してその内容を変更したり子要素を追加したりできます
- [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent)プロパティを使用して要素のテキストを変更できます。この値を変更すると、要素のすべての子要素(存在する場合)が削除され、指定されたテキストに置き換えられます。そのため、特定の要素のすべての子要素を削除する効率的な方法として、空の文字列`''`を割り当てることもできます。
- [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent)プロパティを使用すると、要素のテキストを変更できます。この値を変更すると、要素の子要素(存在する場合)がすべて削除され、指定されたテキストに置き換えられます。そのため、空の文字列`''`を割り当てることで、指定された要素のすべての子要素を効率的に削除することもできます。
- [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement)と[`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append)メソッドを組み合わせて、新しい子要素を作成して添付できます。
- [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement)と[`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append)メソッドを組み合わせることで、新しい子要素を作成して追加できます。
要素の[`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML)プロパティを使用してHTML内容を変更することも可能ですが、これは[クロスサイトスクリプティングXSS](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting)攻撃に対して脆弱であるため避けるべきです。
✅ [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML)プロパティを使用すると、要素のHTML内容を変更することも可能ですが、これは[クロスサイトスクリプティング (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting)攻撃に対して脆弱であるため避けるべきです。
### 課題
### タスク
*ログイン*ページでダッシュボード画面に進む前に、もう1つやるべきことがあります。現在、存在しないユーザー名でログインしようとすると、コンソールにメッセージが表示されますが、通常のユーザーには何も変わらず、何が起こっているのか分かりません。
ダッシュボード画面に進む前に、*ログイン*ページでやるべきことがもう一つあります。現在、存在しないユーザー名でログインしようとすると、コンソールにメッセージが表示されますが、通常のユーザーには何も変化がなく、何が起こっているのか分かりません。
ログインフォームにエラーメッセージを表示するためのプレースホルダー要素を追加しましょう。適切な場所はログイン`<button>`の直前です:
ログインフォームにエラーメッセージを表示するためのプレースホルダー要素を追加しましょう。適切な場所はログイン`<button>`の直前です
```html
...
@ -145,9 +145,9 @@ navigate('/dashboard');
...
```
この`<div>`要素は空であり、何か内容を追加するまで画面には何も表示されません。また、`id`を指定してJavaScriptで簡単に取得できるようにしています。
この`<div>`要素は空であり、何も表示されません。JavaScriptでコンテンツを追加するまで画面には何も表示されません。また、`id`を付けることでJavaScriptで簡単に取得できるようにしています。
`app.js`ファイルに戻り、新しいヘルパー関数`updateElement`を作成します:
`app.js`ファイルに戻り、新しいヘルパー関数`updateElement`を作成してください。
```js
function updateElement(id, text) {
@ -156,7 +156,7 @@ function updateElement(id, text) {
}
```
この関数は非常にシンプルです: 要素の*id*と*text*を指定すると、対応する`id`を持つDOM要素のテキスト内容を更新します。このメソッドを`login`関数内の以前のエラーメッセージの代わりに使用します:
この関数は非常に簡単です。要素の*id*と*text*を指定すると、対応する`id`を持つDOM要素のテキスト内容を更新します。このメソッドを使用して、`login`関数内の以前のエラーメッセージを置き換えます。
```js
if (data.error) {
@ -164,23 +164,23 @@ if (data.error) {
}
```
これで無効なアカウントでログインしようとすると、次のようなものが表示されるはずです:
これで無効なアカウントでログインしようとすると、次のような表示がされるはずです。
![ログイン中に表示されるエラーメッセージのスクリーンショット](../../../../7-bank-project/3-data/images/login-error.png)
![ログイン中に表示されるエラーメッセージのスクリーンショット](../../../../translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.ja.png)
これでエラーテキストが視覚的に表示されるようになりましたが、スクリーンリーダーで試してみると何もアナウンスされないことに気付くでしょう。ページに動的に追加されたテキストがスクリーンリーダーでアナウンスされるためには、[ライブリージョン](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions)と呼ばれるものを使用する必要があります。ここでは、アラートと呼ばれる特定のタイプのライブリージョンを使用します:
これでエラーテキストが視覚的に表示されるようになりましたが、スクリーンリーダーで試してみると何も読み上げられないことに気付くでしょう。ページに動的に追加されたテキストがスクリーンリーダーで読み上げられるようにするには、[ライブリージョン](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions)を使用する必要があります。ここでは、アラートと呼ばれる特定のタイプのライブリージョンを使用します
```html
<div id="loginError" role="alert"></div>
```
同じ動作を`register`関数のエラーにも実装してくださいHTMLの更新を忘れないでください)。
同じ動作を`register`関数のエラーにも実装してくださいHTMLの更新を忘れずに)。
## ダッシュボードに情報を表示する
これまでに学んだ技術を使用して、ダッシュボードページにアカウント情報を表示する作業も行います。
先ほど見た技術を使用して、ダッシュボードページにアカウント情報を表示する処理を行います。
サーバーから受信したアカウントオブジェクトは次のようになります:
サーバーから受信したアカウントオブジェクトは次のような形式です。
```json
{
@ -196,11 +196,11 @@ if (data.error) {
}
```
> 注: にデータが入力されている`test`アカウントを使用すると、作業が簡単になります。
> 注: すでにデータが入力されている`test`アカウントを使用すると、作業が簡単になります。
### 課題
### タスク
まず、HTMLの"Balance"セクションをプレースホルダー要素に置き換えます:
まず、HTMLの「残高」セクションをプレースホルダー要素に置き換えます。
```html
<section>
@ -208,15 +208,15 @@ if (data.error) {
</section>
```
また、アカウントの説明を表示するためにその下に新しいセクションを追加します:
また、アカウントの説明を表示するためにその下に新しいセクションを追加します
```html
<h2 id="description"></h2>
```
✅ アカウントの説明はその下の内容のタイトルとして機能するため、セマンティックに見出しとしてマークアップされています。[見出し構造](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility)がアクセシビリティにとって重要である理由を学び、ページを批判的に見て他に見出しにできる部分がないか検討してください。
✅ アカウントの説明はその下のコンテンツのタイトルとして機能するため、セマンティックに見出しとしてマークアップされています。[見出し構造](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility)がアクセシビリティにとって重要である理由を学び、ページを批判的に見て他に見出しとして適切な箇所がないか検討してください。
次に、`app.js`に新しい関数を作成してプレースホルダーを埋めます:
次に、`app.js`に新しい関数を作成してプレースホルダーを埋めます
```js
function updateDashboard() {
@ -232,11 +232,11 @@ function updateDashboard() {
まず、必要なアカウントデータがあることを確認してから進みます。その後、先ほど作成した`updateElement()`関数を使用してHTMLを更新します。
> 残高表示をより見栄え良くするために、[`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed)メソッドを使用して小数点以下2桁を強制的に表示します。
> 残高表示をより見やすくするために、[`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed)メソッドを使用して小数点以下2桁を強制的に表示します。
次に、ダッシュボードが読み込まれるたびに`updateDashboard()`関数を呼び出す必要があります。[レッスン1の課題](../1-template-route/assignment.md)を既に完了している場合は簡単なはずです。そうでない場合は、次の実装を使用できます。
ダッシュボードが読み込まれるたびに`updateDashboard()`関数を呼び出す必要があります。[レッスン1の課題](../1-template-route/assignment.md)をすでに完了している場合は簡単ですが、次の実装を使用することもできます。
`updateRoute()`関数の最後に次のコードを追加します:
`updateRoute()`関数の最後に次のコードを追加してください。
```js
if (typeof route.init === 'function') {
@ -244,7 +244,7 @@ if (typeof route.init === 'function') {
}
```
そして、ルート定義を次のように更新します:
そして、ルート定義を次のように更新します
```js
const routes = {
@ -257,13 +257,13 @@ const routes = {
## HTMLテンプレートを使用してテーブル行を動的に作成する
[最初のレッスン](../1-template-route/README.md)では、HTMLテンプレートと[`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild)メソッドを使用してアプリのナビゲーションを実装しました。テンプレートはより小さく、ページの繰り返し部分を動的に埋めるためにも使用できます。
[レッスン1](../1-template-route/README.md)では、HTMLテンプレートと[`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild)メソッドを使用してアプリのナビゲーションを実装しました。テンプレートはより小さく、ページの繰り返し部分を動的に埋めるためにも使用できます。
同様のアプローチを使用して、HTMLテーブル内のトランザクションリストを表示します。
### 課題
### タスク
HTMLの`<body>`に新しいテンプレートを追加します:
HTMLの`<body>`に新しいテンプレートを追加してください。
```html
<template id="transaction">
@ -275,15 +275,15 @@ HTMLの`<body>`に新しいテンプレートを追加します:
</template>
```
このテンプレートは1つのテーブル行を表し、トランザクションの*日付*、*オブジェクト*、*金額*の3つの列を埋めるためのものです。
このテンプレートは単一のテーブル行を表し、埋めたい3つの列*日付*、*内容*、*金額*)を持っています。
次に、JavaScriptで簡単に見つけられるように、ダッシュボードテンプレート内のテーブルの`<tbody>`要素にこの`id`プロパティを追加します:
次に、JavaScriptで簡単に見つけられるようにするために、ダッシュボードテンプレート内のテーブルの`<tbody>`要素にこの`id`プロパティを追加します
```html
<tbody id="transactions"></tbody>
```
HTMLの準備が整ったので、JavaScriptコードに切り替えて新しい関数`createTransactionRow`を作成します:
HTMLの準備が整ったので、JavaScriptコードに切り替えて新しい関数`createTransactionRow`を作成します
```js
function createTransactionRow(transaction) {
@ -297,7 +297,7 @@ function createTransactionRow(transaction) {
}
```
この関数はその名前が示す通りのことを行います: 先ほど作成したテンプレートを使用して新しいテーブル行を作成し、トランザクションデータを使用してその内容を埋めます。これを`updateDashboard()`関数内で使用してテーブルを埋めます:
この関数はその名前が示す通りのことを行います先ほど作成したテンプレートを使用して新しいテーブル行を作成し、トランザクションデータを使用してその内容を埋めます。この関数を`updateDashboard()`関数内で使用してテーブルを埋めます。
```js
const transactionsRows = document.createDocumentFragment();
@ -310,7 +310,7 @@ updateElement('transactions', transactionsRows);
ここでは、[`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment)メソッドを使用して新しいDOMフラグメントを作成し、それを操作してから最終的にHTMLテーブルに添付します。
このコードが動作するようにするには、`updateElement()`関数が現在テキストコンテンツのみをサポートしているため、少しコードを変更する必要があります:
このコードが動作する前にもう一つやるべきことがあります。現在の`updateElement()`関数はテキストコンテンツのみをサポートしています。そのコードを少し変更しましょう。
```js
function updateElement(id, textOrNode) {
@ -320,18 +320,18 @@ function updateElement(id, textOrNode) {
}
```
[`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append)メソッドを使用すると、テキストまたは[DOMード](https://developer.mozilla.org/docs/Web/API/Node)のいずれかを親要素に添付できるため、すべてのユースケースに適しています。
[`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append)メソッドを使用すると、テキストまたは[DOMード](https://developer.mozilla.org/docs/Web/API/Node)を親要素に添付することができ、すべてのユースケースに適しています。
`test`アカウントを使用してログインを試みると、ダッシュボードに取引リストが表示されるはずです 🎉。
---
## 🚀 チャレンジ
協力してダッシュボードページを本物の銀行アプリのように見えるようにしましょう。すでにアプリをスタイリングしている場合は、[メディアクエリ](https://developer.mozilla.org/docs/Web/CSS/Media_Queries)を使用して、デスクトップとモバイルデバイスの両方でうまく動作する[レスポンシブデザイン](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks)を作成してみてください。
チームで協力してダッシュボードページを本物の銀行アプリのように見ましょう。すでにアプリをスタイリングしている場合は、[メディアクエリ](https://developer.mozilla.org/docs/Web/CSS/Media_Queries)を使用して、デスクトップとモバイルデバイスの両方で快適に動作する[レスポンシブデザイン](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks)を作成してみてください。
以下はスタイリングされたダッシュボードページの例です:
以下は、スタイリング後のダッシュボードページの例です:
![スタイリング後のダッシュボードの例のスクリーンショット](../../../../7-bank-project/images/screen2.png)
![スタイリング後のダッシュボードの例のスクリーンショット](../../../../translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.ja.png)
## 講義後のクイズ
@ -339,7 +339,9 @@ function updateElement(id, textOrNode) {
## 課題
[コードをリファクタリングしてコメントを追加する](assignment.md)
[コードをリファクタリングし、コメントを追加する](assignment.md)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された原文が正式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4fa20c513e367e9cdd401bf49ae16e33",
"translation_date": "2025-08-24T00:13:27+00:00",
"original_hash": "5d2efabbc8f94d89f4317ee8646c3ce9",
"translation_date": "2025-08-28T17:47:19+00:00",
"source_file": "7-bank-project/4-state-management/README.md",
"language_code": "ja"
}
@ -15,15 +15,15 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
ウェブアプリケーションが成長するにつれて、すべてのデータフローを追跡するのが難しくなります。どのコードがデータを取得し、どのページがそれを使用し、どこでいつ更新が必要なのか...コードが散らかり、保守が難しくなるのは簡単です。特に、アプリの異なるページ間でデータを共有する必要がある場合(例えば、ユーザーデータ)にこの問題は顕著です。*状態管理*の概念は、あらゆる種類のプログラムにおいて常に存在していましたが、ウェブアプリがますます複雑化する中で、開発中に考慮すべき重要なポイントとなっています。
ウェブアプリケーションが成長するにつれて、データフローを追跡するのが難しくなります。どのコードがデータを取得し、どのページがそれを使用し、どこでいつ更新が必要なのか...コードが散らかり、保守が困難になることがあります。特に、アプリの異なるページ間でデータを共有する必要がある場合、例えばユーザーデータなどでは、この問題が顕著です。*状態管理*の概念は、あらゆる種類のプログラムで常に存在していましたが、ウェブアプリがますます複雑化するにつれて、開発中に考慮すべき重要なポイントとなっています。
この最終パートでは、これまでに作成したアプリを見直し、状態管理を再考します。これにより、ブラウザのリフレッシュをサポートし、ユーザーセッション間でデータを永続化できるようにします。
この最終パートでは、これまでに作成したアプリを見直し、状態管理を再考し、ブラウザのリフレッシュをサポートし、ユーザーセッション間でデータを保持できるようにします。
### 前提条件
このレッスンのために、ウェブアプリの[データ取得](../3-data/README.md)パートを完了している必要があります。また、[Node.js](https://nodejs.org)をインストールし、[サーバーAPI](../api/README.md)をローカルで実行してアカウントデータを管理できるようにする必要があります。
このレッスンでは、ウェブアプリの[データ取得](../3-data/README.md)パートを完了している必要があります。また、[Node.js](https://nodejs.org)をインストールし、[サーバーAPI](../api/README.md)をローカルで実行してアカウントデータを管理できるようにする必要があります。
サーバーが正しく動作しているかどうかは、ターミナルで以下のコマンドを実行して確認できます。
サーバーが正しく動作しているかどうかは、ターミナルでのコマンドを実行して確認できます。
```sh
curl http://localhost:5000/api
@ -34,40 +34,40 @@ curl http://localhost:5000/api
## 状態管理を再考する
[前回のレッスン](../3-data/README.md)では、現在ログインしているユーザーの銀行データを含むグローバル変数`account`を使用して、アプリ内での基本的な状態の概念を紹介しました。しかし、現在の実装にはいくつかの欠点があります。ダッシュボードページでページをリフレッシュしてみてください。何が起こりますか?
[前回のレッスン](../3-data/README.md)では、現在ログインしているユーザーの銀行データを含むグローバル変数`account`を使用して、アプリの基本的な状態の概念を紹介しました。しかし、現在の実装にはいくつかの欠点があります。ダッシュボードでページをリフレッシュしてみてください。何が起こりますか?
現在のコードには3つの問題があります
- 状態が永続化されていないため、ブラウザをリフレッシュするとログインページに戻ってしまいます。
- 状態が保持されていないため、ブラウザをリフレッシュするとログインページに戻ってしまいます。
- 状態を変更する関数が複数あり、アプリが成長するにつれて変更を追跡するのが難しくなり、更新を忘れることが容易になります。
- 状態がクリアされないため、*ログアウト*をクリックしても、ログインページにいる間もアカウントデータが残っています。
- 状態がクリーンップされないため、*ログアウト*をクリックしてもログインページにいる間にアカウントデータが残っています。
これらの問題に1つずつ対処するようにコードを更新することもできますが、それではコードの重複が増え、アプリがより複雑で保守が難しくなります。あるいは、数分間立ち止まって戦略を再考することもできます。
これらの問題を一つずつ解決するためにコードを更新することもできますが、それではコードの重複が増え、アプリがより複雑で保守が難しくなります。そこで、数分間立ち止まって戦略を再考することができます。
> ここで本当に解決しようとしている問題は何でしょうか?
[状態管理](https://en.wikipedia.org/wiki/State_management)とは、以下の2つの特定の問題を解決するための良いアプローチを見つけることです
[状態管理](https://en.wikipedia.org/wiki/State_management)は、次の2つの特定の問題を解決するための良いアプローチを見つけることに関するものです:
- アプリ内のデータフローを理解しやすくするにはどうすればよいか?
- 状態データを常にユーザーインターフェースと同期させるにはどうすればよいか(その逆も)?
- 状態データを常にユーザーインターフェースと同期させるにはどうすればよいか(その逆も同様
これらの問題に対処すれば、他の問題もすでに解決されているか、解決が容易になっている可能性があります。これらの問題を解決するためのアプローチは多数ありますが、ここでは**データとその変更方法を中央集約化する**という一般的な解決策を採用します。データフローは以下のようになります:
これらを解決すれば、他の問題もすでに解決されているか、解決が容易になる可能性があります。これらの問題を解決するためのアプローチは多数ありますが、ここでは**データとその変更方法を中央集約化する**という一般的な解決策を採用します。データフローはのようになります:
![HTML、ユーザーアクション、状態間のデータフローを示すスキーマ](../../../../7-bank-project/4-state-management/images/data-flow.png)
![HTML、ユーザーアクション、状態間のデータフローを示すスキーマ](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.ja.png)
> データが自動的にビュー更新する部分については、[リアクティブプログラミング](https://en.wikipedia.org/wiki/Reactive_programming)のより高度な概念に関連しているため、ここでは取り上げません。深く掘り下げたい場合には良いフォローアップのテーマです。
> データが自動的にビュー更新をトリガーする部分については、[リアクティブプログラミング](https://en.wikipedia.org/wiki/Reactive_programming)のより高度な概念に関連しているため、ここでは取り上げません。深く掘り下げたい場合には良いフォローアップのテーマです。
✅ 状態管理にはさまざまなアプローチを持つ多くのライブラリがありますが、[Redux](https://redux.js.org)はその中でも人気のある選択肢です。使用されている概念やパターンを調べてみてください。大規模なウェブアプリで直面する可能性のある問題や、それをどのように解決できるかを学ぶ良い方法です
✅ 状態管理にはさまざまなアプローチを持つ多くのライブラリがありますが、[Redux](https://redux.js.org)はその中でも人気のある選択肢です。大規模なウェブアプリで直面する可能性のある問題とその解決方法を学ぶために、使用される概念やパターンを確認してみてください
### タスク
まずは少しリファクタリングを行います。`account`の宣言を以下のように置き換えます:
まずは少しリファクタリングを行います。`account`の宣言をのように置き換えます:
```js
let account = null;
```
以下に置き換えます
次のように
```js
let state = {
@ -75,23 +75,23 @@ let state = {
};
```
このアイデアは、アプリのすべてのデータを単一の状態オブジェクトに*中央集約化*することです。現在のところ状態には`account`しかありませんが、これにより将来の拡張が可能になります。
このアイデアは、アプリのすべてのデータを単一の状態オブジェクトに*中央集約化*することです。現在の状態には`account`しかないため、あまり変わりませんが、進化の道筋を作ります。
また、これを使用する関数も更新する必要があります。`register()`および`login()`関数では、`account = ...`を`state.account = ...`に置き換えます。
また、それを使用する関数を更新する必要があります。`register()`および`login()`関数では、`account = ...`を`state.account = ...`に置き換えます。
`updateDashboard()`関数の冒頭に以下の行を追加します:
`updateDashboard()`関数の冒頭にの行を追加します:
```js
const account = state.account;
```
このリファクタリング自体は大きな改善をもたらしませんが、次の変更の基盤を築くことが目的です
このリファクタリング自体は大きな改善をもたらしませんでしたが、次の変更の基盤を整えることが目的でした
## データ変更の追跡
## データ変更を追跡する
`state`オブジェクトをデータの保存に使用するようにしたので、次のステップは更新を中央集約化することです。これにより、変更内容とそのタイミングを追跡しやすくなります。
`state`オブジェクトをデータの保存に使用するようにしたので、次のステップは更新を中央集約化することです。これにより、変更内容とその発生時期を追跡しやすくすることが目的です。
`state`オブジェクトに変更を加えないようにするために、それを[*不変*](https://en.wikipedia.org/wiki/Immutable_object)と見なすのも良いプラクティスです。つまり、全く変更できないということです。これにより、状態オブジェクトに何かを変更したい場合は新しい状態オブジェクトを作成する必要があります。この方法を採用することで、意図しない[*副作用*](https://en.wikipedia.org/wiki/Side_effect_(computer_science))を防ぐ保護が構築され、アプリに新しい機能(例えば、元に戻す/やり直しの実装)を追加する可能性が開かれます。また、デバッグが容易になります。例えば、状態に加えられたすべての変更をログに記録し、変更履歴を保持することで、バグの原因を理解することができます。
`state`オブジェクトに変更を加えないようにするために、それを[*不変*](https://en.wikipedia.org/wiki/Immutable_object)と見なすことも良いプラクティスです。つまり、まったく変更できないということです。また、状態オブジェクトを変更したい場合は、新しい状態オブジェクトを作成する必要があります。これにより、望ましくない[*副作用*](https://en.wikipedia.org/wiki/Side_effect_(computer_science))を防ぐ保護が構築され、アプリに新しい機能(例えば、元に戻す/やり直しの実装)を追加する可能性が開かれます。また、デバッグが容易になります。例えば、状態に加えられたすべての変更をログに記録し、変更履歴を保持してバグの原因を理解することができます。
JavaScriptでは、[`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)を使用してオブジェクトの不変バージョンを作成できます。不変オブジェクトに変更を加えようとすると、例外が発生します。
@ -110,9 +110,9 @@ function updateState(property, newData) {
}
```
この関数では、新しい状態オブジェクトを作成し、[*スプレッド演算子*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals)を使用して前の状態からデータをコピーします。その後、[ブラケット記法](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties)を使用して状態オブジェクトの特定のプロパティを新しいデータで上書きします。最後に、`Object.freeze()`を使用してオブジェクトをロックし、変更を防ぎます。現在のところ状態には`account`プロパティしか保存されていませんが、このアプローチを使用すれば、状態に必要なプロパティをいくでも追加できます。
この関数では、新しい状態オブジェクトを作成し、[*スプレッド演算子 (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals)を使用して前の状態からデータをコピーします。その後、[ブラケット記法](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]`を使用して状態オブジェクトの特定のプロパティを新しいデータで上書きします。最後に、`Object.freeze()`を使用してオブジェクトをロックし、変更を防ぎます。現在の状態には`account`プロパティしか保存されていませんが、このアプローチを使用すれば、状態に必要なプロパティをいくでも追加できます。
また、初期状態が凍結されていることを確認するために、`state`の初期化を更新します:
初期状態も不変であることを確認するために、`state`の初期化を更新します:
```js
let state = Object.freeze({
@ -120,21 +120,21 @@ let state = Object.freeze({
});
```
その後、`register`関数を更新し、`state.account = result;`の代わりに以下を使用します:
その後、`register`関数を更新し、`state.account = result;`の代わりに次のコードを使用します:
```js
updateState('account', result);
```
同様に、`login`関数では`state.account = data;`を以下に置き換えます:
同様に、`login`関数を更新し、`state.account = data;`の代わりに次のコードを使用します:
```js
updateState('account', data);
```
次に、ユーザーが*ログアウト*をクリックしたときにアカウントデータがクリアされない問題を修正します。
次に、ユーザーが*ログアウト*をクリックしたときにアカウントデータがクリアされないという問題を修正します。
新しい関数`logout()`を作成します:
新しい`logout()`関数を作成します:
```js
function logout() {
@ -147,27 +147,27 @@ function logout() {
新しいアカウントを登録し、ログアウトして再度ログインして、すべてが正しく動作することを確認してください。
> ヒント:ブラウザの開発ツールでコンソールを開き、`updateState()`の末尾に`console.log(state)`を追加することで、すべての状態変更を確認できます。
> ヒント:ブラウザの開発ツールでコンソールを開き、`updateState()`の最後に`console.log(state)`を追加して、すべての状態変更を確認できます。
## 状態を永続化する
## 状態を保持する
ほとんどのウェブアプリは、正しく動作するためにデータを永続化する必要があります。すべての重要なデータは通常データベースに保存され、サーバーAPIを介してアクセスされます。例えば、今回のケースではユーザーアカウントデータが該当します。しかし、ブラウザで実行されているクライアントアプリにデータを永続化することも、ユーザーエクスペリエンスを向上させたり、読み込みパフォーマンスを改善したりするために興味深い場合があります。
ほとんどのウェブアプリは、正しく動作するためにデータを保持する必要があります。すべての重要なデータは通常データベースに保存され、サーバーAPIを介してアクセスされます。例えば、私たちの場合はユーザーアカウントデータです。しかし、ブラウザで実行されているクライアントアプリにデータを保持することも、ユーザーエクスペリエンスを向上させたり、読み込みパフォーマンスを改善したりするために興味深い場合があります。
ブラウザ内でデータを永続化したい場合、以下のような重要な質問を自分に問いかけるべきです:
ブラウザにデータを保持したい場合、いくつかの重要な質問を自問する必要があります:
- *データは機密性が高いか?* クライアントにユーザーパスワードなどの機密データを保存するのは避けるべきです。
- *このデータをどのくらいの期間保持する必要があるか?* このデータを現在のセッションでのみアクセスする予定なのか、それとも永続的に保存したいのか?
- *データは機密性が高いか?* ユーザーパスワードなどの機密データをクライアントに保存することは避けるべきです。
- *このデータをどのくらいの期間保持する必要があるか?* このデータを現在のセッションでのみアクセスする予定ですか、それとも永続的に保存したいですか?
ウェブアプリ内で情報を保存する方法は、達成したいことに応じてさまざまです。例えば、検索クエリをURLに保存して、他のユーザーと共有可能にすることができます。また、[HTTPクッキー](https://developer.mozilla.org/docs/Web/HTTP/Cookies)を使用して、認証情報のようにサーバーと共有する必要があるデータを保存することもできます。
ウェブアプリ内で情報を保存する方法は、目的に応じてさまざまです。例えば、検索クエリをURLに保存し、ユーザー間で共有可能にすることができます。また、[HTTPクッキー](https://developer.mozilla.org/docs/Web/HTTP/Cookies)を使用して、サーバーと共有する必要があるデータ(例えば[認証](https://en.wikipedia.org/wiki/Authentication)情報)を保存することもできます。
もう1つのオプションは、データを保存するためのブラウザAPIの1つを使用することです。その中でも特に興味深いのは以下の2つです:
もう一つの選択肢は、データを保存するためのブラウザAPIのいずれかを使用することです。特に興味深いものが2つあります:
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage):現在のウェブサイトに特化したデータを異なるセッション間で永続化するための[キー/値ストア](https://en.wikipedia.org/wiki/Key%E2%80%93value_database)。保存されたデータは期限切れになりません。
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage)`localStorage`と同じように動作しますが、保存されたデータはセッションが終了すると(ブラウザが閉じられると)クリアされます。
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage):現在のウェブサイトに特化したデータをセッション間で永続的に保存できる[キー/値ストア](https://en.wikipedia.org/wiki/Key%E2%80%93value_database)。保存されたデータは期限切れになりません。
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage)`localStorage`と同じように動作しますが、保存されたデータはセッション終了時(ブラウザが閉じられたとき)にクリアされます。
これらのAPIはどちらも[文字列](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)のみを保存できることに注意してください。複雑なオブジェクトを保存したい場合は、[`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)を使用して[JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON)形式にシリアライズする必要があります。
これらのAPIはどちらも[文字列](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)のみを保存できることに注意してください。複雑なオブジェクトを保存したい場合は、[`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)を使用して[JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON)形式にシリアル化する必要があります。
✅ サーバーを使用しないウェブアプリを作成したい場合、[`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API)を使用してクライアントにデータベースを作成することも可能です。これは高度なユースケースや大量のデータを保存する必要がある場合に予約されていますが、使用するのはより複雑です。
✅ サーバーを使用しないウェブアプリを作成したい場合、[`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API)を使用してクライアントにデータベースを作成することも可能です。これは高度なユースケースや大量のデータを保存する必要がある場合に予約されていますが、使用するのはより複雑です。
### タスク
@ -177,15 +177,15 @@ function logout() {
const storageKey = 'savedAccount';
```
次に、`updateState()`関数の末尾に以下の行を追加します:
次に、`updateState()`関数の最後に次の行を追加します:
```js
localStorage.setItem(storageKey, JSON.stringify(state.account));
```
これにより、ユーザーアカウントデータが永続化され、以前に中央集約化したすべての状態更新のおかげで常に最新の状態になります。この時点で、これまでのリファクタリングの恩恵を受け始めています🙂。
これにより、ユーザーアカウントデータが保持され、以前に中央集約化したすべての状態更新のおかげで常に最新の状態になります。この時点で、これまでのリファクタリングの恩恵を受け始めています 🙂。
データが保存されるので、アプリが読み込まれたときにそれを復元することも必要です。初期化コードが増え始めるので、`app.js`の末尾にあった以前のコードを含む新しい`init`関数を作成するのが良いアイデアかもしれません:
データが保存されるので、アプリが読み込まれたときにそれを復元することも重要です。初期化コードが増え始めるので、`app.js`の下部にある以前のコードも含めて新しい`init`関数を作成するのが良いアイデアかもしれません:
```js
function init() {
@ -202,17 +202,17 @@ function init() {
init();
```
ここでは保存されたデータを取得し、もしあれば状態をそれに応じて更新します。ページ更新中に状態に依存するコードがある可能性があるため、ルートを更新する*前*にこれを行うことが重要です。
ここでは保存されたデータを取得し、データがあれば状態を適切に更新します。ページ更新中に状態に依存するコードがある可能性があるため、ルートを更新する*前に*これを行うことが重要です。
また、アカウントデータを永続化するようになったので、*ダッシュボード*ページをアプリケーションのデフォルトページにすることもできます。データが見つからない場合、ダッシュボードはログインページにリダイレクトする処理を行います。`updateRoute()`では、フォールバック`return navigate('/login');`を`return navigate('/dashboard');`に置き換えます。
また、アカウントデータを保持するようになったので、*ダッシュボード*ページをアプリケーションのデフォルトページにすることもできます。データが見つからない場合、ダッシュボードはログインページへのリダイレクトを処理します。`updateRoute()`では、フォールバック`return navigate('/login');`を`return navigate('/dashboard');`に置き換えます。
アプリにログインしてページをリフレッシュしてみてください。ダッシュボードに留まるはずです。この更新により、すべての初期問題に対処しました...
アプリにログインしてページをリフレッシュしてみてください。ダッシュボードに留まるはずです。この更新により、すべての初期問題を解決しました...
## データをリフレッシュする
...しかし、新しい問題を作り出してしまったかもしれません。おっと!
`test`アカウントを使用してダッシュボードに移動し、次に以下のコマンドをターミナルで実行して新しいトランザクションを作成します:
`test`アカウントを使用してダッシュボードに移動し、次のコマンドをターミナルで実行して新しいトランザクションを作成します:
```sh
curl --request POST \
@ -221,15 +221,15 @@ curl --request POST \
http://localhost:5000/api/accounts/test/transactions
```
その後、ブラウザでダッシュボードページをリフレッシュしてみてください。何が起こりますか?新しいトランザクションが表示されますか?
ブラウザでダッシュボードページをリフレッシュしてみてください。何が起こりますか?新しいトランザクションが表示されますか?
状態は`localStorage`のおかげで無期限に永続化されますが、それはログアウトして再度ログインするまで更新されないことも意味します!
状態は`localStorage`のおかげで無期限に保持されますが、それはログアウトして再度ログインするまで更新されないことも意味します!
これを修正する1つの戦略は、ダッシュボードが読み込まれるたびにアカウントデータを再読み込みすることです。これにより、古いデータを回避できます。
これを修正するための一つの戦略は、ダッシュボードが読み込まれるたびにアカウントデータを再読み込みし、古いデータを避けることです。
### タスク
新しい関数`updateAccountData`を作成します:
新しい`updateAccountData`関数を作成します:
```js
async function updateAccountData() {
@ -258,7 +258,7 @@ async function refresh() {
}
```
この関数はアカウントデータを更新し、その後ダッシュボードページのHTMLを更新します。これはダッシュボードルートが読み込まれたときに呼び出す必要があります。ルート定義を以下のように更新します:
この関数はアカウントデータを更新し、その後ダッシュボードページのHTMLを更新します。これはダッシュボードルートが読み込まれたときに呼び出す必要があります。ルート定義をのように更新します:
```js
const routes = {
@ -267,24 +267,28 @@ const routes = {
};
```
これでダッシュボードをリロードしてみてください。更新されたアカウントデータが表示されるはずです。
ダッシュボードをリロードしてみてください。更新されたアカウントデータが表示されるはずです。
---
## 🚀 チャレンジ
ダッシュボードが読み込まれるたびにアカウントデータを再読み込みするようになった今、*すべてのアカウントデータ*を永続化する必要がまだあると思いますか?
ダッシュボードが読み込まれるたびにアカウントデータを再読み込みするようになった今、*すべてのアカウント*データを保持する必要があると思いますか?
アプリが動作するために絶対に必要なものだけを`localStorage`に保存および読み込むように変更してみてください。
[講義後のクイズ](https://ff-quizzes.netlify.app/web/quiz/48)
チームで協力して、`localStorage`に保存および読み込む内容をアプリが動作するために絶対に必要なものだけに変更してみてください。
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/48)
## 課題
[「取引を追加」ダイアログの実装](assignment.md)
[「取引を追加」ダイアログを実装する](assignment.md)
以下は、課題を完了した後の例としての結果です:
課題を完了した後の例はこちらです:
![「取引を追加」ダイアログの例を示すスクリーンショット](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.ja.png)
![「取引を追加」ダイアログの例を示すスクリーンショット](../../../../7-bank-project/4-state-management/images/dialog.png)
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解について、当社は責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解について、当社は責任を負いません。

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "7aa6e4f270d38d9cb17f2b5bd86b863d",
"translation_date": "2025-08-23T23:33:31+00:00",
"original_hash": "1ba61d96a11309a2a6ea507496dcf7e5",
"translation_date": "2025-08-28T17:58:51+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/README.md",
"language_code": "ja"
}
-->
# コードエディタの使用
このレッスンでは、ウェブベースのコードエディタである [VSCode.dev](https://vscode.dev) の基本を学びます。これにより、コンピュータに何もインストールせずにコードを変更したり、プロジェクトに貢献したりすることができます。
このレッスンでは、[VSCode.dev](https://vscode.dev) というウェブベースのコードエディタの基本を学びます。これにより、コンピュータに何もインストールせずにコードを変更したり、プロジェクトに貢献したりすることができます。
## 学習目標
@ -25,23 +25,23 @@ CO_OP_TRANSLATOR_METADATA:
### はじめに
コードエディタは、プログラムを書くため、また既存のコーディングプロジェクトと協力するための重要なツールです。エディタの基本とその機能の使い方を理解すれば、コードを書く際にそれらを活用できるようになります。
コードエディタは、プログラムを書くための基本的なツールであり、既存のコーディングプロジェクトに協力するためにも重要です。エディタの基本とその機能の使い方を理解すれば、コードを書く際にそれらを活用できるようになります。
## VSCode.dev の使い方
[VSCode.dev](https://vscode.dev) はウェブ上で動作するコードエディタです。ウェブサイトを開くのと同じように、何もインストールせずに使用できます。エディタを始めるには、次のリンクを開いてください:[https://vscode.dev](https://vscode.dev)。[GitHub](https://github.com/) にサインインしていない場合は、指示に従ってサインインするか、新しいアカウントを作成してサインインしてください。
[VSCode.dev](https://vscode.dev) はウェブ上で動作するコードエディタです。ウェブサイトを開くのと同じように、何もインストールせずに使用できます。エディタを使い始めるには、次のリンクを開いてください:[https://vscode.dev](https://vscode.dev)。[GitHub](https://github.com/) にサインインしていない場合は、指示に従ってサインインするか、新しいアカウントを作成してサインインしてください。
ロードが完了すると、次のような画面が表示されます:
![デフォルトの VSCode.dev](../../../../8-code-editor/images/default-vscode-dev.png)
![Default VSCode.dev](../../../../translated_images/default-vscode-dev.5d06881d65c1b3234ce50cd9ed3b0028e6031ad5f5b441bcbed96bfa6311f6d0.ja.png)
左から右に向かって、主に3つのセクションがあります:
画面は左から右に向かって、主に以下の3つのセクションに分かれています:
1. _アクティビティバー_:虫眼鏡アイコン 🔎、歯車アイコン ⚙️ などのアイコンが含まれています。
1. _アクティビティバー_:虫眼鏡アイコン(🔎)、歯車アイコン(⚙️)などのアイコンが含まれています。
2. 展開されたアクティビティバー(デフォルトでは _エクスプローラー_で、_サイドバー_ と呼ばれます。
3. 右側のコードエリア。
各アイコンをクリックして異なるメニューを表示します。終わったら、_エクスプローラー_ をクリックして元の状態に戻ります
各アイコンをクリックすると、異なるメニューが表示されます。すべて確認したら、_エクスプローラー_ をクリックして元の状態に戻してください
コードを作成したり既存のコードを変更したりする際は、右側の最も大きなエリアを使用します。このエリアを使って既存のコードを確認することもできます。次にそれを行います。
@ -49,15 +49,15 @@ CO_OP_TRANSLATOR_METADATA:
最初に必要なのは、GitHub リポジトリを開くことです。リポジトリを開く方法はいくつかあります。このセクションでは、リポジトリを開いて変更作業を始めるための2つの方法を紹介します。
### 1. エディタを使用する
### 1. エディタを使
エディタ自体を使ってリモートリポジトリを開きます。[VSCode.dev](https://vscode.dev) にアクセスすると、_"Open Remote Repository"_ ボタンが表示されます:
![リモートリポジトリを開く](../../../../8-code-editor/images/open-remote-repository.png)
![Open remote repository](../../../../translated_images/open-remote-repository.bd9c2598b8949e7fc283cdfc8f4050c6205a7c7c6d3f78c4b135115d037d6fa2.ja.png)
また、コマンドパレットを使用することもできます。コマンドパレットは、コマンドやアクションの一部を入力して適切なコマンドを実行するための入力ボックスです。左上のメニューを使用して _View_ を選択し、_Command Palette_ を選択します。または、次のキーボードショートカットを使用しますCtrl-Shift-PMacOS は Command-Shift-P
また、コマンドパレットを使用することもできます。コマンドパレットは、コマンドやアクションの一部の単語を入力して、実行するコマンドを見つけるための入力ボックスです。左上のメニューから _View_ を選択し、_Command Palette_ を選択します。または、次のキーボードショートカットを使用しますCtrl-Shift-PMacOS の場合は Command-Shift-P
![パレットメニュー](../../../../8-code-editor/images/palette-menu.png)
![Palette Menu](../../../../translated_images/palette-menu.4946174e07f426226afcdad707d19b8d5150e41591c751c45b5dee213affef91.ja.png)
メニューが開いたら、_open remote repository_ と入力し、最初のオプションを選択します。あなたが参加している、または最近開いたリポジトリが複数表示されます。完全な GitHub URL を使用して選択することもできます。次の URL をボックスに貼り付けてください:
@ -65,82 +65,79 @@ CO_OP_TRANSLATOR_METADATA:
https://github.com/microsoft/Web-Dev-For-Beginners
```
✅ 成功すると、このリポジトリのすべてのファイルがテキストエディタにロードされます。
✅ 成功すると、このリポジトリのすべてのファイルがテキストエディタに読み込まれます。
### 2. URL を使用する
URL を直接使用してリポジトリをロードすることもできます。たとえば、現在のリポジトリの完全な URL は [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners) ですが、GitHub ドメインを `VSCode.dev/github` に置き換えることで、リポジトリを直接ロードできます。結果の URL は次のようになります:[https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners)。
URL を直接使用してリポジトリを読み込むこともできます。たとえば、現在のリポジトリの完全な URL は [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners) ですが、GitHub ドメインを `VSCode.dev/github` に置き換えることで、リポジトリを直接読み込むことができます。結果として得られる URL は次のようになります:[https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners)。
## ファイルを編集する
ブラウザまたは vscode.dev でリポジトリを開いたら、次のステップはプロジェクトを更新または変更することです。
リポジトリをブラウザまたは vscode.dev で開いたら、次のステップはプロジェクトの更新や変更を行うことです。
### 1. 新しいファイルを作成する
既存のフォルダ内にファイルを作成するか、ルートディレクトリ/フォルダに作成することができます。新しいファイルを作成するには、保存したい場所/ディレクトリを開き、アクティビティバー(左)の _'New file ...'_ アイコンを選択し、名前を付けて Enter を押します。
既存のフォルダ内にファイルを作成するか、ルートディレクトリ/フォルダに作成することができます。新しいファイルを作成するには、保存したい場所/ディレクトリを開き、アクティビティバー(左)の _'New file ...'_ アイコンを選択し、名前を付けて Enter を押します。
![新しいファイルを作成](../../../../8-code-editor/images/create-new-file.png)
![Create a new file](../../../../translated_images/create-new-file.2814e609c2af9aeb6c6fd53156c503ac91c3d538f9cac63073b2dd4a7631f183.ja.png)
### 2. リポジトリ内のファイルを編集して保存する
vscode.dev を使用すると、ローカルにソフトウェアをロードすることなく、プロジェクトを迅速に更新する際に便利です。
コードを更新するには、アクティビティバーにある 'Explorer' アイコンをクリックして、リポジトリ内のファイルとフォルダを表示します。
ファイルを選択してコードエリアで開き、変更を加えて保存します。
vscode.dev を使用すると、ローカルにソフトウェアをロードすることなく、プロジェクトを迅速に更新するのに便利です。コードを更新するには、アクティビティバーにある 'Explorer' アイコンをクリックして、リポジトリ内のファイルとフォルダを表示します。ファイルを選択してコードエリアで開き、変更を加えて保存します。
![ファイルを編集](../../../../8-code-editor/images/edit-a-file.png)
![Edit a file](../../../../translated_images/edit-a-file.52c0ee665ef19f08119d62d63f395dfefddc0a4deb9268d73bfe791f52c5807a.ja.png)
プロジェクトの更新が完了したら、リポジトリに加えたすべての新しい変更を含む _`source control`_ アイコンを選択します。
プロジェクトの更新が完了したら、リポジトリに加えた新しい変更を含む _`source control`_ アイコンを選択します。
プロジェクトに加えた変更を確認するには、展開されたアクティビティバーの `Changes` フォルダ内のファイルを選択します。これにより、ファイルに加えた変更を視覚的に確認できる 'Working Tree' が開きます。赤はプロジェクトからの削除を示し、緑は追加を示します。
プロジェクトに加えた変更を確認するには、展開されたアクティビティバー`Changes` フォルダ内のファイルを選択します。これにより、変更内容を視覚的に確認できる 'Working Tree' が開きます。赤はプロジェクトからの削除を示し、緑は追加を示します。
![変更を確認](../../../../8-code-editor/images/working-tree.png)
![View changes](../../../../translated_images/working-tree.c58eec08e6335c79cc708c0c220c0b7fea61514bd3c7fb7471905a864aceac7c.ja.png)
変更に満足したら、`Changes` フォルダにカーソルを合わせて `+` ボタンをクリックして変更をステージングします。ステージングとは、変更を GitHub にコミットする準備をすることを意味します。
変更に満足できない場合や破棄したい場合は、`Changes` フォルダにカーソルを合わせて `undo` アイコンを選択します。
その後、`commit message`(プロジェクトに加えた変更の説明)を入力し、`チェックアイコン` をクリックして変更をコミットしてプッシュします。
その後、`commit message`(プロジェクトに加えた変更の説明)を入力し、`check icon` をクリックして変更をコミットしてプッシュします。
プロジェクトの作業が完了したら、左上の `ハンバーガーメニューアイコン` を選択して github.com 上のリポジトリに戻ります。
作業が完了したら、左上の `ハンバーガーメニューアイコン` を選択して github.com 上のリポジトリに戻ります。
![変更をステージング&コミット](../../../../8-code-editor/images/edit-vscode.dev.gif)
![Stage & commit changes](../../../../8-code-editor/images/edit-vscode.dev.gif)
## 拡張機能の使用
VSCode に拡張機能をインストールすると、エディタに新しい機能を追加したり、開発環境をカスタマイズしたりして、開発ワークフローを向上させることができます。これらの拡張機能は、複数のプログラミング言語をサポートするのにも役立ち、一般的な拡張機能や言語ベースの拡張機能があります。
利用可能なすべての拡張機能のリストを閲覧するには、アクティビティバーの _`Extensions icon`_ をクリックし、_`Search Extensions in Marketplace`_ とラベル付けされたテキストフィールドに拡張機能の名前を入力します。
拡張機能のリストには、**拡張機能名、発行者名、1文の説明、ダウンロード数**、および**星評価**が表示されます。
利用可能なすべての拡張機能のリストを閲覧するには、アクティビティバーの _`Extensions icon`_ をクリックし、_`Search Extensions in Marketplace`_ とラベル付けされたテキストフィールドに拡張機能の名前を入力します。拡張機能のリストには、**拡張機能名、発行者名、1文の説明、ダウンロード数**、および **星評価** が表示されます。
![拡張機能の詳細](../../../../8-code-editor/images/extension-details.png)
![Extension details](../../../../translated_images/extension-details.9f8f1fd4e9eb2de5069ae413119eb8ee43172776383ebe2f7cf640e11df2e106.ja.png)
また、_`Installed folder`_ 展開して以前にインストールしたすべての拡張機能を表示したり、_`Popular folder`_ 多くの開発者が使用している人気の拡張機能を確認したり、_`recommended folder`_ で同じワークスペースのユーザーや最近開いたファイルに基づいて推奨される拡張機能を確認したりできます。
また、_`Installed folder`_ 展開して以前にインストールしたすべての拡張機能を表示したり、_`Popular folder`_ にある多くの開発者が使用している人気の拡張機能を確認したり、同じワークスペースのユーザーや最近開いたファイルに基づいて推奨される拡張機能を _`recommended folder`_確認したりできます。
![拡張機能を表示](../../../../8-code-editor/images/extensions.png)
![View extensions](../../../../translated_images/extensions.eca0e0c7f59a10b5c88be7fe24b3e32cca6b6058b35a49026c3a9d80b1813b7c.ja.png)
### 1. 拡張機能をインストールする
拡張機能をインストールするには、検索フィールドに拡張機能の名前を入力し、拡張機能が展開されたアクティビティバーに表示されたらクリックして、コードエリアで拡張機能の追加情報を表示します。
拡張機能をインストールするには、検索フィールドに拡張機能の名前を入力し、展開されたアクティビティバーに表示されたらクリックして、コードエリアで拡張機能の追加情報を表示します。
展開されたアクティビティバーの _青いインストールボタン_ をクリックするか、拡張機能を選択してコードエリアに追加情報をロードした後に表示されるインストールボタンを使用してインストールします。
展開されたアクティビティバーの _青いインストールボタン_ をクリックするか、拡張機能を選択してコードエリアに追加情報を読み込んだ後に表示されるインストールボタンを使用してインストールします。
![拡張機能をインストール](../../../../8-code-editor/images/install-extension.gif)
![Install extensions](../../../../8-code-editor/images/install-extension.gif)
### 2. 拡張機能をカスタマイズする
拡張機能をインストールした後、その動作を変更し、好みに基づいてカスタマイズする必要がある場合があります。これを行うには、拡張機能アイコンを選択し、今回は _Installed folder_ に表示される拡張機能をクリックし、_**ギアアイコン**_ をクリックして _Extensions Setting_ に移動します。
拡張機能をインストールした後、その動作を変更し、好みに応じてカスタマイズする必要がある場合があります。これを行うには、拡張機能アイコンを選択し、_Installed folder_ に表示される拡張機能をクリックして _**Gear icon**_ を選択し、_Extensions Setting_ に移動します。
![拡張機能の設定を変更](../../../../8-code-editor/images/extension-settings.png)
![Modify extension settings](../../../../translated_images/extension-settings.21c752ae4f4cdb78a867f140ccd0680e04619d0c44bb4afb26373e54b829d934.ja.png)
### 3. 拡張機能を管理する
拡張機能をインストールして使用した後、vscode.dev はさまざまなニーズに基づいて拡張機能を管理するオプションを提供します。たとえば、次のような選択肢があります:
拡張機能をインストールして使用した後、vscode.dev はさまざまなニーズに基づいて拡張機能を管理するオプションを提供します。たとえば、以下のような選択が可能です:
- **無効化:** _(一時的に拡張機能を無効化し、完全にアンインストールしたくない場合)_
- **無効化する:** _(一時的に拡張機能を無効化し、完全にアンインストールする必要がない場合に使用します)_
展開されたアクティビティバーでインストール済みの拡張機能を選択 > ギアアイコンをクリック > 'Disable' または 'Disable (Workspace)' を選択 **または** コードエリアで拡張機能を開き、青い Disable ボタンをクリック。
展開されたアクティビティバーでインストール済みの拡張機能を選択 > ギアアイコンをクリック > 'Disable' または 'Disable (Workspace)' を選択 **または** コードエリアで拡張機能を開き、青い Disable ボタンをクリックします
- **アンインストール:** 展開されたアクティビティバーでインストール済みの拡張機能を選択 > ギアアイコンをクリック > 'Uninstall' を選択 **または** コードエリアで拡張機能を開き、青い Uninstall ボタンをクリック。
- **アンインストールする:** 展開されたアクティビティバーでインストール済みの拡張機能を選択 > ギアアイコンをクリック > 'Uninstall' を選択 **または** コードエリアで拡張機能を開き、青い Uninstall ボタンをクリックします
---
@ -152,5 +149,7 @@ VSCode に拡張機能をインストールすると、エディタに新しい
[VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) とその他の機能についてさらに学びましょう。
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてお考えください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。

@ -1,25 +1,25 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2fcb983b8dbadadb1bc2e97f8c12dac5",
"translation_date": "2025-08-23T23:36:14+00:00",
"original_hash": "bd3aa6d2b879c30ea496c43aec1c49ed",
"translation_date": "2025-08-28T17:59:29+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/assignment.md",
"language_code": "ja"
}
-->
# vscode.devを使って履歴書ウェブサイトを作成する
# VSCode.devを使って履歴書ウェブサイトを作成する
_採用担当者が履歴書を求めてきたときに、URLを送るだけで済むなんて素敵じゃないですか_ 😎
<!----
TODO: オプションの画像を追加
![コードエディタを使用する](../../../../sketchnotes/webdev101-vscode-dev.png)
> スケッチノート by [Author name](https://example.com)
![コードエディタを使用する](../../../../translated_images/webdev101-vscode-dev.f53c14e8dad231ea09d9e07a2db4a01551d2dc6cdf21225038389e11156af023.ja.png)
> スケッチノート作成者 [Author name](https://example.com)
---->
<!---
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/3)
## 講義前クイズ
[講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/3)
---->
## 目標
@ -30,17 +30,17 @@ TODO: オプションの画像を追加
### 前提条件
1. GitHubアカウント。まだアカウントを作成していない場合は、[GitHub](https://github.com/)にアクセスしてアカウントを作成してください。
1. GitHubアカウント。まだ作成していない場合は、[GitHub](https://github.com/)にアクセスしてアカウントを作成してください。
## 手順
**ステップ1:** 新しいGitHubリポジトリを作成し、名前を`my-resume`と付けます。
**ステップ1:** 新しいGitHubリポジトリを作成し、名前を`my-resume`と付け
**ステップ2:** リポジトリ内に`index.html`ファイルを作成します。github.com上で少なくとも1つのファイルを追加する必要があります。空のリポジトリはvscode.devで開くことができないためです。
**ステップ2:** リポジトリ内に`index.html`ファイルを作成す。github.com上で少なくとも1つのファイルを追加する必要があります。空のリポジトリはvscode.devで開くことができないためです。
`新しいファイルを作成する`リンクをクリックし、名前を`index.html`と入力して`新しいファイルをコミット`ボタンを選択します。
`新しいファイルを作成`リンクをクリックし、名前を`index.html`と入力して`新しいファイルをコミット`ボタンを選択します。
![github.comで新しいファイルを作成する](../../../../8-code-editor/images/new-file-github.com.png)
![github.comで新しいファイルを作成](../../../../translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.ja.png)
**ステップ3:** [VSCode.dev](https://vscode.dev)を開き、`リモートリポジトリを開く`ボタンを選択します。
@ -54,24 +54,24 @@ https://github.com/your-username/my-resume
✅ 成功すると、ブラウザ上のテキストエディタにプロジェクトと`index.html`ファイルが表示されます。
![新しいファイルを作成する](../../../../8-code-editor/images/project-on-vscode.dev.png)
![新しいファイルを作成](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.ja.png)
**ステップ4:** `index.html`ファイルを開き、以下のコードをコードエリアに貼り付けて保存します。
<details>
<summary><b>履歴書ウェブサイトのコンテンツを担当するHTMLコード。</b></summary>
<summary><b>履歴書ウェブサイトの内容を担当するHTMLコード。</b></summary>
<html>
<head>
<link href="style.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<title>あなたの名前をここに記入!</title>
<title>ここにあなたの名前を入力してください</title>
</head>
<body>
<header id="header">
<!-- 履歴書のヘッダー:名前と役職 -->
<h1>あなたの名前をここに記入!</h1>
<h1>ここにあなたの名前を入力してください</h1>
<hr>
あなたの役職!
<hr>
@ -83,15 +83,15 @@ https://github.com/your-username/my-resume
<!-- 連絡先情報(ソーシャルメディア含む) -->
<p>
<i class="fa fa-envelope" aria-hidden="true"></i>
<a href="mailto:username@domain.top-level domain">メールアドレスをここに記</a>
<a href="mailto:username@domain.top-level domain">ここにあなたのメールアドレスを入力してください</a>
</p>
<p>
<i class="fab fa-github" aria-hidden="true"></i>
<a href="github.com/yourGitHubUsername">GitHubユーザー名をここに記入!</a>
<a href="github.com/yourGitHubUsername">ここにあなたのGitHubユーザー名を入力してください</a>
</p>
<p>
<i class="fab fa-linkedin" aria-hidden="true"></i>
<a href="linkedin.com/yourLinkedInUsername">LinkedInユーザー名をここに記入!</a>
<a href="linkedin.com/yourLinkedInUsername">ここにあなたのLinkedInユーザー名を入力してください</a>
</p>
</section>
<section>
@ -107,9 +107,9 @@ https://github.com/your-username/my-resume
<section>
<h2>学歴</h2>
<!-- あなたの学歴 -->
<h3>コース名をここに記入!</h3>
<h3>ここにコース名を入力してください</h3>
<p>
学校名をここに記入!
ここに学校名を入力してください
</p>
<p>
開始日 - 終了日
@ -120,29 +120,29 @@ https://github.com/your-username/my-resume
<section>
<h2>自己紹介</h2>
<!-- あなたについて -->
<p>自己紹介文をここに記入!</p>
<p>ここに自己紹介文を入力してください</p>
</section>
<section>
<h2>職務経験</h2>
<!-- あなたの職務経験 -->
<h3>職務名</h3>
<p>
組織名をここに記入 | 開始月 終了月
ここに組織名を入力してください | 開始月 終了月
</p>
<ul>
<li>タスク1 - 実施内容を記入</li>
<li>タスク2 - 実施内容を記入</li>
<li>貢献の成果や影響を記入</li>
<li>タスク1 - 何をしたかを書いてください</li>
<li>タスク2 - 何をしたかを書いてください</li>
<li>あなたの貢献の成果や影響を書いてください</li>
</ul>
<h3>職務名2</h3>
<p>
組織名をここに記入 | 開始月 終了月
ここに組織名を入力してください | 開始月 終了月
</p>
<ul>
<li>タスク1 - 実施内容を記入</li>
<li>タスク2 - 実施内容を記入</li>
<li>貢献の成果や影響を記入</li>
<li>タスク1 - 何をしたかを書いてください</li>
<li>タスク2 - 何をしたかを書いてください</li>
<li>あなたの貢献の成果や影響を書いてください</li>
</ul>
</section>
@ -154,7 +154,7 @@ https://github.com/your-username/my-resume
HTMLコードの_プレースホルダーのテキスト_をあなたの履歴書の詳細に置き換えてください。
**ステップ5:** My-Resumeフォルダ上でホバーし、`新しいファイル...`アイコンをクリックしてプロジェクトに2つの新しいファイルを作成します`style.css`と`codeswing.json`ファイル
**ステップ5:** My-Resumeフォルダーにカーソルを合わせ、`新しいファイル...`アイコンをクリックしてプロジェクトに2つの新しいファイルを作成します`style.css`と`codeswing.json`ファイル
**ステップ6:** `style.css`ファイルを開き、以下のコードを貼り付けて保存します。
@ -230,32 +230,34 @@ HTMLコードの_プレースホルダーのテキスト_をあなたの履歴
**ステップ7:** `Codeswing拡張機能`をインストールして、コードエリアで履歴書ウェブサイトを視覚化します。
アクティビティバーの_`拡張機能`_アイコンをクリックし、Codeswingと入力します。拡張機能を選択して追加情報を読み込むと、コードエリアに表示される_青いインストールボタン_をクリックしてインストールします。拡張機能をインストールすると、プロジェクトに変更が反映されるのを確認できます 😃
アクティビティバーの_`拡張機能`_アイコンをクリックし、Codeswingと入力します。拡張機能を選択して追加情報を読み込むと、コードエリアに表示される_青いインストールボタン_をクリックするか、展開されたアクティビティバーのインストールボタンを使用してインストールします。拡張機能をインストールした直後に、プロジェクトに対する変更をコードエリアで確認できます 😃
![拡張機能をインストールする](../../../../8-code-editor/images/install-extension.gif)
![拡張機能をインストール](../../../../8-code-editor/images/install-extension.gif)
拡張機能をインストールした後、画面に以下のような表示がされます。
![Codeswing拡張機能の動作](../../../../8-code-editor/images/after-codeswing-extension-pb.png)
![Codeswing拡張機能の動作](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.ja.png)
変更内容に満足したら、`変更`フォルダ上でホバーし、`+`ボタンをクリックして変更をステージします。
変更に満足したら、`変更`フォルダーにカーソルを合わせて`+`ボタンをクリックし、変更をステージします。
コミットメッセージ _(プロジェクトに加えた変更の説明)_ を入力し、`チェック`をクリックして変更をコミットします。プロジェクトの作業が完了したら、左上のハンバーガーメニューアイコンを選択してGitHubのリポジトリに戻ります。
おめでとうございます 🎉 vscode.devを使って数ステップで履歴書ウェブサイトを作成しました。
おめでとうございます 🎉 数ステップでVSCode.devを使って履歴書ウェブサイトを作成しました。
## 🚀 チャレンジ
変更権限を持つリモートリポジトリを開き、いくつかのファイルを更新してみましょう。次に、新しいブランチを作成して変更を加え、プルリクエストを作成してください
変更権限を持つリモートリポジトリを開き、いくつかのファイルを更新してみてください。次に、新しいブランチを作成して変更を加え、プルリクエストを作成してみましょう
<!----
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/4)
## 講義後クイズ
[講義後クイズ](https://ff-quizzes.netlify.app/web/quiz/4)
---->
## 復習と自己学習
[VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza)とその他の機能についてさらに学びましょう。
[VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza)とそのその他の機能についてさらに学びましょう。
---
**免責事項**:
この文書はAI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。
この文書はAI翻訳サービス[Co-op Translator](https://github.com/Azure/co-op-translator)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書を正式な情報源としてご参照ください。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の利用に起因する誤解や誤った解釈について、当方は一切の責任を負いません。

@ -0,0 +1,389 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "cf15ff7770c5a484349383bb27d1131f",
"translation_date": "2025-08-28T18:54:40+00:00",
"source_file": "9-chat-project/README.md",
"language_code": "ja"
}
-->
# チャットプロジェクト
このチャットプロジェクトでは、GitHub Modelsを使用してチャットアシスタントを構築する方法を示します。
完成したプロジェクトは以下のようになります:
<div>
<img src="./assets/screenshot.png" alt="チャットアプリ" width="600">
</div>
少し背景を説明すると、生成AIを使用してチャットアシスタントを構築することは、AIについて学び始める素晴らしい方法です。このレッスンを通じて、生成AIをウェブアプリに統合する方法を学びます。それでは始めましょう。
## 生成AIへの接続
バックエンドにはGitHub Modelsを使用します。これは無料でAIを利用できる素晴らしいサービスです。プレイグラウンドにアクセスして、選択したバックエンド言語に対応するコードを取得してください。以下はその例です[GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground)
<div>
<img src="./assets/playground.png" alt="GitHub Models AI Playground" with="600">
</div>
「Code」タブと選択したランタイムを選びます。
<div>
<img src="./assets/playground-choice.png" alt="プレイグラウンド選択" with="600">
</div>
この場合、Pythonを選択し、以下のコードを取得します
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
# Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "",
},
{
"role": "user",
"content": "What is the capital of France?",
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
print(response.choices[0].message.content)
```
このコードを少し整理して再利用可能にします:
```python
def call_llm(prompt: str, system_message: str):
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": system_message,
},
{
"role": "user",
"content": prompt,
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
return response.choices[0].message.content
```
この関数`call_llm`を使用すると、プロンプトとシステムプロンプトを渡し、結果を返すことができます。
### AIアシスタントのカスタマイズ
AIアシスタントをカスタマイズしたい場合は、以下のようにシステムプロンプトを設定して動作を指定できます
```python
call_llm("Tell me about you", "You're Albert Einstein, you only know of things in the time you were alive")
```
## Web APIを介して公開
素晴らしいですね。AI部分が完成したので、これをWeb APIに統合する方法を見てみましょう。Web APIにはFlaskを使用しますが、他のウェブフレームワークでも問題ありません。以下はそのコードです
```python
# api.py
from flask import Flask, request, jsonify
from llm import call_llm
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
@app.route("/", methods=["GET"])
def index():
return "Welcome to this API. Call POST /hello with 'message': 'my message' as JSON payload"
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
```
ここでは、Flask APIを作成し、デフォルトルート「/」と「/chat」を定義します。「/chat」はフロントエンドが質問を渡すために使用されます。
*llm.py*を統合するには以下を行います:
- `call_llm`関数をインポート:
```python
from llm import call_llm
from flask import Flask, request
```
- 「/chat」ルートから呼び出す
```python
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
```
ここでは、受信リクエストを解析してJSONボディから`message`プロパティを取得します。その後、以下の呼び出しでLLMを使用します
```python
response = call_llm(message, "You are a helpful assistant")
# return the response as JSON
return jsonify({
"response": response
})
```
素晴らしいですね。必要なことは完了しました。
### Corsの設定
バックエンドとフロントエンドが異なるポートで動作するため、フロントエンドがバックエンドにアクセスできるようにするためにCORSクロスオリジンリソース共有を設定する必要があります。*api.py*にはこれを設定するコードがあります:
```python
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
```
現在はすべてのオリジンを許可する「*」に設定されていますが、これは安全ではないため、運用環境では制限する必要があります。
## プロジェクトを実行
さて、*llm.py*と*api.py*が揃いました。バックエンドでこれを動作させるには以下を行います:
- 依存関係をインストール:
```sh
cd backend
python -m venv venv
source ./venv/bin/activate
pip install openai flask flask-cors openai
```
- APIを起動
```sh
python api.py
```
Codespacesを使用している場合は、エディタの下部にあるPortsに移動し、右クリックして「Port Visibility」を選択し、「Public」を選択してください。
### フロントエンドの作成
APIが稼働したので、これに対応するフロントエンドを作成しましょう。最低限のフロントエンドを作成し、段階的に改善していきます。*frontend*フォルダに以下を作成してください:
```text
backend/
frontend/
index.html
app.js
styles.css
```
まず**index.html**を見てみましょう:
```html
<html>
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<form>
<textarea id="messages"></textarea>
<input id="input" type="text" />
<button type="submit" id="sendBtn">Send</button>
</form>
<script src="app.js" />
</body>
</html>
```
上記はチャットウィンドウをサポートするための最低限の構成です。メッセージを表示するテキストエリア、メッセージを入力するための入力フィールド、バックエンドにメッセージを送信するボタンで構成されています。次に*app.js*のJavaScriptを見てみましょう。
**app.js**
```js
// app.js
(function(){
// 1. set up elements
const messages = document.getElementById("messages");
const form = document.getElementById("form");
const input = document.getElementById("input");
const BASE_URL = "change this";
const API_ENDPOINT = `${BASE_URL}/hello`;
// 2. create a function that talks to our backend
async function callApi(text) {
const response = await fetch(API_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: text })
});
let json = await response.json();
return json.response;
}
// 3. add response to our textarea
function appendMessage(text, role) {
const el = document.createElement("div");
el.className = `message ${role}`;
el.innerHTML = text;
messages.appendChild(el);
}
// 4. listen to submit events
form.addEventListener("submit", async(e) => {
e.preventDefault();
// someone clicked the button in the form
// get input
const text = input.value.trim();
appendMessage(text, "user")
// reset it
input.value = '';
const reply = await callApi(text);
// add to messages
appendMessage(reply, "assistant");
})
})();
```
コードをセクションごとに説明します:
- 1) ここでは後で参照するすべての要素を取得します。
- 2) このセクションでは、組み込みの`fetch`メソッドを使用してバックエンドを呼び出す関数を作成します。
- 3) `appendMessage`は、ユーザーが入力したメッセージやレスポンスを追加するのに役立ちます。
- 4) ここではsubmitイベントを監視し、入力フィールドを読み取り、ユーザーのメッセージをテキストエリアに配置し、APIを呼び出し、レスポンスをテキストエリアに表示します。
次にスタイリングを見てみましょう。ここでは自由にデザインできますが、以下は一例です:
**styles.css**
```
.message {
background: #222;
box-shadow: 0 0 0 10px orange;
padding: 10px:
margin: 5px;
}
.message.user {
background: blue;
}
.message.assistant {
background: grey;
}
```
これらの3つのクラスを使用して、アシスタントからのメッセージとユーザーからのメッセージを異なるスタイルで表示します。インスピレーションを得たい場合は、`solution/frontend/styles.css`フォルダをチェックしてください。
### Base Urlの変更
ここで設定していないものが1つあります。それは`BASE_URL`です。バックエンドが起動するまでこれは不明です。設定方法:
- APIをローカルで実行する場合、`http://localhost:5000`のように設定します。
- Codespacesで実行する場合、`[name]app.github.dev`のようになります。
## 課題
*project*フォルダを作成し、以下のような内容を含めてください:
```text
project/
frontend/
index.html
app.js
styles.css
backend/
api.py
llm.py
```
上記の指示に従って内容をコピーしますが、自由にカスタマイズしてください。
## 解答
[Solution](./solution/README.md)
## ボーナス
AIアシスタントの性格を変更してみてください。*api.py*で`call_llm`を呼び出す際に、2番目の引数を変更することで可能です。例えば
```python
call_llm(message, "You are Captain Picard")
```
また、CSSやテキストも変更してみてください。*index.html*や*styles.css*で変更を加えてください。
## まとめ
素晴らしいですね。AIを使用してパーソナルアシスタントをゼロから作成する方法を学びました。GitHub Models、Pythonのバックエンド、HTML、CSS、JavaScriptのフロントエンドを使用して実現しました。
## Codespacesでのセットアップ
- 以下に移動:[Web Dev For Beginners repo](https://github.com/microsoft/Web-Dev-For-Beginners)
- テンプレートから作成GitHubにログインしていることを確認してください右上のコーナー
![テンプレートから作成](../../../translated_images/template.67ad477109d29a2b04599a83c964c87fcde041256d4f04d3589cbb00c696f76c.ja.png)
- リポジトリ内でCodespaceを作成
![Codespaceを作成](../../../translated_images/codespace.bcecbdf5d2747d3d17da67a78ad911c8853d68102e34748ec372cde1e9236e1d.ja.png)
これで作業可能な環境が開始されます。
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確さが含まれる可能性があります。元の言語で記載された原文が正式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の利用に起因する誤解や誤訳について、当社は一切の責任を負いません。

@ -0,0 +1,55 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "a7b7f54b13f9e6683a844d173ffdd766",
"translation_date": "2025-08-28T18:55:55+00:00",
"source_file": "9-chat-project/solution/README.md",
"language_code": "ja"
}
-->
# コードを実行する
## セットアップ
仮想環境を作成する
```sh
cd backend
python -m venv venv
source ./venv/bin/activate
```
## 依存関係をインストールする
```sh
pip install openai flask flask-cors
```
## APIを実行する
```sh
python api.py
```
## フロントエンドを実行する
フロントエンドフォルダに移動してください
*app.js* を見つけ、`BASE_URL` をバックエンドのURLに変更してください
実行する
```
npx http-server -p 8000
```
チャットでメッセージを入力してみてください。応答が表示されるはずですCodespaceで実行している場合、またはアクセストークンを設定している場合
## アクセストークンを設定するCodespaceで実行していない場合
[Set up PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) を参照してください
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確さが含まれる可能性があります。元の言語で記載された原文が正式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当社は一切の責任を負いません。

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "efa251c5fc089367f0a81c572874afca",
"translation_date": "2025-08-28T10:47:41+00:00",
"original_hash": "687c62646ad5595f1ba733edc294cdae",
"translation_date": "2025-08-28T17:44:04+00:00",
"source_file": "README.md",
"language_code": "ja"
}
@ -30,43 +30,50 @@ CO_OP_TRANSLATOR_METADATA:
# 初心者向けウェブ開発 - カリキュラム
Microsoft Cloud Advocatesによる12週間の包括的なコースでウェブ開発の基礎を学びましょう。24のレッスンでは、JavaScript、CSS、HTMLを使った実践的なプロジェクトテラリウム、ブラウザ拡張機能、宇宙ゲームなどを通じて学びます。クイズ、ディスカッション、実践課題を通じてスキルを向上させ、プロジェクトベースの学習法で知識の定着を最大化します。今日からコーディングの旅を始めましょう!
Microsoft Cloud Advocatesによる12週間の包括的なコースでウェブ開発の基礎を学びましょう。24のレッスンでは、JavaScript、CSS、HTMLを使った実践的なプロジェクトテラリウム、ブラウザ拡張機能、宇宙ゲームなどを通じて学びます。クイズ、ディスカッション、実践課題を通じてスキルを向上させ、プロジェクトベースの教育法で知識の定着を最適化します。今すぐコーディングの旅を始めましょう!
#### 🧑‍🎓 _学生の方へ_
### 🌐 多言語対応
[**Student Hubページ**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon) を訪問してください。初心者向けリソース、学生向けパック、さらには無料の認定証バウチャーを取得する方法が見つかります。このページはブックマークして、毎月内容が更新されるので定期的にチェックしてください。
#### GitHub Actionによるサポート (自動更新 & 常に最新)
### 📣 お知らせ - _新しいカリキュラム_「JavaScript向け生成AI」がリリースされました
[フランス語](../fr/README.md) | [スペイン語](../es/README.md) | [ドイツ語](../de/README.md) | [ロシア語](../ru/README.md) | [アラビア語](../ar/README.md) | [ペルシャ語 (ファルシ)](../fa/README.md) | [ウルドゥー語](../ur/README.md) | [中国語 (簡体字)](../zh/README.md) | [中国語 (繁体字, マカオ)](../mo/README.md) | [中国語 (繁体字, 香港)](../hk/README.md) | [中国語 (繁体字, 台湾)](../tw/README.md) | [日本語](./README.md) | [韓国語](../ko/README.md) | [ヒンディー語](../hi/README.md) | [ベンガル語](../bn/README.md) | [マラーティー語](../mr/README.md) | [ネパール語](../ne/README.md) | [パンジャブ語 (グルムキー)](../pa/README.md) | [ポルトガル語 (ポルトガル)](../pt/README.md) | [ポルトガル語 (ブラジル)](../br/README.md) | [イタリア語](../it/README.md) | [ポーランド語](../pl/README.md) | [トルコ語](../tr/README.md) | [ギリシャ語](../el/README.md) | [タイ語](../th/README.md) | [スウェーデン語](../sv/README.md) | [デンマーク語](../da/README.md) | [ノルウェー語](../no/README.md) | [フィンランド語](../fi/README.md) | [オランダ語](../nl/README.md) | [ヘブライ語](../he/README.md) | [ベトナム語](../vi/README.md) | [インドネシア語](../id/README.md) | [マレー語](../ms/README.md) | [タガログ語 (フィリピン)](../tl/README.md) | [スワヒリ語](../sw/README.md) | [ハンガリー語](../hu/README.md) | [チェコ語](../cs/README.md) | [スロバキア語](../sk/README.md) | [ルーマニア語](../ro/README.md) | [ブルガリア語](../bg/README.md) | [セルビア語 (キリル文字)](../sr/README.md) | [クロアチア語](../hr/README.md) | [スロベニア語](../sl/README.md) | [ウクライナ語](../uk/README.md) | [ビルマ語 (ミャンマー)](../my/README.md)
**追加の翻訳を希望する場合は、[こちら](https://github.com/Azure/co-op-translator/blob/main/getting_started/supported-languages.md)に対応言語が記載されています。**
#### 🧑‍🎓 _学生の皆さんへ_
[**Student Hubページ**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon)を訪れて、初心者向けリソース、学生向けパック、さらには無料の認定証バウチャーを取得する方法を見つけてください。このページはブックマークして、定期的にチェックすることをお勧めします。毎月コンテンツが更新されます。
### 📣 お知らせ - _生成AIを使った新しいプロジェクト_
新しいAIアシスタントプロジェクトが追加されました。詳細は[プロジェクト](./09-chat-project/README.md)をご覧ください。
### 📣 お知らせ - _新しいカリキュラム_ JavaScript向け生成AIがリリースされました
新しい生成AIカリキュラムをお見逃しなく
[https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) を訪問して学び始めましょう!
[https://aka.ms/genai-js-course](https://aka.ms/genai-js-course)を訪れて学び始めましょう!
![Background](../../translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.ja.png)
![背景](../../translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.ja.png)
- 基礎からRAGまでを網羅したレッスン
- GenAIとコンパニオンアプリを使って歴史上の人物と対話
- 楽しく魅力的なストーリーでタイムトラベル体験!
![character](../../translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.ja.png)
- 楽しく魅力的なストーリーでタイムトラベル体験
各レッスンには以下が含まれます:
- 課題
- 知識チェック
- チャレンジ
![キャラクター](../../translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.ja.png)
以下のトピックを学びます:
各レッスンには、課題、知識チェック、チャレンジが含まれており、以下のトピックを学ぶ手助けをします:
- プロンプトとプロンプトエンジニアリング
- テキストと画像アプリの生成
- 検索アプリ
[https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) を訪問して学び始めましょう!
[https://aka.ms/genai-js-course](https://aka.ms/genai-js-course)を訪れて学び始めましょう!
## 🌱 始め方
> **教師の方へ**: このカリキュラムの使用方法について[いくつかの提案](for-teachers.md)を含めています。ぜひ[ディスカッションフォーラム](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner)でフィードバックをお寄せください
> **教師の皆さん**、このカリキュラムの使用方法について[いくつかの提案](for-teachers.md)を含めています。フィードバックは[ディスカッションフォーラム](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner)でお待ちしています
**[学習者の方へ](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**: 各レッスンでは、事前クイズから始め、講義資料を読み、さまざまな活動を完了し、事後クイズで理解度を確認してください。
**[学習者の皆さん](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**、各レッスンでは、事前クイズから始め、講義資料を読み、さまざまな活動を完了し、事後クイズで理解度を確認してください。
学習体験を向上させるために、仲間と一緒にプロジェクトに取り組むことをお勧めします!ディスカッションは[ディスカッションフォーラム](https://github.com/microsoft/Web-Dev-For-Beginners/discussions)で歓迎されており、モデレーターが質問に答えるために待機しています。
@ -74,141 +81,140 @@ Microsoft Cloud Advocatesによる12週間の包括的なコースでウェブ
### 📋 環境のセットアップ
このカリキュラムにはすぐに使える開発環境が用意されています!始める際には、[Codespace](https://github.com/features/codespaces/)(ブラウザベースでインストール不要の環境)を使用するか、ローカルのコンピュータで[Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)などのテキストエディタを使用して実行することができます。
このカリキュラムにはすぐに使える開発環境が用意されています!始める際には、[Codespace](https://github.com/features/codespaces/)(ブラウザベースでインストール不要の環境)を使用するか、ローカルのコンピュータで[Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)などのテキストエディタを使用して実行することができます。
#### リポジトリを作成する
作業内容を簡単に保存するために、このリポジトリのコピーを作成することをお勧めします。ページ上部の **Use this template** ボタンをクリックすると、カリキュラムのコピーがあなたのGitHubアカウントに新しいリポジトリとして作成されます。
作業内容を簡単に保存するために、このリポジトリのコピーを作成することをお勧めします。ページ上部の**Use this template**ボタンをクリックすると、カリキュラムのコピーがあなたのGitHubアカウントに新しいリポジトリとして作成されます。
手順:
1. **リポジトリをフォークする**: ページ右上の「Fork」ボタンをクリックしてください。
1. **リポジトリをフォークする**: このページの右上にある「Fork」ボタンをクリックしてください。
2. **リポジトリをクローンする**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
#### Codespaceでカリキュラムを実行する
作成したリポジトリのコピーで、**Code** ボタンをクリックし、**Open with Codespaces** を選択してください。これにより、作業用の新しいCodespaceが作成されます。
作成したリポジトリのコピーで、**Code**ボタンをクリックし、**Open with Codespaces**を選択します。これにより、作業用の新しいCodespaceが作成されます。
[!Codespace](../..)./images/createcodespace.png)
#### ローカルコンピュータでカリキュラムを実行する
ローカルコンピュータでカリキュラムを実行するには、テキストエディタ、ブラウザ、コマンドラインツールが必要です。最初のレッスン[プログラミング言語とツールの紹介](../../1-getting-started-lessons/1-intro-to-programming-languages)では、これらのツールのさまざまなオプションを紹介し、最適なものを選択する方法を説明します。
ローカルコンピュータでこのカリキュラムを実行するには、テキストエディタ、ブラウザ、コマンドラインツールが必要です。最初のレッスン[プログラミング言語とツールの紹介](../../1-getting-started-lessons/1-intro-to-programming-languages)では、これらのツールのさまざまなオプションを紹介し、最適なものを選択する方法を説明します。
おすすめのエディタは[Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)で、内蔵の[ターミナル](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon)も利用できます。[こちら](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)からダウンロードできます。
私たちのおすすめは[Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)をエディタとして使用することです。このエディタには[ターミナル](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon)が組み込まれています。[Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)は[こちら](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)からダウンロードできます。
1. リポジトリをコンピュータにクローンします。**Code** ボタンをクリックしてURLをコピーしてください:
1. リポジトリをコンピュータにクローンします。**Code**ボタンをクリックしてURLをコピーしてください:
[!CodeSpace](./images/createcodespace.png)
次に、[Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)内の[ターミナル](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon)を開き、コピーしたURLを `<your-repository-url>` に置き換えて以下のコマンドを実行してください:
次に、[Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)内の[ターミナル](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon)を開き、コピーしたURLを`<your-repository-url>`に置き換えて以下のコマンドを実行してください:
```bash
git clone <your-repository-url>
```
2. Visual Studio Codeでフォルダを開きます。**File** > **Open Folder** をクリックし、クローンしたフォルダを選択してください。
> 推奨されるVisual Studio Code拡張機能:
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - HTMLページをVisual Studio Code内でプレビューするため
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - コードを書く速度を向上させるため
## 📂 各レッスンには以下が含まれます:
- スケッチノート(オプション)
- 補足動画(オプション)
- レッスン前のウォームアップクイズ
- 書かれたレッスン内容
- プロジェクトベースのレッスンでは、プロジェクトを構築するためのステップバイステップガイド
- 知識チェック
- チャレンジ
- 補足資料
- 課題
- [レッスン後のクイズ](https://ff-quizzes.netlify.app/web/)
> **クイズについての注意**: すべてのクイズはQuiz-appフォルダに含まれており、合計48個のクイズが各3問ずつあります。[こちら](https://ff-quizzes.netlify.app/web/)で利用可能です。クイズアプリはローカルで実行するか、Azureにデプロイできます。`quiz-app`フォルダ内の指示に従ってください。
## 🗃️ レッスン
| | プロジェクト名 | 教えられる概念 | 学習目標 | リンクされたレッスン | 著者 |
| :-: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :---------------------: |
| 01 | 始め方 | プログラミングとツールの紹介 | ほとんどのプログラミング言語の基本的な基盤と、プロの開発者が仕事をするのに役立つソフトウェアについて学ぶ | [プログラミング言語とツールの紹介](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | 始め方 | GitHubの基本、チームでの作業 | プロジェクトでGitHubを使用する方法、コードベースで他の人と協力する方法 | [GitHubの紹介](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | 始め方 | アクセシビリティ | ウェブアクセシビリティの基本を学ぶ | [アクセシビリティの基礎](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | JSの基本 | JavaScriptのデータ型 | JavaScriptのデータ型の基本を学ぶ | [データ型](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | JSの基本 | 関数とメソッド | アプリケーションのロジックフローを管理するための関数とメソッドについて学ぶ | [関数とメソッド](./2-js-basics/2-functions-methods/README.md) | Jasmine and Christopher |
| 06 | JSの基本 | JSでの意思決定 | 意思決定方法を使用してコード内で条件を作成する方法を学ぶ | [意思決定](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | JSの基本 | 配列とループ | JavaScriptで配列とループを使用してデータを操作する | [配列とループ](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [テラリウム](./3-terrarium/solution/README.md) | HTMLの実践 | オンラインテラリウムを作成するためのHTMLを構築し、レイアウトの構築に焦点を当てる | [HTMLの紹介](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [テラリウム](./3-terrarium/solution/README.md) | CSSの実践 | オンラインテラリウムをスタイル付けするためのCSSを構築し、CSSの基本とページをレスポンシブにする方法に焦点を当てる | [CSSの紹介](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [Terrarium](./3-terrarium/solution/README.md) | JavaScriptのクロージャとDOM操作 | JavaScriptを使ってドラッグドロップインターフェースとして機能するテラリウムを構築し、クロージャとDOM操作に焦点を当てます | [JavaScriptのクロージャとDOM操作](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [Typing Game](./4-typing-game/solution/README.md) | タイピングゲームを作成 | キーボードイベントを使用してJavaScriptアプリのロジックを駆動する方法を学びます | [イベント駆動型プログラミング](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [Green Browser Extension](./5-browser-extension/solution/README.md) | ブラウザの操作 | ブラウザの仕組み、その歴史、ブラウザ拡張機能の最初の要素をスキャフォールドする方法を学びます | [ブラウザについて](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [Green Browser Extension](./5-browser-extension/solution/README.md) | フォームの構築、APIの呼び出し、ローカルストレージへの変数保存 | ローカルストレージに保存された変数を使用してAPIを呼び出すブラウザ拡張機能のJavaScript要素を構築します | [API、フォーム、ローカルストレージ](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [Green Browser Extension](./5-browser-extension/solution/README.md) | ブラウザのバックグラウンドプロセス、ウェブパフォーマンス | ブラウザのバックグラウンドプロセスを使用して拡張機能のアイコンを管理し、ウェブパフォーマンスと最適化について学びます | [バックグラウンドタスクとパフォーマンス](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [Space Game](./6-space-game/solution/README.md) | JavaScriptを使ったより高度なゲーム開発 | クラスとコンポジションを使用した継承やPub/Subパターンについて学び、ゲーム構築の準備をします | [高度なゲーム開発の紹介](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [Space Game](./6-space-game/solution/README.md) | Canvasへの描画 | 画面に要素を描画するために使用されるCanvas APIについて学びます | [Canvasへの描画](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [Space Game](./6-space-game/solution/README.md) | 画面上の要素の移動 | 要素がカートesian座標とCanvas APIを使用して動きを得る方法を発見します | [要素の移動](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [Space Game](./6-space-game/solution/README.md) | 衝突検知 | キー入力を使用して要素が衝突し反応するようにし、ゲームのパフォーマンスを確保するためのクールダウン機能を提供します | [衝突検知](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [Space Game](./6-space-game/solution/README.md) | スコアの保持 | ゲームの状態とパフォーマンスに基づいて数学的計算を行います | [スコアの保持](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [Space Game](./6-space-game/solution/README.md) | ゲームの終了と再開 | ゲームの終了と再開について学び、アセットのクリーンアップや変数値のリセットを含めます | [終了条件](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [Banking App](./7-bank-project/solution/README.md) | ウェブアプリにおけるHTMLテンプレートとルート | マルチページウェブサイトのアーキテクチャのスキャフォールドをルーティングとHTMLテンプレートを使用して作成する方法を学びます | [HTMLテンプレートとルート](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [Banking App](./7-bank-project/solution/README.md) | ログインと登録フォームの作成 | フォームの作成とバリデーションルーチンの処理について学びます | [フォーム](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [Banking App](./7-bank-project/solution/README.md) | データの取得と使用方法 | アプリ内でデータがどのように流れ、取得、保存、破棄されるかを学びます | [データ](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [Banking App](./7-bank-project/solution/README.md) | 状態管理の概念 | アプリが状態を保持する方法とそれをプログラム的に管理する方法を学びます | [状態管理](./7-bank-project/4-state-management/README.md) | Yohan |
2. Visual Studio Codeでフォルダを開きます。**File**をクリックして開いてください。
> **フォルダーを開く** を選択し、クローンしたばかりのフォルダーを選択します。
> 推奨される Visual Studio Code 拡張機能:
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - Visual Studio Code 内で HTML ページをプレビューするため
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - コードを書くスピードを向上させるため
## 📂 各レッスンに含まれる内容:
- オプションのスケッチノート
- オプションの補足動画
- レッスン前のウォームアップクイズ
- 書面によるレッスン
- プロジェクトベースのレッスンでは、プロジェクトを構築するためのステップバイステップガイド
- 知識チェック
- チャレンジ
- 補足資料
- 課題
- [レッスン後のクイズ](https://ff-quizzes.netlify.app/web/)
> **クイズについての注意**: すべてのクイズは Quiz-app フォルダーに含まれており、3問ずつの合計48クイズがあります。これらは [こちら](https://ff-quizzes.netlify.app/web/) で利用可能です。クイズアプリはローカルで実行することも、Azure にデプロイすることもできます。詳細は `quiz-app` フォルダーの指示に従ってください。
## 🗃️ レッスン
| | プロジェクト名 | 教えられる概念 | 学習目標 | リンクされたレッスン | 著者 |
| :-: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :---------------------: |
| 01 | はじめに | プログラミングとツールの基本 | ほとんどのプログラミング言語の基本的な基盤と、プロの開発者が使用するソフトウェアについて学ぶ | [プログラミング言語とツールの基本](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | はじめに | GitHub の基本、チームでの作業 | プロジェクトで GitHub を使用する方法、コードベースで他の人と協力する方法 | [GitHub の基本](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | はじめに | アクセシビリティ | ウェブアクセシビリティの基本を学ぶ | [アクセシビリティの基本](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | JS の基本 | JavaScript のデータ型 | JavaScript のデータ型の基本を学ぶ | [データ型](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | JS の基本 | 関数とメソッド | アプリケーションのロジックフローを管理するための関数とメソッドについて学ぶ | [関数とメソッド](./2-js-basics/2-functions-methods/README.md) | Jasmine and Christopher |
| 06 | JS の基本 | JavaScript での意思決定 | 意思決定メソッドを使用してコード内で条件を作成する方法を学ぶ | [意思決定](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | JS の基本 | 配列とループ | JavaScript で配列とループを使用してデータを操作する | [配列とループ](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [テラリウム](./3-terrarium/solution/README.md) | HTML の実践 | オンラインテラリウムを作成するための HTML を構築し、レイアウト作成に焦点を当てる | [HTML の紹介](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [テラリウム](./3-terrarium/solution/README.md) | CSS の実践 | オンラインテラリウムをスタイル付けするための CSS を構築し、レスポンシブデザインを含む CSS の基本に焦点を当てる | [CSS の紹介](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [テラリウム](./3-terrarium/solution/README.md) | JavaScript クロージャ、DOM 操作 | テラリウムをドラッグ&ドロップインターフェースとして機能させるための JavaScript を構築し、クロージャと DOM 操作に焦点を当てる | [JavaScript クロージャ、DOM 操作](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [タイピングゲーム](./4-typing-game/solution/README.md) | タイピングゲームを作成 | キーボードイベントを使用して JavaScript アプリのロジックを駆動する方法を学ぶ | [イベント駆動型プログラミング](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [グリーンブラウザ拡張機能](./5-browser-extension/solution/README.md) | ブラウザの操作 | ブラウザの仕組み、その歴史、ブラウザ拡張機能の最初の要素をスキャフォールドする方法を学ぶ | [ブラウザについて](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [グリーンブラウザ拡張機能](./5-browser-extension/solution/README.md) | フォームの作成、API の呼び出し、ローカルストレージへの変数の保存 | ローカルストレージに保存された変数を使用して API を呼び出すためのブラウザ拡張機能の JavaScript 要素を構築する | [API、フォーム、ローカルストレージ](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [グリーンブラウザ拡張機能](./5-browser-extension/solution/README.md) | ブラウザのバックグラウンドプロセス、ウェブパフォーマンス | ブラウザのバックグラウンドプロセスを使用して拡張機能のアイコンを管理する方法を学び、ウェブパフォーマンスと最適化について学ぶ | [バックグラウンドタスクとパフォーマンス](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [スペースゲーム](./6-space-game/solution/README.md) | JavaScript を使用したより高度なゲーム開発 | クラスとコンポジションの両方を使用した継承や、ゲーム構築の準備として Pub/Sub パターンについて学ぶ | [高度なゲーム開発の紹介](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [スペースゲーム](./6-space-game/solution/README.md) | Canvas への描画 | 画面に要素を描画するために使用される Canvas API について学ぶ | [Canvas への描画](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [スペースゲーム](./6-space-game/solution/README.md) | 画面上の要素の移動 | 要素がどのように動きを得るか、デカルト座標と Canvas API を使用して学ぶ | [要素の移動](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [スペースゲーム](./6-space-game/solution/README.md) | 衝突検出 | 要素が衝突して相互に反応する方法を学び、ゲームのパフォーマンスを確保するためのクールダウン機能を提供する | [衝突検出](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [スペースゲーム](./6-space-game/solution/README.md) | スコアの管理 | ゲームの状態とパフォーマンスに基づいて数学的計算を行う | [スコアの管理](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [スペースゲーム](./6-space-game/solution/README.md) | ゲームの終了と再開 | ゲームの終了と再開について学び、アセットのクリーンアップや変数値のリセットを含む | [終了条件](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [バンキングアプリ](./7-bank-project/solution/README.md) | ウェブアプリでの HTML テンプレートとルート | ルーティングと HTML テンプレートを使用してマルチページウェブサイトのアーキテクチャのスキャフォールドを作成する方法を学ぶ | [HTML テンプレートとルート](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [バンキングアプリ](./7-bank-project/solution/README.md) | ログインと登録フォームの作成 | フォームの作成とバリデーションルーチンの処理について学ぶ | [フォーム](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [バンキングアプリ](./7-bank-project/solution/README.md) | データの取得と使用方法 | アプリ内でデータがどのように流れ、取得、保存、破棄されるかを学ぶ | [データ](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [バンキングアプリ](./7-bank-project/solution/README.md) | 状態管理の概念 | アプリが状態をどのように保持し、それをプログラム的に管理する方法を学ぶ | [状態管理](./7-bank-project/4-state-management/README.md) | Yohan |
| 25 | [ブラウザ/VScode コード](../../8-code-editor) | VScode の操作 | コードエディタの使用方法を学ぶ | [VScode コードエディタの使用](./8-code-editor/1-using-a-code-editor/README.md) | Chris |
| 26 | [AI アシスタント](./9-chat-project/README.md) | AI の操作 | 独自の AI アシスタントを構築する方法を学ぶ | [AI アシスタントプロジェクト](./9-chat-project/README.md) | Chris |
## 🏫 教育方針
私たちのカリキュラムは、以下の2つの主要な教育方針に基づいて設計されています
私たちのカリキュラムは、以下の2つの主要な教育方針に基づいて設計されています:
* プロジェクトベースの学習
* 頻繁なクイズ
このプログラムでは、JavaScript、HTML、CSSの基礎と、現代のウェブ開発者が使用する最新のツールや技術を教えます。学生は、タイピングゲーム、仮想テラリウム、環境に優しいブラウザ拡張機能、スペースインベーダースタイルのゲーム、そしてビジネス向けの銀行アプリを構築することで、実践的な経験を積む機会を得ます。このシリーズの終わりまでに、学生はウェブ開発に関する確固たる理解を得ることができます。
このプログラムでは、JavaScript、HTML、CSS の基本と、現代のウェブ開発者が使用する最新のツールや技術を教えます。学生は、タイピングゲーム、仮想テラリウム、エコフレンドリーなブラウザ拡張機能、スペースインベーダー風のゲーム、ビジネス向けバンキングアプリを構築することで、実践的な経験を積む機会を得ます。このシリーズの終わりまでに、学生はウェブ開発確固たる理解を得ることができます。
> 🎓 このカリキュラムの最初のいくつかのレッスンをMicrosoft Learnで[学習パス](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon)として受講することができます!
> 🎓 このカリキュラムの最初のいくつかのレッスンは、Microsoft Learn の [学習パス](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) として受講できます!
プロジェクトに内容を合わせることで、学生にとってより魅力的なプロセスとなり、概念の定着が促進されます。また、JavaScriptの基本を紹介するいくつかのスターターレッスンを作成し、"[Beginners Series to: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)"というビデオチュートリアルコレクションのビデオとペアリングしました。このコレクションの著者の一部は、このカリキュラムに貢献しています。
プロジェクトに沿った内容を確保することで、学生にとってより魅力的なプロセスとなり、概念の定着が促進されます。また、JavaScript の基本を紹介するいくつかのスターターレッスンを作成し、"[Beginners Series to: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)" のビデオコレクションとペアリングしました。このコレクションの一部の著者は、このカリキュラムに貢献しています。
さらに、授業前の低リスクなクイズは、学生がトピックを学ぶ意図を設定し、授業後の2回目のクイズはさら定着を確保します。このカリキュラムは柔軟で楽しいように設計されており、全体または部分的に受講することができます。プロジェクトは小さなものから始まり、12週間のサイクルの終わりまでに徐々に複雑になります。
さらに、授業前の低リスクなクイズは、学生がトピックを学ぶ意図を設定し、授業後の2回目のクイズはさらなる定着を確保します。このカリキュラムは柔軟で楽しいように設計されており、全体または一部を受講することができます。プロジェクトは小さなものから始まり、12週間のサイクルの終わりまでに徐々に複雑になります。
JavaScriptフレームワークを導入せず、ウェブ開発者としてフレームワークを採用する前に必要な基本スキルに集中するよう意図的に設計されていますが、このカリキュラムを完了した後の次のステップとして、Node.jsについて学ぶことをお勧めします。これには、別のビデオコレクション"[Beginner Series to: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)"が役立ちます。
> [行動規範](CODE_OF_CONDUCT.md)と[貢献ガイドライン](CONTRIBUTING.md)をご覧ください。建設的なフィードバックを歓迎します!
JavaScript フレームワークを導入せず、フレームワークを採用する前に必要な基本スキルに集中するよう意図的に設計されていますが、このカリキュラムを修了した後の次のステップとして、Node.js を学ぶことをお勧めします。こちらのビデオコレクションをご覧ください: "[Beginner Series to: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)".
> [行動規範](CODE_OF_CONDUCT.md) と [貢献ガイドライン](CONTRIBUTING.md) をご覧ください。建設的なフィードバックをお待ちしています!
## 🧭 オフラインアクセス
このドキュメントをオフラインで実行するには、[Docsify](https://docsify.js.org/#/)を使用します。このリポジトリをフォークし、[Docsifyをインストール](https://docsify.js.org/#/quickstart)してローカルマシンにセットアップします。その後、このリポジトリのルートフォルダで`docsify serve`と入力します。ウェブサイトはローカルホストのポート3000で提供されます`localhost:3000`。
このドキュメントをオフラインで実行するには、[Docsify](https://docsify.js.org/#/) を使用できます。このリポジトリをフォークし、[Docsify をインストール](https://docsify.js.org/#/quickstart) してから、このリポジトリのルートフォルダーで `docsify serve` と入力してください。ウェブサイトはローカルホストのポート3000で提供されます: `localhost:3000`.
## 📘 PDF
すべてのレッスンのPDFは[こちら](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf)からダウンロードできます。
すべてのレッスンの PDF は [こちら](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf) で見つけることができます。
## 🎒 その他のコース
私たちのチームは他にもコースを提供しています!以下をご覧ください:
私たちのチームは他のコースも制作しています!ぜひご覧ください:
- [Generative AI for Beginners](https://aka.ms/genai-beginners)
- [Generative AI for Beginners .NET](https://github.com/microsoft/Generative-AI-for-beginners-dotnet)
- [Generative AI with JavaScript](https://github.com/microsoft/generative-ai-with-javascript)
- [Generative AI with Java](https://github.com/microsoft/Generative-AI-for-beginners-java)
- [AI for Beginners](https://aka.ms/ai-beginners)
- [Data Science for Beginners](https://aka.ms/datascience-beginners)
- [ML for Beginners](https://aka.ms/ml-beginners)
- [Cybersecurity for Beginners](https://github.com/microsoft/Security-101)
- [Web Dev for Beginners](https://aka.ms/webdev-beginners)
- [IoT for Beginners](https://aka.ms/iot-beginners)
- [XR Development for Beginners](https://github.com/microsoft/xr-development-for-beginners)
- [Mastering GitHub Copilot for Agentic use](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
- [Mastering GitHub Copilot for C#/.NET Developers](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
- [Choose Your Own Copilot Adventure](https://github.com/microsoft/CopilotAdventures)
- [初心者向け生成 AI](https://aka.ms/genai-beginners)
- [初心者向け生成 AI .NET](https://github.com/microsoft/Generative-AI-for-beginners-dotnet)
- [JavaScript を使った生成 AI](https://github.com/microsoft/generative-ai-with-javascript)
- [Java を使った生成 AI](https://github.com/microsoft/Generative-AI-for-beginners-java)
- [初心者向け AI](https://aka.ms/ai-beginners)
- [初心者向けデータサイエンス](https://aka.ms/datascience-beginners)
- [初心者向け機械学習](https://aka.ms/ml-beginners)
- [初心者向けサイバーセキュリティ](https://github.com/microsoft/Security-101)
- [初心者向けウェブ開発](https://aka.ms/webdev-beginners)
- [初心者向けIoT](https://aka.ms/iot-beginners)
- [初心者向けXR開発](https://github.com/microsoft/xr-development-for-beginners)
- [GitHub Copilotを活用したエージェント的使用法の習得](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
- [C#/.NET開発者向けGitHub Copilotの習得](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
- [GitHub Copilotで冒険を選ぼう](https://github.com/microsoft/CopilotAdventures)
## ライセンス
## ライセンス
このリポジトリはMITライセンスの下でライセンスされています。詳細は[LICENSE](../../LICENSE)ファイルをご覧ください。
このリポジトリはMITライセンスの下で提供されています。詳細は[LICENSE](../../LICENSE)ファイルをご覧ください。
---
**免責事項**:
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された原文が正式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の利用に起因する誤解や誤認について、当方は一切の責任を負いません。
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は責任を負いません。

@ -1,18 +1,18 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "c63675cfaf1d223b37bb9fecbfe7c252",
"translation_date": "2025-08-27T22:47:06+00:00",
"original_hash": "2dcbb9259dee4f20a4f08d9a1aa2bd4c",
"translation_date": "2025-08-28T18:50:20+00:00",
"source_file": "1-getting-started-lessons/1-intro-to-programming-languages/README.md",
"language_code": "my"
}
-->
# ပရိုဂရမ်မင်းဘာသာစကားများနှင့် အသုံးဝင်သောကိရိယာများ
ဒီသင်ခန်းစာမှာ ပရိုဂရမ်မင်းဘာသာစကားများ၏ အခြေခံအချက်များကို လေ့လာပါမည်။ ဒီမှာဖော်ပြထားတဲ့အကြောင်းအရာတွေဟာ ယနေ့ခေတ်ပရိုဂရမ်မင်းဘာသာစကားများအများစုအတွက် သက်ဆိုင်ပါတယ်။ "အသုံးဝင်သောကိရိယာများ" အပိုင်းမှာတော့ ပရိုဂရမ်မာတစ်ဦးအနေနဲ့ အသုံးဝင်မယ့် ဆော့ဖ်ဝဲလ်များကို လေ့လာနိုင်ပါမည်။
ဒီသင်ခန်းစာမှာ ပရိုဂရမ်မင်းဘာသာစကားများ၏ အခြေခံအချက်များကို လေ့လာပါမည်။ ဒီမှာဖော်ပြထားတဲ့အကြောင်းအရာများဟာ ယနေ့ခေတ်ပရိုဂရမ်မင်းဘာသာစကားများအများစုအတွက် သက်ဆိုင်ပါတယ်။ "အသုံးဝင်သောကိရိယာများ" အပိုင်းမှာတော့ ပရိုဂရမ်မာတစ်ဦးအနေနဲ့ အသုံးဝင်မယ့် ဆော့ဖ်ဝဲလ်များကို လေ့လာနိုင်ပါမည်။
![Intro Programming](../../../../translated_images/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.my.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
> [Tomomi Imura](https://twitter.com/girlie_mac) ရဲ့ Sketchnote
## သင်ခန်းစာမတိုင်မီ စမ်းမေးခွန်း
[Pre-lecture quiz](https://forms.office.com/r/dru4TE0U9n?origin=lprLink)
@ -30,21 +30,21 @@ CO_OP_TRANSLATOR_METADATA:
## ပရိုဂရမ်မင်းဆိုတာဘာလဲ?
ပရိုဂရမ်မင်း (coding) ဆိုတာက ကွန်ပျူတာ သို့မဟုတ် မိုဘိုင်းစက်ကိရိယာတစ်ခုအတွက် အညွှန်းများရေးသားခြင်းဖြစ်ပါတယ်။ ဒီအညွှန်းတွေကို ပရိုဂရမ်မင်းဘာသာစကားတစ်ခုနဲ့ရေးပြီး စက်ကိရိယာက အဓိပ္ပါယ်ဖွင့်ဆိုပေးပါတယ်။ ဒီအညွှန်းတွေကို *program*, *computer program*, *application (app)*, *executable* စတဲ့အမည်တွေနဲ့ ခေါ်ဆိုနိုင်ပါတယ်။
ပရိုဂရမ်မင်း (coding) ဆိုတာက ကွန်ပျူတာ သို့မဟုတ် မိုဘိုင်းစက်ကိရိယာလိုမျိုးသော စက်ပစ္စည်းတစ်ခုအတွက် အညွှန်းများရေးသားခြင်းဖြစ်ပါတယ်။ ဒီအညွှန်းတွေကို ပရိုဂရမ်မင်းဘာသာစကားတစ်ခုနဲ့ရေးပြီး စက်ကိရိယာက အဓိပ္ပါယ်ဖွင့်ဆိုပေးပါတယ်။ ဒီအညွှန်းစုများကို *program*, *computer program*, *application (app)*, *executable* စတဲ့အမည်များနဲ့ ခေါ်ဆိုနိုင်ပါတယ်။
*Program* ဆိုတာက ကုဒ်နဲ့ရေးထားတဲ့ အရာတစ်ခုဖြစ်ပါတယ်။ ဥပမာ - ဝဘ်ဆိုဒ်များ, ဂိမ်းများ, ဖုန်းအက်ပ်များစသည်ဖြင့်။ ကုဒ်မရေးဘဲနဲ့လည်း ပရိုဂရမ်တစ်ခုဖန်တီးနိုင်ပေမယ့် အခြေခံလောဂျစ်ကို စက်ကိရိယာက ဖွင့်ဆိုပေးရမှာဖြစ်ပြီး အဲ့ဒီလောဂျစ်ကို ကုဒ်နဲ့ရေးထားတာဖြစ်နိုင်ပါတယ်။ *Running* သို့မဟုတ် *executing* လုပ်နေတဲ့ ပရိုဂရမ်တစ်ခုက အညွှန်းတွေကို လုပ်ဆောင်နေပါတယ်။ သင်ဒီသင်ခန်းစာကို ဖတ်နေတဲ့ စက်ကိရိယာကလည်း ပရိုဂရမ်တစ်ခုကို လည်ပတ်နေပါတယ်။
*Program* ဆိုတာက ကုဒ်နဲ့ရေးထားတဲ့ အရာတစ်ခုဖြစ်ပါတယ်။ ဥပမာ - ဝဘ်ဆိုဒ်များ၊ ဂိမ်းများ၊ ဖုန်းအက်ပ်များစသည်ဖြစ်ပါတယ်။ ကုဒ်မရေးဘဲနဲ့လည်း ပရိုဂရမ်တစ်ခုဖန်တီးနိုင်ပေမယ့် အခြေခံလောဂျစ်ကို စက်ကိရိယာက ဖွင့်ဆိုပေးရပြီး အဲ့ဒီလောဂျစ်ကို ကုဒ်နဲ့ရေးထားတာဖြစ်ပါတယ်။ *Running* သို့မဟုတ် *executing* လုပ်နေတဲ့ ပရိုဂရမ်တစ်ခုဟာ အညွှန်းတွေကို လုပ်ဆောင်နေပါတယ်။ သင်ဒီသင်ခန်းစာကို ဖတ်နေတဲ့ စက်ကိရိယာကလည်း ဒီစာကို မျက်နှာပြင်ပေါ်မှာ ပြပေးဖို့ ပရိုဂရမ်တစ်ခုကို လည်ပတ်နေပါတယ်။
✅ သုတေသနလုပ်ပါ - ကမ္ဘာ့ပထမဆုံး ကွန်ပျူတာပရိုဂရမ်မာအဖြစ် သတ်မှတ်ခံရသူက ဘယ်သူလဲ?
✅ သုတေသနလုပ်ပါ: ကမ္ဘာ့ပထမဆုံး ကွန်ပျူတာပရိုဂရမ်မာအဖြစ် သတ်မှတ်ခံရသူက ဘယ်သူလဲ?
## ပရိုဂရမ်မင်းဘာသာစကားများ
ပရိုဂရမ်မင်းဘာသာစကားတွေက စက်ကိရိယာအတွက် အညွှန်းရေးဖို့ ပရိုဂရမ်မာတွေကို အခွင့်အလမ်းပေးပါတယ်။ စက်ကိရိယာတွေက binary (1s နှင့် 0s) ကိုသာ နားလည်နိုင်ပြီး အများစုသော ပရိုဂရမ်မာတွေအတွက် အဲ့ဒီနည်းနဲ့ ဆက်သွယ်ဖို့ မထိရောက်ပါဘူး။ ပရိုဂရမ်မင်းဘာသာစကားတွေက လူနဲ့ က်ကြား ဆက်သွယ်ရေးအတွက် အထောက်အကူပေးပါတယ်။
ပရိုဂရမ်မင်းဘာသာစကားတွေက စက်ကိရိယာအတွက် အညွှန်းရေးဖို့ ပရိုဂရမ်မာတွေကို အခွင့်အလမ်းပေးပါတယ်။ စက်ကိရိယာတွေဟာ binary (1s နှင့် 0s) ကိုသာ နားလည်နိုင်ပြီး အများစုသော ပရိုဂရမ်မာတွေအတွက် အဲ့ဒီနည်းနဲ့ ဆက်သွယ်ဖို့ အလွန်မထိရောက်ပါဘူး။ ပရိုဂရမ်မင်းဘာသာစကားတွေက လူနဲ့ ကွနပျူတာကြား ဆက်သွယ်ရေးအတွက် အထောက်အကူပေးတဲ့ ကိရိယာဖြစ်ပါတယ်။
ပရိုဂရမ်မင်းဘာသာစကားတွေဟာ အမျိုးအစားအမျိုးမျိုးရှိပြီး ရည်ရွယ်ချက်အမျိုးမျိုးအတွက် အသုံးပြုနိုင်ပါတယ်။ ဥပမာ - JavaScript ကို ဝဘ်အက်ပ်လီကေးရှင်းများအတွက် အသုံးပြုပြီး Bash ကို အပရိုပရိုစစ်ဆင်ရေးစနစ်များအတွက် အသုံးပြုပါတယ်။
ပရိုဂရမ်မင်းဘာသာစကားတွေဟာ အမျိုးအစားအမျိုးမျိုးရှိပြီး ရည်ရွယ်ချက်အမျိုးမျိုးအတွက် အသုံးပြုနိုင်ပါတယ်။ ဥပမာ - JavaScript ကို ဝဘ်အက်ပ်များအတွက် အဓိကအသုံးပြုပြီး Bash ကို အဓိကအားဖြင့် အစီအစဉ်စနစ်များအတွက် အသုံးပြုပါတယ်။
*Low level languages* တွေဟာ စက်ကိရိယာအတွက် အညွှန်းဖွင့်ဆိုဖို့ အဆင့်နည်းနည်းသာ လိုအပ်ပါတယ်။ ဒါပေမယ့် *high level languages* တွေက ဖတ်ရှုရလွယ်ကူပြီး အထောက်အပံ့များတဲ့အတွက် လူကြိုက်များပါတယ်။ JavaScript ကို *high level language* အဖြစ် သတ်မှတ်နိုင်ပါတယ်။
*Low level languages* တွေဟာ စက်ကိရိယာအတွက် အညွှန်းဖွင့်ဆိုဖို့ အဆင့်နည်းနည်းသာ လိုအပ်ပါတယ်။ ဒါပေမယ့် *high level languages* တွေဟာ ဖတ်ရလွယ်ကူပြီး အထောက်အပံ့များတဲ့အတွက် လူကြိုက်များပါတယ်။ JavaScript ကို high level language အဖြစ် သတ်မှတ်နိုင်ပါတယ်။
အောက်ပါကုဒ်က JavaScript နဲ့ ARM assembly code တို့ကို အသုံးပြုပြီး *high level* နဲ့ *low level* ဘာသာစကားကြား ကွာခြားချက်ကို ဖော်ပြထားပါတယ်။
အောက်ပါကုဒ်က JavaScript နဲ့ ARM assembly code တို့ကို အသုံးပြုပြီး high level language နဲ့ low level language တို့ရဲ့ ကွာခြားချက်ကို ဖော်ပြထားပါတယ်။
```javascript
let number = 10
@ -83,19 +83,19 @@ back add r0,r1
end
```
ယုံကြည်ပါ - *သူတို့နှစ်ခုလုံး တူညီတဲ့အရာကို လုပ်ဆောင်နေပါတယ်*: Fibonacci အစီအစဉ်ကို 10 အထိ ပုံနှိပ်ပြနေပါတယ်။
ယုံကြည်ပါ - *တစ်ခုတည်းသောအရာကို လုပ်ဆောင်နေပါတယ်*: Fibonacci sequence ကို 10 အထိ ပုံနှိပ်ပြနေပါတယ်။
✅ Fibonacci အစီအစဉ်ဆိုတာ [သတ်မှတ်ထားသည်](https://en.wikipedia.org/wiki/Fibonacci_number) - 0 နဲ့ 1 ကနေ စတင်ပြီး နောက်ထပ်နံပါတ်တစ်ခုဟာ အရင်နံပါတ်နှစ်ခုရဲ့ စုစုပေါင်းဖြစ်ပါတယ်။ ပထမဆုံး 10 ခုက 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ဖြစ်ပါတယ်။
✅ Fibonacci sequence ဆိုတာ [အဓိပ္ပါယ်ဖော်ပြထားတဲ့အတိုင်း](https://en.wikipedia.org/wiki/Fibonacci_number) နံပါတ်နှစ်ခုရဲ့ စုစုပေါင်းဖြစ်ပြီး 0 နဲ့ 1 ကနေ စတင်ပါတယ်။ ပထမဆုံး 10 ခုက 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ဖြစ်ပါတယ်။
## ပရိုဂရမ်တစ်ခု၏ အခြေခံအချက်များ
ပရိုဂရမ်တစ်ခုအတွင်း အညွှန်းတစ်ခုကို *statement* လို့ခေါ်ပြီး အညွှန်းတစ်ခုပြီးဆုံးတဲ့နေရာကို သတ်မှတ်ထားတဲ့ စာလုံး သို့မဟုတ် လိုင်းအကွာအဝေးရှိပါတယ်။ ဘာသာစကားတစ်ခုစီအလိုက် အညွှန်းပြီးဆုံးပုံက မတူနိုင်ပါတယ်။
ပရိုဂရမ်တစ်ခုအတွင်း အညွှန်းတစ်ခုကို *statement* လို့ခေါ်ပြီး အညွှန်းတစ်ခုပြီးဆုံးတဲ့နေရာကို သတ်မှတ်ထားတဲ့ စာလုံး သို့မဟုတ် လိုင်းအကွာအဝေးရှိပါတယ်။ အညွှန်းတစ်ခုပြီးဆုံးပုံဟာ ဘာသာစကားတစ်ခုစီအလိုက် ကွဲပြားပါတယ်။
ပရိုဂရမ်အတွင်းရှိ အညွှန်းတွေဟာ အသုံးပြုသူ သို့မဟုတ် အခြားနေရာကနေ ရရှိတဲ့ ဒေတာကို အခြေခံပြီး လုပ်ဆောင်နိုင်ပါတယ်။ ဒေတာဟာ ပရိုဂရမ်ရဲ့ အပြုအမူကို ပြောင်းလဲနိုင်တဲ့အတွက် ပရိုဂရမ်မင်းဘာသာစကားတွေမှာ ဒေတာကို ယာယီသိမ်းဆည်းဖို့ နည်းလမ်းတစ်ခုပါဝင်ပါတယ်။ ဒါတွေကို *variables* လို့ခေါ်ပါတယ်။ Variables တွေဟာ ဒေတာကို စက်ရဲ့ မှတ်ဉာဏ်ထဲမှာ သိမ်းဆည်းဖို့ အညွှန်းပေးတဲ့ statement တွေဖြစ်ပါတယ်။ Variables တွေဟာ အလျားလိုက်သင်္ချာမှာရှိတဲ့ variables တွေနဲ့ ဆင်တူပြီး အမည်တစ်ခုရှိပြီး တန်ဖိုးက အချိန်အလိုက် ပြောင်းလဲနိုင်ပါတယ်။
ပရိုဂရမ်အတွင်းရှိ အညွှန်းတွေဟာ အသုံးပြုသူ သို့မဟုတ် အခြားနေရာက ရရှိတဲ့ ဒေတာကို အခြေခံပြီး လုပ်ဆောင်နိုင်ပါတယ်။ ဒေတာဟာ ပရိုဂရမ်ရဲ့ အပြုအမူကို ပြောင်းလဲနိုင်တဲ့အတွက် ဒေတာကို ယာယီသိမ်းဆည်းဖို့ နည်းလမ်းတစ်ခုကို ပရိုဂရမ်မင်းဘာသာစကားတွေမှာ ပါဝင်ပါတယ်။ ဒါတွေကို *variables* လို့ခေါ်ပါတယ်။ Variables တွေဟာ ဒေတာကို စက်ရဲ့ မှတ်ဉာဏ်ထဲမှာ သိမ်းဆည်းဖို့ အညွှန်းပေးတဲ့ statement တွေဖြစ်ပါတယ်။ Variables တွေဟာ အလျားလိုက်သင်္ချာမှာရှိတဲ့ variables တွေနဲ့ ဆင်တူပြီး အမည်တစ်ခုရှိပြီး တန်ဖိုးက အချိန်အလိုက် ပြောင်းလဲနိုင်ပါတယ်။
တစ်ခါတစ်လေမှာ အညွှန်းတစ်ချို့ကို စက်ကိရိယာက မလုပ်ဆောင်နိုင်ပါဘူး။ ဒါဟာ ပရိုဂရမ်မာရဲ့ ရည်ရွယ်ချက်အတိုင်း ဖြစ်နိုင်သလို မမျှော်လင့်ထားတဲ့ အမှားတစ်ခုကြောင့် ဖြစ်နိုင်ပါတယ်။ ဒီလို application ကို ထိန်းချုပ်နိုင်ခြင်းက ပိုမိုခိုင်မာပြီး ပြုပြင်ထိန်းသိမ်းရလွယ်ကူစေပါတယ်။ အများအားဖြင့် ဒီလို ထိန်းချုပ်မှုတွေဟာ အခြေအနေတစ်ခုဖြစ်ပေါ်တဲ့အခါမှာ ဖြစ်ပါတယ်။ ယနေ့ခေတ်ပရိုဂရမ်မင်းမှာ အများဆုံးအသုံးပြုတဲ့ statement တစ်ခုက `if..else` statement ဖြစ်ပါတယ်။
တစ်ချို့သော အညွှန်းတွေဟာ စက်ကိရိယာက လုပ်ဆောင်မည်မဟုတ်ပါဘူး။ ဒါဟာ ပရိုဂရမ်မာရဲ့ ရည်ရွယ်ချက်အတိုင်း ဖြစ်နိုင်သလို မမျှော်လင့်ထားတဲ့ အမှားတစ်ခုကြောင့် ဖြစ်နိုင်ပါတယ်။ ဒီလို application ကို ထိန်းချုပ်နိုင်ခြင်းက ပိုမိုခိုင်မာပြီး ပြုပြင်ထိန်းသိမ်းရလွယ်ကူစေပါတယ်။ အများအားဖြင့် ဒီလိုထိန်းချုပ်မှုတွေဟာ အခြေအနေတစ်ခုဖြစ်ပေါ်တဲ့အခါမှာ ဖြစ်ပါတယ်။ ယနေ့ခေတ်ပရိုဂရမ်မင်းမှာ အများဆုံးအသုံးပြုတဲ့ ထိန်းချုပ်မှုအညွှန်းတစ်ခုက `if..else` statement ဖြစ်ပါတယ်။
✅ ဒီလို statement အမျိုးအစားကို နောက်ထပ်သင်ခန်းစာတွေမှာ ပိုမိုလေ့လာနိုင်ပါမည်။
✅ ဒီလိုအညွှန်းအမျိုးအစားကို နောက်ထပ်သင်ခန်းစာတွေမှာ ပိုမိုလေ့လာနိုင်ပါမည်။
## အသုံးဝင်သောကိရိယာများ
@ -103,89 +103,71 @@ back add r0,r1
> 🎥 အထက်ပါပုံကို နှိပ်ပြီး tooling အကြောင်း ဗီဒီယိုကြည့်ပါ
ဒီအပိုင်းမှာ သင့်ရဲ့ ပရိုဂရမ်မင်းခရီးစတင်ရာမှာ အသုံးဝင်မယ့် ဆော့ဖ်ဝဲလ်တစ်ချို့ကို လေ့လာနိုင်ပါမည်။
ဒီအပိုင်းမှာ သင့်ရဲ့ ပရိုဂရမ်မာဘဝကို စတင်ရာမှာ အထောက်အကူဖြစ်မယ့် ဆော့ဖ်ဝဲလ်တစ်ချို့ကို လေ့လာနိုင်ပါမည်။
**ဖွံ့ဖြိုးရေးပတ်ဝန်းကျင်** ဆိုတာက ပရိုဂရမ်မာတစ်ဦးအနေနဲ့ ဆော့ဖ်ဝဲရေးသားရာမှာ မကြာခဏ အသုံးပြုရတဲ့ ကိရိယာများနှင့် လုပ်ဆောင်ချက်များရဲ့ ပုံစံတစ်ခုဖြစ်ပါတယ်။ ဒီကိရိယာတစ်ချို့ဟာ ပရိုဂရမ်မာရဲ့ လိုအပ်ချက်အ ပြင်ဆင်ထားပြီး အချိန်အလိုက် ပြောင်းလဲနိုင်ပါတယ်။
**Development environment** ဆိုတာက ပရိုဂရမ်မာတစ်ဦးအနေနဲ့ ဆော့ဖ်ဝဲရေးသားရာမှာ မကြာခဏအသုံးပြုတဲ့ ကိရိယာများနဲ့ လုပ်ဆောင်ချက်များရဲ့ အထူးပတ်ဝန်းကျင်တစ်ခုဖြစ်ပါတယ်။ ဒီကိရိယာတစ်ချို့ဟာ ပရိုဂရမ်မာရဲ့ လိုအပ်ချက်အလိုက် ပြင်ဆင်ထားပြီး အချိန်အလိုက် ပြောင်းလဲနိုင်ပါတယ်။ Development environment တွေဟာ အသုံးပြုသူတစ်ဦးစီအလိုက် ထူးခြားပါတယ်။
### Editor များ
### Editors
ဆော့ဖ်ဝဲရေးသားရာမှာ အရေးကြီးဆုံးကိရိယာတစ်ခုက Editor ဖြစ်ပါတယ်။ Editor တွေမှာ သင့်ရဲ့ကုဒ်ကို ရေးပြီး တစ်ခါတစ်လေမှာတော့ အဲ့ဒီကုဒ်ကို အလုပ်လုပ်စေပါမည်။
ဆော့ဖ်ဝဲရေးသားရာမှာ အရေးကြီးဆုံးကိရိယာတစ်ခုက editor ဖြစ်ပါတယ်။ Editors တွေဟာ သင့်ရဲ့ကုဒ်ကိုရေးရာမှာ အသုံးပြုတဲ့နေရာဖြစ်ပြီး တစ်ခါတစ်လေ သင့်ကုဒ်ကို အလုပ်လုပ်စေရာမှာလည်း အသုံးပြုနိုင်ပါတယ်။
Developer တွေဟာ Editor တွေကို အောက်ပါအကြောင်းအရာများအတွက် အားထားကြပါတယ် -
Developers တွေဟာ editors တွေကို အောက်ပါအကြောင်းအရာများအတွက် အားထားကြပါတယ် -
- *Debugging* က ကုဒ်ထဲမှာ Bug နဲ့ အမှားတွေကို ရှာဖွေဖို့ ကူညီပါတယ်။ တချို့ Editor တွေမှာ Debugging လုပ်ဆောင်ချက်ပါဝင်ပြီး သတ်မှတ်ထားတဲ့ ဘာသာစကားအတွက် ပြင်ဆင်နိုင်ပါတယ်။
- *Syntax highlighting* က ကုဒ်ကို ဖတ်ရလွယ်ကူစေဖို့ အရောင်နဲ့ စာသားဖော်ပြမှုတွေ ထည့်သွင်းပေးပါတယ်။
- *Extensions and Integrations* တွေက Developer တွေအတွက် အထူးပြုလုပ်ထားတဲ့ ကိရိယာတွေဖြစ်ပါတယ်။
- *Customization* က Developer တစ်ဦးချင်းစီရဲ့ လိုအပ်ချက်အရ Development Environment ကို ပြင်ဆင်နိုင်စေပါတယ်။
- *Debugging* က ကုဒ်ထဲမှာ bug တွေကို ရှာဖွေပြီး လိုင်းတစ်လိုင်းစီကို စစ်ဆေးနိုင်စေပါတယ်။ တစ်ချို့သော editors တွေမှာ debugging လုပ်ဆောင်ချက်ပါဝင်ပြီး အထူးပြုဘာသာစကားအတွက် ပြင်ဆင်နိုင်ပါတယ်။
- *Syntax highlighting* က ကုဒ်ကို ဖတ်ရလွယ်ကူစေဖို့ အရောင်နဲ့ စာသားဖော်ပြမှုကို ထည့်သွင်းပေးပါတယ်။ Editors များအများစုမှာ syntax highlighting ကို ပြင်ဆင်နိုင်ပါတယ်။
- *Extensions and Integrations* တွေက ပရိုဂရမ်မာတွေအတွက် အထူးပြုကိရိယာတွေဖြစ်ပြီး base editor ထဲမှာ မပါဝင်တဲ့အရာတွေဖြစ်ပါတယ်။ ဥပမာ - ပရိုဂရမ်မာတစ်ဦးဟာ သူ့ကုဒ်ကို ရှင်းပြဖို့ documentation ရေးတတ်ကြပါတယ်။ သူတို့ဟာ spell check extension တစ်ခုကို ထည့်သွင်းပြီး documentation ထဲမှာ စာလုံးပေါင်းအမှားတွေကို ရှာဖွေတတ်ကြပါတယ်။ Extensions များအများစုဟာ အထူးပြု editor တစ်ခုအတွက် ရည်ရွယ်ထားပြီး editor များအများစုမှာ ရနိုင်တဲ့ extensions တွေကို ရှာဖွေရန် နည်းလမ်းပါဝင်ပါတယ်။
- *Customization* က ပရိုဂရမ်မာတစ်ဦးရဲ့ လိုအပ်ချက်အလိုက် ထူးခြားတဲ့ development environment တစ်ခုကို ဖန်တီးနိုင်စေပါတယ်။ Editors များအများစုဟာ အလွန်ပြင်ဆင်နိုင်ပြီး ပရိုဂရမ်မာတွေကို သူတို့ရဲ့ custom extensions တွေ ဖန်တီးနိုင်စေပါတယ်။
#### လူကြိုက်များတဲ့ Editor များနှင့် Web Development Extensions
#### လူကြိုက်များတဲ့ Editors နဲ့ Web Development Extensions
- [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)
- [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
- [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare)
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
- [Atom](https://atom.io/)
- [spell-check](https://atom.io/packages/spell-check)
- [teletype](https://atom.io/packages/teletype)
- [atom-beautify](https://atom.io/packages/atom-beautify)
- [Sublimetext](https://www.sublimetext.com/)
- [emmet](https://emmet.io/)
- [SublimeLinter](http://www.sublimelinter.com/en/stable/)
- [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)
- [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
- [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare)
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
- [Atom](https://atom.io/)
- [spell-check](https://atom.io/packages/spell-check)
- [teletype](https://atom.io/packages/teletype)
- [atom-beautify](https://atom.io/packages/atom-beautify)
- [Sublimetext](https://www.sublimetext.com/)
- [emmet](https://emmet.io/)
- [SublimeLinter](http://www.sublimelinter.com/en/stable/)
### Browser များ
### Browsers
Web Developer တွေအတွက် Browser ကလည်း အရေးကြီးတဲ့ ကိရိယာတစ်ခုဖြစ်ပါတယ်။ Browser တွေက Web ပေါ်မှာ ကုဒ်တွေကို ဘယ်လို အလုပ်လုပ်တယ်ဆိုတာ ကြည့်ဖို့ အသုံးဝင်ပါတယ်။
အရေးကြီးတဲ့ကိရိယာတစ်ခုက browser ဖြစ်ပါတယ်။ Web developers တွေဟာ သူတို့ရဲ့ကုဒ်ကို ဝဘ်ပေါ်မှာ အလုပ်လုပ်ပုံကို ကြည့်ဖို့ browser ကို အားထားကြပါတယ်။ HTML လိုမျိုး editor ထဲမှာရေးထားတဲ့ visual elements တွေကို ပြသဖို့လည်း browser ကို အသုံးပြုကြပါတယ်။
Browser တွေမှာ *Developer Tools* (DevTools) ဆိုတဲ့ Feature တွေပါဝင်ပြီး Application အကြောင်း အရေးကြီးတဲ့ အချက်အလက်တွေကို စုဆောင်းဖို့ ကူညီပါတယ်။
Browser များအများစုမှာ *developer tools* (DevTools) ပါဝင်ပြီး application အကြောင်း အရေးကြီးသော အချက်အလက်တွေကို စုဆောင်းဖို့ အထောက်အကူပေးတဲ့ လုပ်ဆောင်ချက်တွေ ပါဝင်ပါတယ်။ ဥပမာ - ဝဘ်စာမျက်နှာတစ်ခုမှာ အမှားတွေရှိရင် အဲ့ဒီအမှားတွေ ဖြစ်ပေါ်တဲ့အချိန်ကို သိဖို့ sometimes DevTools ကို အသုံးပြုနိုင်ပါတယ်။
#### လူကြိုက်များတဲ့ Browser များနှင့် DevTools
#### လူကြိုက်များတဲ့ Browsers နဲ့ DevTools
- [Edge](https://docs.microsoft.com/microsoft-edge/devtools-guide-chromium/?WT.mc_id=academic-77807-sagibbon)
- [Chrome](https://developers.google.com/web/tools/chrome-devtools/)
- [Firefox](https://developer.mozilla.org/docs/Tools)
- [Edge](https://docs.microsoft.com/microsoft-edge/devtools-guide-chromium/?WT.mc_id=academic-77807-sagibbon)
- [Chrome](https://developers.google.com/web/tools/chrome-devtools/)
- [Firefox](https://developer.mozilla.org/docs/Tools)
### Command Line Tools
ချို့ Developer တွေက ပုံမှန် GUI မျက်နှာပြင်ထက် Command Line ကို ပိုမိုအားထားကြပါတယ်။ Command Line က Developer တွေ Keyboard မှာ အလုပ်လုပ်နေစဉ် Mouse ကို အသုံးမပြုဘဲ အလုပ်လုပ်နိုင်စေပါတယ်။
စ်ချို့သော developers တွေဟာ နေ့စဉ်လုပ်ငန်းစဉ်တွေကို ပုံမှန် graphical view မဟုတ်တဲ့ command line ကို အားထားကြပါတယ်။ ကုဒ်ရေးရာမှာ အများကြီးရိုက်ရတာကြောင့် တစ်ချို့သော developers တွေဟာ ကီးဘုတ်ပေါ်မှာ အလုပ်လုပ်နေတဲ့ flow ကို မဖြတ်ချင်ကြပါဘူး။ သူတို့ဟာ desktop windows တွေကို ပြောင်းဖို့၊ ဖိုင်အမျိုးမျိုးကို အလုပ်လုပ်ဖို့၊ ကိရိယာတွေကို အသုံးပြုဖို့ keyboard shortcuts တွေကို အသုံးပြုကြပါတယ်။ Command line ကို အသုံးပြုရတဲ့ အကျိုးကျေးဇူးတစ်ခုက command line tools တွေကို အသုံးပြုပြီး mouse နဲ့ keyboard ကြား ပြောင်းဖို့ မလိုအပ်ဘဲ အများကြီးလုပ်ဆောင်နိုင်ပါတယ်။ Command line ဟာ ပြင်ဆင်နိုင်ပြီး သင့်ရဲ့ configuration ကို သိမ်းဆည်းထားနိုင်သလို နောက်ပိုင်း ပြောင်းလဲနိုင်ပြီး အခြား development machines တွေမှာ ပြန်တင်နိုင်ပါတယ်။ Development environment တွေဟာ ပရိုဂရမ်မာတစ်ဦးစီအလိုက် ထူးခြားတဲ့အတွက် တစ်ချို့က command line ကို မသုံးကြပါဘူး၊ တစ်ချို့က အပြည့်အဝအားထားကြပြီး တစ်ချို့က နှစ်မျိုးလုံးကို ရောစပ်အသုံးပြုကြပါတယ်။
#### လူကြိုက်များတဲ့ Command Line Tools
### လူကြိုက်များတဲ့ Command Line Options
- [Git](https://git-scm.com/) (💻 အများစုသော OS တွေမှာ ပါဝင်ပြီးသား)
- [NPM](https://www.npmjs.com/)
- [Yarn](https://classic.yarnpkg.com/en/docs/cli/)
Command line options တွေဟာ သင့်ရဲ့ operating system အလိုက် ကွဲပြားပါတယ်။
### Documentation
*💻 = operating system မှာ အလိုအလျောက်ပါဝင်ပြီးသား*
Developer တစ်ဦးအနေနဲ့ အသစ်တစ်ခုကို လေ့လာချင်တဲ့အခါ Documentation ကို အားထားကြပါတယ်။ Documentation တွေက Tools နဲ့ ဘာသာစကားတွေကို မှန်ကန်စွာ အသုံးပြုဖို့ လမ်းညွှန်ပေးပါတယ်။
#### Windows
#### လူကြိုက်များတဲ့ Web Development Documentation
- [Powershell](https://docs.microsoft.com/powershell/scripting/overview?view=powershell-7/?WT.mc_id=academic-77807-sagibbon) 💻
- [Command Line](https://docs.microsoft.com/windows-server/administration/windows-commands/windows-commands/?WT.mc_id=academic-77807-sagibbon) (CMD လို့လည်း သိကြပါတယ်) 💻
- [Windows Terminal](https://docs.microsoft.com/windows/terminal/?WT.mc_id=academic-77807-sagibbon)
- [mintty](https://mintty.github.io/)
- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web)
- [Frontend Masters](https://frontendmasters.com/learn/)
- [Web.dev](https://web.dev)
- [Microsoft Developer Docs](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers)
- [W3 Schools](https://www.w3schools.com/where_to_start.asp)
#### MacOS
✅ သုတေသနလုပ်ပါ - Web Developer ရဲ့ ပတ်ဝန်းကျင်နဲ့ Web Designer ရဲ့ ပတ်ဝန်းကျင်ကို နှိုင်းယှဉ်ကြည့်ပါ။
- [Terminal](https://support.apple.com/guide/terminal/open-or-quit-terminal-apd5265185d-f365-44cb-8b09-71a064a42125/mac) 💻
- [iTerm](https://iterm2.com/)
- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7/?WT.mc_id=academic
---
## 🚀 စိန်ခေါ်မှု
Programming Language တချို့ကို နှိုင်းယှဉ်ကြည့်ပါ။ JavaScript နဲ့ Java ရဲ့ ထူးခြားချက်တွေက ဘာတွေလဲ? COBOL နဲ့ Go ရဲ့ ကွာခြားချက်တွေက ဘာတွေလဲ?
## သင်ခန်းစာပြီးနောက် စမ်းမေးခွန်း
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/2)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
ပရိုဂရမ်မာအနေနဲ့ အသုံးပြုနိုင်တဲ့ ဘာသာစကားအမျိုးမျိုးကို လေ့လာပါ။ ဘာသာစကားတစ်ခုနဲ့ ကုဒ်တစ်ကြောင်းရေးပြီး နောက်ထပ်နှစ်ခုမှာ ပြန်ရေးကြည့်ပါ။ ဘာတွေ သင်ယူရမလဲ?
## အိမ်စာ
[Reading the Docs](assignment.md)
---
**ဝက်ဘ်ဆိုက်မှတ်ချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှန်ကန်မှုအတွက် ကြိုးစားနေပါသော်လည်း၊ အလိုအလျောက်ဘာသာပြန်ဆိုမှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို ကျေးဇူးပြု၍ သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူလဘာသာစကားဖြင့် အာဏာတည်သောရင်းမြစ်အဖြစ် သတ်မှတ်ရန် လိုအပ်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်ဆောင်ရွက်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော နားလည်မှုမှားများ သို့မဟုတ် အဓိပ္ပါယ်မှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှု ဝန်ဆောင်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှုမှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "05666cecb8983a72cf0ce1d18932b5b7",
"translation_date": "2025-08-27T22:52:50+00:00",
"original_hash": "361249da70432ddfd4741c917d1a6f50",
"translation_date": "2025-08-28T18:53:20+00:00",
"source_file": "1-getting-started-lessons/2-github-basics/README.md",
"language_code": "my"
}
@ -14,67 +14,67 @@ CO_OP_TRANSLATOR_METADATA:
![Intro to GitHub](../../../../translated_images/webdev101-github.8846d7971abef6f947909b4f9d343e2a23778aa716ca6b9d71df7174ee5009ac.my.png)
> [Tomomi Imura](https://twitter.com/girlie_mac) ရဲ့ Sketchnote
## သင်ခန်းစာမတိုင်မီ စမ်းမေးခွန်း
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/3)
## သင်ခန်းစာမတိုင်မီ Quiz
[Pre-lecture quiz](https://ff-quizzes.netlify.app)
## မိတ်ဆက်
ဒီသင်ခန်းစာမှာ အောက်ပါအချက်တွေကို လေ့လာပါမယ်-
- သင့်စက်မှာ လုပ်ဆောင်မှုတွေကို မှတ်တမ်းတင်ခြင်း
- သင့်စက်မှာ လုပ်ဆောင်မှုတွေကို tracking လုပ်ခြင်း
- အခြားသူတွေနဲ့ ပရောဂျက်တွေမှာ အတူတူလုပ်ဆောင်ခြင်း
- open source software တွေကို ဘယ်လိုပံ့ပိုးပေးနိုင်မလဲ
- open source software တွေကို ဘယ်လိုအကူအညီပေးနိုင်မလဲ
### ကြိုတင်လိုအပ်ချက်များ
### လိုအပ်ချက်များ
စတင်မလုပ်ခင် Git install လုပ်ထားမထား စစ်ဆေးဖို့လိုပါတယ်။ Terminal မှာ `git --version` လို့ရိုက်ပါ။
စတင်မလုပ်ခင် Git install လုပ်ထားမထား စစ်ဆေးဖို့လိုအပ်ပါတယ်။ Terminal မှာ `git --version` လို့ ရိုက်ပါ။
Git install မလုပ်ထားရင် [Git ကို ဒေါင်းလု်လုပ်ပါ](https://git-scm.com/downloads)။ ပြီးရင် Terminal မှာ သင့်ရဲ့ Git profile ကို setup လုပ်ပါ:
Git install မလုပ်ထားရင် [Git ကို ဒေါင်းလု်လုပ်ပါ](https://git-scm.com/downloads)။ ပြီးရင် Terminal မှာ သင့်ရဲ့ Git profile ကို setup လုပ်ပါ:
* `git config --global user.name "your-name"`
* `git config --global user.email "your-email"`
Git configure လုပ်ထားမထား စစ်ဆေးဖို့ `git config --list` လို့ရိုက်ပါ။
Git configuration ရှိမရှိ စစ်ဆေးဖို့ `git config --list` လို့ ရိုက်ပါ။
GitHub account တစ်ခု၊ code editor (ဥပမာ Visual Studio Code) တစ်ခု၊ Terminal (သို့မဟုတ် command prompt) ကို ဖွင့်ထားဖို့လိုပါတယ်။
GitHub account တစ်ခု၊ code editor (Visual Studio Code ကောင်းကောင်း) တစ်ခု၊ Terminal (command prompt) ကို ဖွင့်ထားဖို့ လိုအပ်ပါတယ်။
[github.com](https://github.com/) ကိုသွားပြီး account တစ်ခုဖန်တီးပါ၊ မဟုတ်ရင် login လုပ်ပြီး profile ကို ဖြည့်ပါ။
[github.com](https://github.com/) ကို သွားပြီး account တစ်ခုဖွင့်ပါ၊ မဖွင့်ရသေးရင် ဖွင့်ပါ၊ ဖွင့်ပြီးရင် profile ကို ဖြည့်ပါ။
✅ GitHub က ကမ္ဘာ့ code repository တစ်ခုသာမဟုတ်ပါဘူး၊ အခြား platform တွေလည်းရှိပါတယ်။ ဒါပေမယ့် GitHub က အများဆုံးလူသိများပါတယ်။
✅ GitHub က ကမ္ဘာ့တစ်ခုတည်းသော code repository မဟုတ်ပါဘူး၊ အခြား platform တွေရှိပေမယ့် GitHub က အများဆုံး အသိအကျွမ်းရရှိထားပါတယ်။
### ပြင်ဆင်မှု
သင့်ရဲ့ local machine (laptop သို့မဟုတ် PC) မှာ code project ပါတဲ့ folder တစ်ခုလိုအပ်ပါတယ်။ GitHub မှာ public repository တစ်ခုလည်းလိုအပ်ပါတယ်။ ဒါက အခြားသူတွေရဲ့ project တွေကို ဘယ်လိုပံ့ပိုးပေးရမလဲဆိုတာကို သင်ခန်းစာအနေနဲ့ အသုံးပြုနိုင်ပါတယ်။
သင့်ရဲ့ local machine (laptop သို့မဟုတ် PC) မှာ code project ပါတဲ့ folder တစ်ခုလိုအပ်ပါတယ်။ GitHub မှာ public repository တစ်ခုလည်း လိုအပ်ပါတယ်။ ဒါက အခြားသူတွေရဲ့ project တွေကို ဘယ်လိုအကူအညီပေးရမလဲဆိုတာကို သင်ခန်းစာအနေနဲ့ အသုံးပြုနိုင်ပါတယ်။
---
## Code စီမံခန့်ခွဲမှု
သင့် local machine မှာ code project ပါတဲ့ folder တစ်ခုရှိပြီး git ကို အသုံးပြုပြီး version control စနစ်နဲ့ progress ကို track လုပ်ချင်တယ်ဆိုပါစို့။ git ကို အသုံးပြုတာကို အချို့လူတွေက "အနာဂတ်မှာ ကိုယ့်ကိုယ်ကိုချစ်တဲ့စာရေးတာ" လို့တင်စားကြပါတယ်။ commit messages တွေကို ရက်ပေါင်းများစွာ၊ လများစွာ၊ နှစ်များစွာအကြာမှာ ပြန်ဖတ်တဲ့အခါ သင့်ရဲ့ဆုံးဖြတ်ချက်ကို ဘာကြောင့်လုပ်ခဲ့တယ်ဆိုတာကို ပြန်လည်သတိရနိုင်ပါတယ်။ ဒါမှမဟုတ် ပြောင်းလဲမှုကို "rollback" လုပ်နိုင်ပါတယ်။ ဒါဟာ သင့်ရဲ့ commit messages တွေကောင်းမွန်တဲ့အခါမှာ ဖြစ်နိုင်ပါတယ်။
သင့် local folder မှာ code project တစ်ခုရှိပြီး git (version control system) ကို အသုံးပြုပြီး သင့်ရဲ့ လုပ်ဆောင်မှုတွေကို tracking လုပ်ချင်တယ်ဆိုပါစို့။ git ကို အသုံးပြုတာကို အချို့လူတွေက "သင့်ရဲ့ အနာဂတ်ကိုချစ်တဲ့ စာရေးခြင်း" လို့ နှိုင်းယှဉ်တယ်။ commit messages တွေကို ရက်ပေါင်းများစွာ၊ လများစွာ၊ နှစ်များစွာအကြာမှာ ပြန်ဖတ်တဲ့အခါ သင့်ရဲ့ ဆုံးဖြတ်ချက်ကို ဘာကြောင့်လုပ်ခဲ့တာလဲ၊ သို့မဟုတ် ပြောင်းလဲမှုကို "rollback" လုပ်ဖို့ အလွယ်တကူ သတိရနိုင်ပါတယ်။
### Task: Repository တစ်ခုဖန်တီးပြီး code ကို commit လုပ်ပါ
### Task: Repository တစ်ခုဖန်တီးပြီး code commit လုပ်ပါ
> ဗီဒီယိုကို ကြည့်ပါ
>
> [![Git နှင့် GitHub အခြေခံဗီဒီယို](https://img.youtube.com/vi/9R31OUPpxU4/0.jpg)](https://www.youtube.com/watch?v=9R31OUPpxU4)
> [![Git and GitHub basics video](https://img.youtube.com/vi/9R31OUPpxU4/0.jpg)](https://www.youtube.com/watch?v=9R31OUPpxU4)
1. **GitHub မှာ repository ဖန်တီးပါ**။ GitHub.com မှာ repositories tab မှာ သို့မဟုတ် navigation bar ရဲ့ အပေါ်ယာဘက်မှာ **new repo** button ကို ရှာပါ။
1. **GitHub မှာ repository တစ်ခုဖန်တီးပါ**။ GitHub.com မှာ repositories tab မှာ သို့မဟုတ် navigation bar ရဲ့ အပေါ်ယာဘက်မှာ **new repo** button ကို ရှာပါ။
1. သင့် repository (folder) ကို နာမည်ပေးပါ။
1. **create repository** ကို ရွေးပါ။
1. **သင့်ရဲ့ working folder ကို သွားပါ**။ Terminal မှာ သင့်ရဲ့ folder (directory) ကို switch လုပ်ပါ။ Terminal မှာ အောက်ပါအတိုင်း ရိုက်ပါ:
1. **သင့်ရဲ့ လုပ်ဆောင်မှု folder ကို ရှာပါ**။ Terminal မှာ သင့်ရဲ့ folder (directory) ကို ရွေးပါ။ အောက်ပါ command ကို ရိုက်ပါ:
```bash
cd [name of your folder]
```
1. **Git repository ကို initialize လုပ်ပါ**Project မှာ အောက်ပါအတိုင်း ရိုက်ပါ:
1. **Git repository ကို initialize လုပ်ပါ**သင့် project မှာ အောက်ပါ command ကို ရိုက်ပါ:
```bash
git init
```
1. **Status ကို စစ်ဆေးပါ**။ Repository ရဲ့ status ကို စစ်ဆေးဖို့ အောက်ပါအတိုင်း ရိုက်ပါ:
1. **Status ကို စစ်ဆေးပါ**။ Repository ရဲ့ status ကို စစ်ဆေးဖို့ အောက်ပါ command ကို ရိုက်ပါ:
```bash
git status
@ -91,24 +91,24 @@ GitHub account တစ်ခု၊ code editor (ဥပမာ Visual Studio Code)
modified: file2.txt
```
`git status` command က typically repo မှာ save လုပ်ဖို့အဆင်သင့်ဖြစ်နေတဲ့ file တွေ၊ သို့မဟုတ် ပြောင်းလဲမှုရှိတဲ့ file တွေကို ပြသပေးပါတယ်။
`git status` command က သင့်ရဲ့ repo မှာ save လုပ်ဖို့ ပြင်ဆင်ထားတဲ့ file တွေ၊ သို့မဟုတ် ပြောင်းလဲမှုရှိတဲ့ file တွေကို ပြသနိုင်ပါတယ်။
1. **File အားလုံးကို tracking အတွက် add လုပ်ပါ**
ဒါကို staging files/ adding files to the staging area လို့လည်းခေါ်ပါတယ်။
1. **File အားလုံးကို tracking လုပ်ပါ**
ဒါကို staging files/ adding files to the staging area လို့လည်း ခေါ်ပါတယ်။
```bash
git add .
```
`git add` နဲ့ `.` argument က သင့်ရဲ့ file အားလုံးနဲ့ ပြောင်းလဲမှုတွေကို tracking အတွက် add လုပ်ပေးပါတယ်။
`git add` နဲ့ `.` argument က သင့်ရဲ့ file အားလုံးကို tracking လုပ်ဖို့ အညွှန်းပေးပါတယ်။
1. **ရွေးချယ်ထားတဲ့ file တွေကို tracking အတွက် add လုပ်ပါ**
1. **ရွေးချယ်ထားတဲ့ file တွေကို tracking လုပ်ပါ**
```bash
git add [file or folder name]
```
ဒီ command က သင့်ရဲ့ next commit မှာ file အားလုံးကို add မလုပ်ချင်တဲ့အခါ ရွေးချယ်ထားတဲ့ file တွေကိုသာ staging area မှာ add လုပ်နိုင်ပါတယ်။
ဒီ command က သင့်ရဲ့ next commit မှာ file အားလုံးကို tracking မလုပ်ချင်တဲ့အခါ ရွေးချယ်ထားတဲ့ file တွေကိုသာ staging area မှာ ထည့်နိုင်ပါတယ်။
1. **File အားလုံးကို unstaging လုပ်ပါ**
@ -116,7 +116,7 @@ GitHub account တစ်ခု၊ code editor (ဥပမာ Visual Studio Code)
git reset
```
ဒီ command က file အားလုံးကို တစ်ခါတည်း unstaging လုပ်နိုင်ပါတယ်။
ဒီ command က file အားလုံးကို unstaging လုပ်ဖို့ အသုံးပြုနိုင်ပါတယ်။
1. **File တစ်ခုကို unstaging လုပ်ပါ**
@ -124,35 +124,35 @@ GitHub account တစ်ခု၊ code editor (ဥပမာ Visual Studio Code)
git reset [file or folder name]
```
ဒီ command က next commit မှာ ထည့်မလိုတဲ့ file တစ်ခုကို unstaging လုပ်နိုင်ပါတယ်။
ဒီ command က next commit မှာ ထည့်မလိုတဲ့ file တစ်ခုကို unstaging လုပ်ဖို့ အသုံးပြုနိုင်ပါတယ်။
1. **သင့်ရဲ့လုပ်ဆောင်မှုကို permanent လုပ်ပါ**။ ဒီအချိန်မှာ သင့်ရဲ့ file တွေကို staging area မှာ add လုပ်ပြီး Git က tracking လုပ်နေပါပြီ။ ပြောင်းလဲမှုကို permanent လုပ်ဖို့ commit လုပ်ဖို့လိုပါတယ်။ Commit လုပ်ဖို့ `git commit` command ကို အသုံးပြုပါ။ Commit က သင့် repo ရဲ့ history မှာ saving point တစ်ခုကို ကိုယ်စားပြုပါတယ်။ Commit လုပ်ဖို့ အောက်ပါအတိုင်း ရိုက်ပါ:
1. **သင့်ရဲ့ လုပ်ဆောင်မှုကို အတည်ပြုပါ**။ ဒီအချိန်မှာ သင့်ရဲ့ file တွေကို staging area မှာ ထည့်ပြီး Git က tracking လုပ်နေပါတယ်။ ပြောင်းလဲမှုကို permanent လုပ်ဖို့ commit လုပ်ဖို့လိုအပ်ပါတယ်။ Commit လုပ်ဖို့ `git commit` command ကို အသုံးပြုပါ။ Commit က သင့် repo ရဲ့ သမိုင်းမှာ save point တစ်ခုကို ကိုယ်စားပြုပါတယ်။ အောက်ပါ command ကို ရိုက်ပါ:
```bash
git commit -m "first commit"
```
ဒီ command က သင့်ရဲ့ file အားလုံးကို commit လုပ်ပြီး "first commit" message ကို ထည့်ပေးပါတယ်။ အနာဂတ် commit messages တွေမှာ သင့်ပြောင်းလဲမှုအမျိုးအစားကို ဖော်ပြနိုင်ဖို့ ပိုမိုဖော်ပြနိုင်တဲ့ description ကို အသုံးပြုပါ။
ဒီ command က သင့်ရဲ့ file အားလုံးကို commit လုပ်ပြီး "first commit" message ကို ထည့်ပါမယ်။ အနာဂတ် commit messages တွေမှာ သင့်ရဲ့ ပြောင်းလဲမှုအမျိုးအစားကို ဖော်ပြဖို့ ပိုမိုဖော်ပြနိုင်တဲ့ description ကို အသုံးပြုပါ။
1. **Local Git repo ကို GitHub နဲ့ ချိတ်ဆက်ပါ**။ Git repo ကို local machine မှာ အသုံးပြုနိုင်ပေမယ့် တစ်ချိန်မှာ file တွေကို backup လုပ်ဖို့ သို့မဟုတ် အခြားသူတွေကို သင့် repo မှာ အတူတူလုပ်ဆောင်ဖို့ ဖိတ်ခေါ်ဖို့လိုပါတယ်။ GitHub က အဲ့ဒီအတွက် အကောင်းဆုံးနေရာတစ်ခုဖြစ်ပါတယ်။ GitHub မှာ repo တစ်ခုဖန်တီးပြီးသားဖြစ်တဲ့အတွက် local Git repo ကို GitHub နဲ့ ချိတ်ဆက်ဖို့သာလိုပါတယ်။ `git remote add` command က အဲ့ဒီအလုပ်ကို လုပ်ပေးပါမယ်။ အောက်ပါ command ကို ရိုက်ပါ:
1. **Local Git repo ကို GitHub နဲ့ ချိတ်ဆက်ပါ**။ Git repo ကို သင့်စက်မှာ အသုံးပြုနိုင်ပေမယ့် တစ်ချိန်မှာ file တွေကို backup လုပ်ဖို့ သို့မဟုတ် အခြားသူတွေကို သင့် repo မှာ အလုပ်လုပ်ဖို့ ဖိတ်ခေါ်ဖို့ GitHub ကို အသုံးပြုချင်ပါလိမ့်မယ်။ GitHub မှာ repo တစ်ခုဖန်တီးပြီးသားဖြစ်တဲ့အတွက် local Git repo ကို GitHub နဲ့ ချိတ်ဆက်ဖို့ command `git remote add` ကို အသုံးပြုပါ။ အောက်ပါ command ကို ရိုက်ပါ:
> မှတ်ချက်- Command ရိုက်မလုပ်ခင် GitHub repo page ကိုသွားပြီး repository URL ကို ရှာပါ။ အောက်ပါ command မှာ ```https://github.com/username/repository_name.git``` ကို သင့် GitHub URL နဲ့ အစားထိုးပါ။
> သတိပြုပါ၊ command ကို ရိုက်မလုပ်ခင် GitHub repo page ကို သွားပြီး repository URL ကို ရှာပါ။ အောက်ပါ command မှာ ```https://github.com/username/repository_name.git``` ကို သင့် GitHub URL နဲ့ အစားထိုးပါ။
```bash
git remote add origin https://github.com/username/repository_name.git
```
ဒီ command က "origin" လို့ခေါ်တဲ့ remote connection တစ်ခုကို ဖန်တီးပြီး GitHub repository ကို ချိတ်ဆက်ပေးပါတယ်။
ဒီ command က "origin" လို့ခေါ်တဲ့ remote connection တစ်ခုကို ဖန်တီးပြီး သင့် GitHub repository ကို ချိတ်ဆက်ပါမယ်။
1. **Local file တွေကို GitHub ကို ပို့ပါ**။ အခုအချိန်မှာ local repo နဲ့ GitHub repo အကြား connection တစ်ခုဖန်တီးပြီးသားဖြစ်ပါတယ်။ File တွေကို GitHub ကို ပို့ဖို့ `git push` command ကို အသုံးပြုပါ:
> မှတ်ချက်- သင့် branch name က ```main``` နဲ့ default အနေနဲ့ မတူနိုင်ပါတယ်။
> သတိပြုပါ၊ သင့် branch name က ```main``` နဲ့ default အနေနဲ့ မတူနိုင်ပါတယ်။
```bash
git push -u origin main
```
ဒီ command က သင့်ရဲ့ "main" branch ရဲ့ commit တွေကို GitHub ကို ပို့ပေးပါတယ်။
ဒီ command က သင့်ရဲ့ "main" branch ရဲ့ commits တွေကို GitHub ကို ပို့ပါမယ်။
2. **အခြားပြောင်းလဲမှုတွေကို ထည့်ပါ**။ ပြောင်းလဲမှုတွေကို ဆက်လက်လုပ်ဆောင်ပြီး GitHub ကို push လုပ်ချင်ရင် အောက်ပါ command သုံးခုကို အသုံးပြုရပါမယ်:
@ -162,29 +162,29 @@ GitHub account တစ်ခု၊ code editor (ဥပမာ Visual Studio Code)
git push
```
> Tip- `.gitignore` file တစ်ခုကို အသုံးပြုပြီး GitHub မှာ track လုပ်ချင်မယ့် file တွေကို ဖယ်ရှားနိုင်ပါတယ်။ ဥပမာ- သင့် folder မှာရှိတဲ့ notes file တစ်ခုက public repository မှာ မပါသင့်တဲ့အခါ။ `.gitignore` file template တွေကို [.gitignore templates](https://github.com/github/gitignore) မှာ ရှာနိုင်ပါတယ်။
> Tip, `.gitignore` file တစ်ခုကို အသုံးပြုပြီး GitHub မှာ tracking မလုပ်ချင်တဲ့ file တွေကို ဖယ်ရှားနိုင်ပါတယ်။ ဥပမာ- သင့် folder မှာရှိတဲ့ notes file တစ်ခုက public repository မှာ မပါသင့်တဲ့ file ဖြစ်နိုင်ပါတယ်။ `.gitignore` file templates တွေကို [.gitignore templates](https://github.com/github/gitignore) မှာ ရှာနိုင်ပါတယ်။
#### Commit messages
Git commit subject line က အောက်ပါစာကြောင်းကို ပြည့်စုံစေပါမယ်-
Git commit subject line က အောက်ပါ စာကြောင်းကို ပြည့်စုံစေပါမယ်:
If applied, this commit will <your subject line here>
Subject မှာ imperative, present tense ကို အသုံးပြုပါ- "change" မဟုတ်ရင် "changed" သို့မဟုတ် "changes" မဟုတ်ပါဘူး
Subject မှာ imperative, present tense ကို အသုံးပြုပါ: "change" မဟုတ် "changed" သို့မဟုတ် "changes" မဟုတ်ပါ။
Subject အတိုင်း body (optional) မှာလည်း imperative, present tense ကို အသုံးပြုပါ။ Body မှာ ပြောင်းလဲမှုရဲ့ motivation ကို ဖော်ပြပြီး ယခင်အခြေအနေနဲ့ နှိုင်းယှဉ်ပါ။ `why` ကို ရှင်းပြတာဖြစ်ပြီး `how` ကို မဟုတ်ပါ။
✅ GitHub ကို အချိန်အနည်းငယ် သွားလေ့လာပါ။ Commit message ကောင်းကောင်းတစ်ခုကို ရှာနိုင်ပါသလား? အနည်းဆုံး message တစ်ခုကို ရှာနိုင်ပါသလား? Commit message မှာ ဘယ်အချက်တွေက အရေးကြီးပြီး အသုံးဝင်တယ်လို့ သင်ထင်ပါသလဲ?
✅ GitHub ကို အချိန်အနည်းငယ် သွားလေ့လာပါ။ Commit message ကောင်းတစ်ခုကို ရှာနိုင်ပါသလား? အနည်းဆုံး message တစ်ခုကို ရှာနိုင်ပါသလား? Commit message မှာ ဘယ်အချက်တွေက အရေးကြီးပြီး အသုံးဝင်တယ်လို့ သင်ထင်ပါသလဲ?
### Task: အတူတူလုပ်ဆောင်ပါ
GitHub မှာ အရာတွေကို ထည့်သွင်းတာရဲ့ အဓိကရည်ရွယ်ချက်က အခြား developer တွေနဲ့ အတူတူလုပ်ဆောင်နိုင်ဖို့ပါ။
GitHub မှာ အရာတွေကို ထည့်သွင်းတာရဲ့ အဓိကရည်ရွယ်ချက်က အခြား developer တွေနဲ့ အတူတူလုပ်ဆောင်နိုင်ဖို့ ဖြစ်ပါတယ်
## အခြားသူတွေနဲ့ ပရောဂျက်တွေမှာ အတူတူလုပ်ဆောင်ခြင်း
## အခြားသူတွေနဲ့ ပရောဂျက်တွေမှာ အလုပ်လုပ်ခြင်း
> ဗီဒီယိုကို ကြည့်ပါ
>
> [![Git နှင့် GitHub အခြေခံဗီဒီယို](https://img.youtube.com/vi/bFCM-PC3cu8/0.jpg)](https://www.youtube.com/watch?v=bFCM-PC3cu8)
> [![Git and GitHub basics video](https://img.youtube.com/vi/bFCM-PC3cu8/0.jpg)](https://www.youtube.com/watch?v=bFCM-PC3cu8)
သင့် repository မှာ `Insights > Community` ကို သွားပြီး သင့် project က recommended community standards တွေနဲ့ ဘယ်လိုနှိုင်းယှဉ်နိုင်တယ်ဆိုတာကို ကြည့်ပါ။
သင့် repository မှာ `Insights > Community` ကို သွားပြီး သင့် project က recommended community standards တွေနဲ့ ဘယ်လိုနှိုင်းယှဉ်နိုင်လဲဆိုတာကို ကြည့်ပါ။
GitHub repo ကို တိုးတက်အောင်လုပ်နိုင်တဲ့ အချက်တွေက:
- **Description**. သင့် project အတွက် description ထည့်ထားပါသလား?
@ -193,26 +193,26 @@ GitHub မှာ အရာတွေကို ထည့်သွင်းတာ
- **Code of Conduct**. [Code of Conduct](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/) ရှိပါသလား?
- **License**. အရေးကြီးဆုံးအနေနဲ့ [license](https://docs.github.com/articles/adding-a-license-to-a-repository/) ရှိပါသလား?
ဒီ resource တွေက အသစ် join လုပ်တဲ့ team member တွေကို အကျိုးရှိစေပါမယ်။ Contributor တွေက သင့် code ကို မကြည့်ခင် project က သင့်အချိန်ကို သုံးဖို့ သင့်တော်တဲ့နေရာလားဆိုတာကို သိဖို့ အရင်ဆုံး ဒီအချက်တွေကို ကြည့်ကြပါတယ်။
ဒီ resource တွေက အသစ် join လုပ်တဲ့ team member တွေကို အကျိုးရှိစေပါမယ်။ Contributor တွေက သင့် code ကို မကြည့်ခင် project ရဲ့ အခြေအနေကို ကြည့်ပြီး သင့် project က သူတို့ရဲ့ အချိန်ကို သုံးဖို့ သင့်တော်တဲ့နေရာလားဆိုတာကို စဉ်းစားပါမယ်။
✅ README file တွေက ပြင်ဆင်ဖို့ အချိန်ယူရတယ်၊ ဒါပေမယ့် 忙နေတဲ့ maintainer တွေက မကြည့်မိတတ်ပါတယ်။ အလွန်ဖော်ပြချက်ကောင်းတဲ့ README file တစ်ခုကို ရှာနိုင်ပါသလား? မှတ်ချက်- [README file ကောင်းကောင်းရေးဖို့ tools](https://www.makeareadme.com/) တွေရှိပါတယ်၊ သင်စမ်းသုံးချင်နိုင်ပါတယ်။
✅ README file တွေက ပြင်ဆင်ဖို့ အချိန်ယူရတယ်၊ ဒါပေမယ့် 忙နေတဲ့ maintainer တွေက often neglect လုပ်တတ်ပါတယ်။ အလွန်ဖော်ပြချက်ကောင်းတဲ့ README file တစ်ခုကို ရှာနိုင်ပါသလား? Note: [README file ကောင်းတွေ ဖန်တီးဖို့ tools](https://www.makeareadme.com/) တွေရှိပါတယ်၊ သင်စမ်းသုံးချင်နိုင်ပါတယ်။
### Task: Code တစ်ချို့ကို Merge လုပ်ပါ
Contributing docs တွေက လူတွေ project ကို contribute လုပ်ဖို့ အကူအညီပေးပါတယ်။ ဘယ်အမျိုးအစားရဲ့ contribution တွေကို ရှာနေတယ်ဆိုတာနဲ့ process ဘယ်လိုလုပ်ရမယ်ဆိုတာကို ရှင်းပြပါတယ်။ Contributor တွေက သင့် GitHub repo ကို contribute လုပ်ဖို့ အောက်ပါအဆင့်တွေကို လိုက်နာရပါမယ်:
Contributing docs တွေက လူတွေ project ကို အကူအညီပေးဖို့ လမ်းညွှန်ပါတယ်။ ဘယ်အမျိုးအစားအကူအညီတွေကို ရှာနေတယ်ဆိုတာနဲ့ process ဘယ်လိုလုပ်ရမယ်ဆိုတာကို ရှင်းပြပါတယ်။ Contributors တွေ GitHub repo မှာ အကူအညီပေးဖို့ အောက်ပါအဆင့်တွေကို လိုက်နာရပါမယ်:
1. **Forking your repo** Contributor တွေကို သင့် project ကို _fork_ လုပ်ဖို့ လိုအပ်ပါတယ်။ Forking ဆိုတာ သင့် repository ရဲ့ replica ကို သူတို့ရဲ့ GitHub profile မှာ ဖန်တီးတာဖြစ်ပါတယ်။
1. **Clone**. သူတို့ project ကို local machine မှာ clone လုပ်ပါ။
1. **Create a branch**. Contributor တွေကို သူတို့ရဲ့အလုပ်အတွက် _branch_ တစ်ခုဖန်တီးဖို့ တိုက်တွန်းပါ
1. **Focus their change on one area**. Contributor တွေကို တစ်ခါ commit မှာ တစ်ခုတည်းသောအရာကို အာရုံစိုက်ဖို့ တိုက်တွန်းပါ- ဒါက သူတို့ရဲ့အလုပ်ကို merge လုပ်နိုင်တဲ့ အခွင့်အလမ်းကို မြှင့်တင်ပေးပါတယ်။ ဥပမာ- bug fix တစ်ခုရေးတာ၊ feature အသစ်တစ်ခုထည့်တာ၊ test အချို့ကို update လုပ်တာ- သင့်အနေနဲ့ ၃ ခုထဲက ၂ ခု သို့မဟုတ် ၁ ခုကိုသာ implement လုပ်ချင်ရင် ဘာဖြစ်မလဲ?
1. **Forking your repo**. Contributor တွေ project ကို _fork_ လုပ်ဖို့လိုအပ်ပါတယ်။ Forking က သင့် repository ရဲ့ replica ကို သူတို့ရဲ့ GitHub profile မှာ ဖန်တီးတာဖြစ်ပါတယ်။
1. **Clone**. Forked project ကို သူတို့ရဲ့ local machine မှာ clone လုပ်ပါ။
1. **Create a branch**. Contributor တွေ သူတို့ရဲ့ အလုပ်အတွက် _branch_ တစ်ခုဖန်တီးဖို့လိုအပ်ပါတယ်
1. **Focus their change on one area**. Contributor တွေကို တစ်ခါ commit မှာ တစ်ခုတည်းသော အရာကို အာရုံစိုက်ဖို့ တိုက်တွန်းပါ။ ဒါက သူတို့ရဲ့ အလုပ်ကို merge လုပ်နိုင်တဲ့ အခွင့်အရေးကို မြှင့်တင်ပါမယ်။ ဥပမာ- bug fix တစ်ခုရေး၊ feature အသစ်တစ်ခုထည့်၊ test အချို့ကို update လုပ်တယ်ဆိုပါစို့။ သင့်အနေနဲ့ ၃ ခုထဲက ၂ ခု သို့မဟုတ် ၁ ခုကိုသာ implement လုပ်ချင်ရင် ဘာဖြစ်မလဲ?
✅ Branch တွေက code ကောင်းကောင်းရေးပြီး ship လုပ်ဖို့ အရေးကြီးတဲ့အခြေအနေတွေကို စဉ်းစားနိုင်ပါသလား?
✅ Branch တွေက ကောင်းတဲ့ code ရေးပြီး publish လုပ်ဖို့ အရေးကြီးတဲ့ အခြေအနေတွေကို စဉ်းစားပါ။ ဘယ်လို use case တွေကို သင်စဉ်းစားနိုင်ပါသလဲ?
> မှတ်ချက်- သင်လိုချင်တဲ့ပြောင်းလဲမှုကို အခြားသူတွေကလုပ်ဖို့ မစောင့်ပါနဲ့၊ သင့်အလုပ်အတွက် branch တွေကို ဖန်တီးပါ။ သင့်ရဲ့ commit တွေကို သင့် "checked out" လုပ်ထားတဲ့ branch မှာသာလုပ်ပါမယ်။ `git status` ကို အသုံးပြုပြီး ဘယ် branch မှာရှိတယ်ဆိုတာကို စစ်ဆေးပါ။
> Note, သင်လိုချင်တဲ့ ပြောင်းလဲမှုကို သင်ကိုယ်တိုင် branch တွေဖန်တီးပြီး လုပ်ဆောင်ပါ။ သင့်ရဲ့ commit တွေကို သင့်ရဲ့ "checked out" လုပ်ထားတဲ့ branch မှာသာ လုပ်ပါမယ်။ `git status` ကို အသုံးပြုပြီး သင့်ရဲ့ branch ကို စစ်ဆေးပါ။
Contributor workflow ကို လေ့လာကြပါစို့။ Contributor က repo ကို _fork_ လုပ်ပြီး _clone_ လုပ်ထားပြီး local machine မှာ Git repo တစ်ခုရှိပြီးသားဖြစ်တယ်လို့ ယူဆပါ:
1. **Branch တစ်ခုဖန်တီးပါ**. Contributor ရဲ့ပြောင်းလဲမှုတွေကို ထည့်သွင်းမယ့် branch ကို ဖန်တီးဖို့ `git branch` command ကို အသုံးပြုပါ:
1. **Branch တစ်ခုဖန်တီးပါ**. Contributor ရဲ့ ပြောင်းလဲမှုတွေကို ထည့်သွင်းမယ့် branch ကို ဖန်တီးဖို့ `git branch` command ကို အသုံးပြုပါ:
```bash
git branch [branch-name]
@ -224,93 +224,96 @@ Contributor workflow ကို လေ့လာကြပါစို့။ Contri
git switch [branch-name]
```
1. **အလုပ်လုပ်ပါ**. ဒီအချိန်မှာ သင့်ပြောင်းလဲမှုတွေကို ထည့်သွင်းပါ။ Git ကို အောက်ပါ command တွေကို အသုံးပြုပြီး ပြောပြဖို့ မမေ့ပါနဲ့:
1. **အလုပ်လုပ်ပါ**. အခုအချိန်မှာ ပြောင်းလဲမှုတွေကို ထည့်သွင်းပါ။ Git ကို အောက်ပါ command တွေကို အသုံးပြုပြီး ပြောင်းလဲမှုတွေကို သိစေပါ:
```bash
git add .
git commit -m "my changes"
```
Commit ကို အကောင်းဆုံးနာမည်ပေးပါ၊ သင့်အတွက်သာမက repo maintainer အတွက်လည်း အရေးကြီးပါတယ်။
Commit ကို နာမည်ကောင်းပေးဖို့ မမေ့ပါနဲ့၊ သင့်အတွက်သာမက repo maintainer အတွက်လည်း အရေးကြီးပါတယ်။
1. **သင့်အလုပ်ကို `main` branch နဲ့ ပေါင်းစည်းပါ**. တစ်ချိန်မှာ သင့်အလုပ်ပြီးဆုံးပြီး `main` branch နဲ့ ပေါင်းစည်းချင်ပါတယ်။ `main` branch က meantime မှာ ပြောင်းလဲမှုရှိနိုင်ပါတယ်၊ ဒါကြောင့် အောက်ပါ command တွေကို အသုံးပြုပြီး update လုပ်ပါ:
1. **Main branch နဲ့ အလုပ်ကို ပေါင်းစည်းပါ**. Contributor က အလုပ်ပြီးဆုံးပြီး `main` branch နဲ့ အလုပ်ကို ပေါင်းစည်းချင်ပါတယ်။ `main` branch က meantime မှာ ပြောင်းလဲမှုရှိနိုင်ပါတယ်၊ ဒါကြောင့် အောက်ပါ command တွေကို အသုံးပြုပြီး update လုပ်ပါ:
```bash
git switch main
git pull
```
ဒီအချိန်မှာ conflict ဖြစ်နိုင်တဲ့အခြေအနေတွေကို သင့် working branch မှာဖြစ်စေဖို့လိုပါတယ်။ အောက်ပါ command တွေကို run လုပ်ပါ:
အခုအချိန်မှာ conflict ဖြစ်နိုင်တဲ့အခြေအနေတွေကို working branch မှာဖြစ်စေဖို့လိုအပ်ပါတယ်။ အောက်ပါ command တွေကို အသုံးပြုပါ:
GitHub ရဲ့ fork လုပ်ထားတဲ့ repo ကိုသွားပြီး သင် push လုပ်ထားတဲ့ remote branch ကိုဖျက်ပစ်ပါ။
```bash
git switch [branch_name]
git merge main
```
`Pull request` ဆိုတာ အနည်းငယ်အဓိပ္ပာယ်မမှန်သလိုပဲ။ အကြောင်းကတော့ သင်ဟာ project ကို သင့်ရဲ့ပြောင်းလဲမှုတွေ push လုပ်ချင်တာပါ။ ဒါပေမယ့် maintainer (project ရဲ့ပိုင်ရှင်) သို့မဟုတ် core team က သင့်ပြောင်းလဲမှုတွေကို project ရဲ့ "main" branch နဲ့ပေါင်းစည်းမလားဆိုတာ ဆုံးဖြတ်ဖို့လိုပါတယ်။ ဒါကြောင့် သင်ဟာ maintainer ကို ပြောင်းလဲမှုအပေါ်ဆုံးဖြတ်ချက်တောင်းနေတဲ့အရာပါ။
ဒီ command က `main` branch ရဲ့ ပြောင်းလဲမှုတွေကို contributor ရဲ့ branch မှာ ထည့်သွင်းပါမယ်။ Conflict ဖြစ်ရင် VS Code က Git ရဲ့ _confusion_ ကို ပြသပြီး သင့်
`Pull request` ဆိုတာ အရမ်းအဆန်းထင်ရတယ်၊ အကြောင်းကတော့ သင်တကယ်တော့ သင့်ပြောင်းလဲမှုတွေကို ပရောဂျက်ထဲသို့ push လုပ်ချင်တာပါ။ ဒါပေမယ့် maintainer (ပရောဂျက်ပိုင်ရှင်) သို့မဟုတ် core team က သင့်ပြောင်းလဲမှုတွေကို ပရောဂျက်ရဲ့ "main" branch နဲ့ပေါင်းစည်းမယ့်အခါ အတည်ပြုဖို့လိုပါတယ်။ ဒါကြောင့် သင်က maintainer ကို ပြောင်းလဲမှုအပေါ်ဆုံးဖြတ်ချက်တစ်ခုကို တောင်းဆိုနေတဲ့အရာဖြစ်ပါတယ်။
Pull request က branch တစ်ခုမှာပြုလုပ်ထားတဲ့ ပြောင်းလဲတွေကို နှိုင်းယှဉ်ပြီး ဆွေးနွေးဖို့နေရာတစ်ခုပါ။ Review, comment, integrated test စတာတွေပါဝင်ပါတယ်။ Pull request ကောင်းတစ်ခုဟာ commit message နဲ့တူတဲ့ စည်းမျဉ်းတွေကိုလိုက်နာပါတယ်။ သင့်အလုပ်က အခက်အခဲတစ်ခုကိုဖြေရှင်းပေးနိုင်တဲ့အခါ issue tracker မှာ issue တစ်ခုကို reference ထည့်နိုင်ပါတယ်။ ဒါကို `#` နဲ့ issue နံပါတ်ကိုထည့်ရပါတယ်။ ဥပမာ `#97` လိုပါ။
Pull request က branch တစ်ခုမှာ ပြောင်းလဲမှုတွေကို နှိုင်းယှဉ်ပြီး ဆွေးနွေးဖို့နေရာတစ်ခုဖြစ်ပါတယ်။ Review, comment, integrated tests နဲ့ အခြားအရာတွေပါဝင်ပါတယ်။ Pull request တစ်ခုက commit message တစ်ခုလိုပဲ စည်းမျဉ်းတွေကိုလိုက်နာသင့်ပါတယ်။ သင့်အလုပ်က ဥပမာအားဖြင့် issue တစ်ခုကို ဖြေရှင်းပေးတယ်ဆိုရင် issue tracker မှာ issue တစ်ခုကို reference ထည့်နိုင်ပါတယ်။ ဒါကို `#` နဲ့ သင့် issue ရဲ့ နံပါတ်ကို ထည့်ရေးရပါတယ်။ ဥပမာ `#97` လိုပါ။
🤞 အားလုံးအဆင်ပြေပြီး project owner(s) က သင့်ပြောင်းလဲမှုတွေကို project ထဲမှာပေါင်းစည်းပေးမယ်လို့မျှော်လင့်ပါတယ် 🤞
🤞အားလုံးအဆင်ပြေပြီး project owner(s) က သင့်ပြောင်းလဲမှုတွေကို ပရောဂျက်ထဲ merge လုပ်ပေးပါစေ🤞
GitHub ရဲ့ remote branch မှာ commit အသစ်တွေကို သင့်ရဲ့ local working branch နဲ့ update လုပ်ပါ။
GitHub ရဲ့ remote branch နဲ့ သင့် local working branch ကို အားလုံးနောက်ဆုံး commit တွေနဲ့ update လုပ်ပါ:
`git pull`
## Open Source ကို ဘယ်လိုပံ့ပိုးမလဲ
ပထမဦးစွာ GitHub မှာ သင့်စိတ်ဝင်စားပြီး ပြောင်းလဲမှုတစ်ခုလုပ်ချင်တဲ့ repository (သို့မဟုတ် **repo**) တစ်ခုကိုရှာပါ။ အဲဒီ repo ရဲ့အကြောင်းအရာတွေကို သင့်စက်ထဲကို copy လုပ်ချင်ပါလိမ့်မယ်။
ပထမဦးဆုံး GitHub မှာ သင့်စိတ်ဝင်စားတဲ့ repository (သို့မဟုတ် **repo**) တစ်ခုကို ရှာဖွေပြီး ပြောင်းလဲမှုတစ်ခုကို ပံ့ပိုးချင်ပါတယ်။ အဲဒီ repo ရဲ့ အကြောင်းအရာတွေကို သင့်စက်ထဲကို ကူးယူချင်ပါလိမ့်မယ်။
✅ 'Beginner-friendly' repo တွေကို [good-first-issue tag နဲ့ရှာဖွေပါ](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/)။
✅ 'Beginner-friendly' repo တွေကို ရှာဖွေဖို့ နည်းလမ်းက [good-first-issue ဆိုတဲ့ tag နဲ့ ရှာဖွေပါ](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/)။
![Copy a repo locally](../../../../translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.my.png)
![Repo တစ်ခုကို locally ကူးယူခြင်း](../../../../translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.my.png)
Code ကို copy လုပ်ဖို့နည်းလမ်းအများကြီးရှိပါတယ်။ နည်းလမ်းတစ်ခုကတော့ repository ရဲ့အကြောင်းအရာတွေကို HTTPS, SSH, သို့မဟုတ် GitHub CLI (Command Line Interface) ကိုသုံးပြီး "clone" လုပ်တာပါ
Code ကို ကူးယူဖို့ နည်းလမ်းအများကြီးရှိပါတယ်။ နည်းလမ်းတစ်ခုက repository ရဲ့ အကြောင်းအရာတွေကို HTTPS, SSH, သို့မဟုတ် GitHub CLI (Command Line Interface) ကို အသုံးပြုပြီး "clone" လုပ်ခြင်းဖြစ်ပါတယ်
Terminal ကိုဖွင့်ပြီး repository ကိုအောက်ပါအတိုင်း clone လုပ်ပါ:
Terminal ကို ဖွင့်ပြီး repository ကို အောက်ပါအတိုင်း clone လုပ်ပါ:
`git clone https://github.com/ProjectURL`
Project ပေါ်မှာအလုပ်လုပ်ဖို့အတွက် မှန်ကန်တဲ့ folder ကိုရွှေ့ပါ:
Project ပေါ်မှာ အလုပ်လုပ်ဖို့ အမှန်တကယ် folder ကို ပြောင်းပါ:
`cd ProjectURL`
GitHub ရဲ့ embedded code editor / cloud development environment ဖြစ်တဲ့ [Codespaces](https://github.com/features/codespaces) သို့မဟုတ် [GitHub Desktop](https://desktop.github.com/) ကိုသုံးပြီး project အပြည့်အစုံကိုဖွင့်နိုင်ပါတယ်။
GitHub ရဲ့ embedded code editor / cloud development environment ဖြစ်တဲ့ [Codespaces](https://github.com/features/codespaces) သို့မဟုတ် [GitHub Desktop](https://desktop.github.com/) ကို အသုံးပြုပြီးလည်း project တစ်ခုလုံးကို ဖွင့်နိုင်ပါတယ်။
နောက်ဆုံးအနေနဲ့ code ကို zipped folder အနေနဲ့ download လုပ်နိုင်ပါတယ်။
### GitHub အကြောင်း စိတ်ဝင်စားစရာအချက်အချို့
### GitHub အကြောင်း စိတ်ဝင်စားစရာ အချက်အချို့
GitHub မှာ public repository မည်သည့်အရာမဆို star, watch, သို့မဟုတ် "fork" လုပ်နိုင်ပါတယ်။ သင့်ရဲ့ starred repositories တွေကို အပေါ်ညာဘက် drop-down menu မှာတွေ့နိုင်ပါတယ်။ Bookmark လုပ်တာနဲ့တူပေမယ့် code အတွက်ပါ။
GitHub မှာ public repository မည်သည့်အရာကိုမဆို star, watch, သို့မဟုတ် "fork" လုပ်နိုင်ပါတယ်။ သင့် starred repositories တွေကို အပေါ်ညာဘက် drop-down menu မှာ ရှာနိုင်ပါတယ်။ Bookmark လုပ်တာလိုပဲ၊ ဒါပေမယ့် code အတွက်ပါ။
Projects တွေမှာ issue tracker တစ်ခုရှိပါတယ်၊ အများအားဖြင့် GitHub ရဲ့ "Issues" tab မှာရှိပါတယ်၊ project နဲ့ပတ်သက်တဲ့ပြဿနာတွေကိုဆွေးနွေးဖို့နေရာပါ။ Pull Requests tab မှာတော့ ပြုလုပ်ဆဲပြောင်းလဲမှုတွေကိုဆွေးနွေးပြီး review လုပ်ကြပါတယ်။
Projects တွေမှာ issue tracker ရှိပါတယ်၊ အများအားဖြင့် GitHub ရဲ့ "Issues" tab မှာရှိပြီး project နဲ့ပတ်သက်တဲ့ ပြဿနာတွေကို ဆွေးနွေးကြပါတယ်။ Pull Requests tab မှာတော့ လက်ရှိ ပြောင်းလဲမှုတွေကို ဆွေးနွေးပြီး ပြန်လည်သုံးသပ်ကြပါတယ်။
Projects တွေမှာ forum, mailing list, သို့မဟုတ် Slack, Discord, IRC လို chat channel တွေမှာလည်း ဆွေးနွေးမှုတွေရှိနိုင်ပါတယ်။
✅ သင့်ရဲ့ GitHub repo အသစ်ကိုကြည့်ပြီး settings edit လုပ်တာ, repo မှာအချက်အလက်ထည့်တာ, project တစ်ခု (Kanban board လို) ဖန်တီးတာလို အရာတွေကိုစမ်းကြည့်ပါ။ လုပ်နိုင်စရာအများကြီးရှိပါတယ်!
✅ သင့် GitHub repo အသစ်ကို လေ့လာပြီး settings ကို ပြင်ဆင်ခြင်း၊ repo မှာ အချက်အလက်ထည့်ခြင်း၊ project တစ်ခု (ဥပမာ Kanban board) ဖန်တီးခြင်းလို အရာတွေကို စမ်းကြည့်ပါ။ လုပ်လို့ရတဲ့အရာတွေ အများကြီးရှိပါတယ်!
---
## 🚀 စိန်ခေါ်မှု
မိတ်ဆွေတစ်ယောက်နဲ့တွဲဖက်ပြီး တစ်ဦးရဲ့ code ပေါ်မှာအလုပ်လုပ်ပါ။ Project တစ်ခုကိုပူးတွဲဖန်တီးပြီး, code ကို fork လုပ်ပါ, branch တွေဖန်တီးပြီး ပြောင်းလဲမှုတွေကိုပေါငးစည်းပါ။
သူငယ်ချင်းတစ်ဦးနဲ့ တွဲဖက်ပြီး တစ်ဦးရဲ့ code ကို တစ်ဦးက အလုပ်လုပ်ပါ။ ပူးပေါင်းပြီး project တစ်ခု ဖန်တီးပါ၊ code ကို fork လုပ်ပါ၊ branch တွေ ဖန်တီးပါ၊ ပြောင်းလဲမှုတွေကို merge လုပ်ပါ။
## Post-Lecture Quiz
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/4)
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/en/)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
[Open source software ကိုဘယ်လိုပံ့ပိုးမလဲ](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution) ဆိုတာကိုပိုမိုဖတ်ရှုပါ။
[Open source software ကို ဘယ်လိုပံ့ပိုးမလဲ](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution) ဆိုတာကို ပိုမိုဖတ်ရှုပါ။
[Git cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/) ကိုကြည့်ပါ။
[Git cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/) ကိုလည်း ကြည့်ပါ။
လေ့ကျင့်ပါ၊ လေ့ကျင့်ပါ၊ လေ့ကျင့်ပါ။ GitHub မှာ [skills.github.com](https://skills.github.com) မှတဆင့် လေ့လာရေးလမ်းကြောင်းကောင်းများရှိပါတယ်။
လေ့ကျင့်ပါ၊ လေ့ကျင့်ပါ၊ လေ့ကျင့်ပါ။ GitHub မှာ [skills.github.com](https://skills.github.com) မှတဆင့် လေ့လာရေးလမ်းကြောင်းတွေ ရှိပါတယ်:
- [GitHub မှာပထမဆုံးအပတ်](https://skills.github.com/#first-week-on-github)
- [GitHub ပေါ်မှာ ပထမဆုံးအပတ်](https://skills.github.com/#first-week-on-github)
ပိုမိုအဆင့်မြင့်သင်တန်းတွေကိုလည်းတွေ့နိုင်ပါတယ်။
ပိုမိုအဆင့်မြင့်တဲ့ သင်တန်းတွေကိုလည်း ရှာတွေ့နိုင်ပါမယ်။
## လုပ်ငန်းတာဝန်
## လုပ်ဆောင်ရန်
[GitHub မှာပထမဆုံးအပတ် သင်တန်း](https://skills.github.com/#first-week-on-github) ကိုပြီးစီးပါ။
[GitHub ပေါ်မှာ ပထမဆုံးအပတ် သင်တန်း](https://skills.github.com/#first-week-on-github) ကို ပြီးမြောက်ပါ။
---
**ဝက်ဘ်ဆိုက်မှတ်ချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှန်ကန်မှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက်ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို ကျေးဇူးပြု၍ သတိပြုပါ။ မူလဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတည်သော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော နားလည်မှုမှားများ သို့မဟုတ် အဓိပ္ပာယ်မှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,138 +1,130 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e4cd5b1faed4adab5acf720f82798003",
"translation_date": "2025-08-27T22:50:36+00:00",
"original_hash": "7598502c4dd1630c72b19ae6bd2523a4",
"translation_date": "2025-08-28T18:52:19+00:00",
"source_file": "1-getting-started-lessons/3-accessibility/README.md",
"language_code": "my"
}
-->
# ဝက်ဘ်စာမျက်နှာများကို လွယ်ကူစွာ အသုံးပြုနိုင်အောင် ဖန်တီးခြင်း
# ဝက်ဘ်ဆိုဒ်များကို လွယ်ကူစွာ အသုံးပြုနိုင်အောင် ဖန်တီးခြင်း
![Accessibility အကြောင်းအားလုံး](../../../../translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.my.png)
> [Tomomi Imura](https://twitter.com/girlie_mac) မှ Sketchnote
![အဆင်ပြေမှုအကြောင်း အားလုံး](../../../../translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.my.png)
> [Tomomi Imura](https://twitter.com/girlie_mac) Sketchnote
## သင်ခန်းစာမတိုင်မီ မေးခွန်း
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/5)
## သင်ခန်းစာမတိုင်မီ စစ်ဆေးမှု
[သင်ခန်းစာမတိုင်မီ စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/)
> ဝက်ဘ်၏ အားသာချက်မှာ ၎င်း၏ အထွေထွေသုံးနိုင်မှုတွင် ရှိသည်။ မသန်စွမ်းမှုရှိသူများပါဝင်နိုင်မှုသည် အရေးပါသော အချက်တစ်ခုဖြစ်သည်။
> "ဝက်ဘ်၏ အားသာချက်မှာ ၎င်း၏ စွမ်းဆောင်နိုင်မှုအပေါ် မူတည်သည်။ မည်သည့် မသန်မစွမ်းသူမဆို ဝင်ရောက်နိုင်စေရန် အရေးကြီးသည်။"
>
> \- Sir Timothy Berners-Lee, W3C Director နှင့် World Wide Web ကို တီထွင်သူ
> \- Sir Timothy Berners-Lee, W3C ဒါရိုက်တာနှင့် World Wide Web ၏ တီထွင်ရှင်
ဤအဆိုသည် ဝက်ဘ်ဆိုက်များကို လွယ်ကူစွာ အသုံးပြုနိုင်အောင် ဖန်တီးရန်၏ အရေးပါမှုကို အလွန်ကောင်းစွာ ဖော်ပြထားသည်။ လူတိုင်း မဝင်ရောက်နိုင်သော အက်ပလီကေးရှင်းသည် အလိုအလျောက် ဖယ်ရှားထားသော အက်ပလီကေးရှင်းဖြစ်သည်။ ဝက်ဘ်ဒီဗယ်လော့ပါများအနေဖြင့် ကျွန်ုပ်တို့သည် အမြဲတမ်း Accessibility ကို စဉ်းစားထားသင့်သည်။ စတင်ချိန်မှစ၍ ဤအချက်ကို အာရုံစိုက်ခြင်းဖြင့် သင်ဖန်တီးသော စာမျက်နှာများကို လူတိုင်း ဝင်ရောက်နိုင်စေရန် အကောင်းဆုံးလမ်းကြောင်းပေါ်ရောက်ရှိနေမည်ဖြစ်သည်။ ဤသင်ခန်းစာတွင် သင်၏ ဝက်ဘ်အရင်းအမြစ်များကို လွယ်ကူစွာ အသုံးပြုနိုင်စေရန် ကူညီနိုင်သော ကိရိယာများနှင့် Accessibility ကို စဉ်းစားပြီး ဖန်တီးနည်းကို သင်ယူမည်ဖြစ်သည်။
ဤအဆိုအရ ဝက်ဘ်ဆိုဒ်များကို လွယ်ကူစွာ အသုံးပြုနိုင်အောင် ဖန်တီးရမည့် အရေးကြီးမှုကို အလင်းပေးထားသည်။ မည်သူမဆို ဝင်ရောက်အသုံးပြုနိုင်မည့် အက်ပ်ပလီကေးရှင်းတစ်ခု မရှိပါက ၎င်းသည် အခြားသူများကို ခွဲခြားထားခြင်းဖြစ်သည်။ ဝက်ဘ်ဒီဗလော့ပါများအနေဖြင့် အမြဲတမ်း အဆင်ပြေမှုကို စဉ်းစားထားရမည်။ အစမှစ၍ ဤအချက်ကို အလေးထားပါက သင်ဖန်တီးသည့် စာမျက်နှာများအားလုံးကို မည်သူမဆို ဝင်ရောက်နိုင်စေရန် အခြေခံအဆင့်ကို ရောက်ရှိနိုင်မည်ဖြစ်သည်။ ဤသင်ခန်းစာတွင် သင်၏ ဝက်ဘ်အရင်းအမြစ်များကို လွယ်ကူစွာ အသုံးပြုနိုင်စေရန် ကူညီမည့် ကိရိယာများနှင့် အဆင်ပြေမှုကို စဉ်းစားပြီး ဖန်တီးနည်းကို သင်ယူမည်ဖြစ်သည်။
> သင်ဤသင်ခန်းစာကို [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon) တွင် လေ့လာနိုင်သည်။
> ဤသင်ခန်းစာကို [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon) တွင် လေ့လာနိုင်ပါသည်။
## အသုံးပြုရန် ကိရိယာများ
### Screen readers
### မျက်နှာပြင်ဖတ်စက်များ
လူသိများသော Accessibility ကိရိယာများထဲမှ Screen readers သည် အရေးပါသော ကိရိယာတစ်ခုဖြစ်သည်။
အဆင်ပြေမှုအတွက် အထင်ရှားဆုံး ကိရိယာများထဲမှ တစ်ခုမှာ မျက်နှာပြင်ဖတ်စက်များဖြစ်သည်။
[Screen readers](https://en.wikipedia.org/wiki/Screen_reader) သည် မျက်စိမမြင်သူများအတွက် အသုံးပြုသော client များဖြစ်သည်။ ဘရောက်ဇာမှ သင်မျှဝေလိုသော အချက်အလက်ကို သေချာစွာ ဖော်ပြရန် အချိန်ကုန်သလို Screen reader မှလည်း အချက်အလက်ကို သေချာစွာ ဖော်ပြရန် အချိန်ကုန်ရမည်။
[မျက်နှာပြင်ဖတ်စက်များ](https://en.wikipedia.org/wiki/Screen_reader) သည် မျက်မမြင်သူများအတွက် အများဆုံး အသုံးပြုသော ကိရိယာများဖြစ်သည်။ ဘရောက်ဇာမှတဆင့် သင်ပေးလိုသည့် အချက်အလက်များကို ပေးနိုင်ရန် ကြိုးစားသလို မျက်နှာပြင်ဖတ်စက်မှလည်း ထိုအချက်အလက်များကို မှန်ကန်စွာ ဖော်ပြနိုင်ရန် သေချာရမည်။
အခြေခံအားဖြင့် Screen reader သည် စာမျက်နှာကို အပေါ်မှ အောက်သို့ အသံထွက်ဖတ်ပေးမည်။ သင်၏ စာမျက်နှာသည် စာသားသာပါရှိပါက reader သည် ဘရောက်ဇာနှင့် ဆင်တူသော ပုံစံဖြင့် အချက်အလက်ကို ဖော်ပြမည်။ သို့သော် ဝက်ဘ်စာမျက်နှာများသည် စာသားသာမပါရှိဘဲ လင့်ခ်များ၊ ဓာတ်ပုံများ၊ အရောင်များနှင့် အခြားသော ရှုထောင့်ဆိုင်ရာ အစိတ်အပိုင်းများပါရှိသည်။ ဤအချက်အလက်များကို Screen reader မှ သေချာစွာ ဖတ်နိုင်စေရန် ဂရုစိုက်ရမည်။
အခြေခံအားဖြင့် မျက်နှာပြင်ဖတ်စက်သည် စာမျက်နှာကို အပေါ်မှ အောက်သို့ အသံထွက်ဖြင့် ဖတ်ပေးမည်။ သင်၏ စာမျက်နှာသည် စာသားသာ ပါရှိပါက ဖတ်စက်သည် ဘရောက်ဇာနှင့် ဆင်တူသော ပုံစံဖြင့် အချက်အလက်များကို ဖော်ပြမည်။ သို့သော် ဝက်ဘ်စာမျက်နှာများသည် စာသားသာမက လင့်ခ်များ၊ ပုံများ၊ အရောင်များနှင့် အခြား ဗီဇွယ်အချက်အလက်များပါဝင်လေ့ရှိသည်။ ထိုအချက်အလက်များကို မျက်နှာပြင်ဖတ်စက်မှ မှန်ကန်စွာ ဖတ်နိုင်ရန် သတိထားရမည်။
ဝက်ဘ်ဒီဗယ်လော့ပါများသည် Screen reader ကို ရင်းနှီးကျွမ်းဝင်ထားသင့်သည်။ အထက်တွင် ဖော်ပြထားသည့်အတိုင်း ၎င်းသည် သင်၏ အသုံးပြုသူများ အသုံးပြုမည့် client ဖြစ်သည်။ ဘရောက်ဇာ၏ လုပ်ဆောင်ပုံကို သင် ရင်းနှီးကျွမ်းဝင်ထားသည့်အတိုင်း Screen reader ၏ လုပ်ဆောင်ပုံကိုလည်း သင်လေ့လာသင့်သည်။ ကံကောင်းစွာဖြင့် Screen readers များသည် အများစုသော Operating systems တွင် built-in ဖြစ်သည်။
ဝက်ဘ်ဒီဗလော့ပါများအနေဖြင့် မျက်နှာပြင်ဖတ်စက်နှင့် ရင်းနှီးဖို့ လိုအပ်သည်။ အထက်တွင် ဖော်ပြထားသည့်အတိုင်း ၎င်းသည် သင်၏ အသုံးပြုသူများ၏ အဓိက ကိရိယာဖြစ်သည်။ ဘရောက်ဇာ၏ လုပ်ဆောင်ပုံကို သင် သိထားသလို မျက်နှာပြင်ဖတ်စက်၏ လုပ်ဆောင်ပုံကိုလည်း သင်သိထားရမည်။ ကံကောင်းစွာဖြင့် မျက်နှာပြင်ဖတ်စက်များသည် များစွာသော အပလီကေးရှင်းစနစ်များတွင် ပါဝင်ပြီးသားဖြစ်သည်။
ဘရောက်ဇာတချို့တွင်လည်း built-in ကိရိယာများနှင့် extension များပါရှိပြီး စာသားကို အသံထွက်ဖတ်ပေးခြင်း သို့မဟုတ် အခြေခံ navigation လုပ်ဆောင်ချက်များကို ပေးနိုင်သည်။ ဥပမာအားဖြင့် [Edge browser tools](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features) များသည် Accessibility အတွက် အရေးပါသော ကိရိယာများဖြစ်သော်လည်း Screen reader စမ်းသပ်မှုကိရိယာများနှင့် မရောထွေးသင့်ပါ။
အချို့သော ဘရောက်ဇာများတွင်လည်း စာသားများကို အသံထွက်ဖတ်ပေးသည့် ကိရိယာများနှင့် အခြေခံ လမ်းညွှန်မှုများပေးနိုင်သည့် လိုက်ဖက်သော ကိရိယာများပါရှိသည်။ ဥပမာအားဖြင့် [Edge ဘရောက်ဇာ၏ အဆင်ပြေမှုအတွက် အထူးကိရိယာများ](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features) တို့ဖြစ်သည်။ သို့သော် ၎င်းတို့သည် မျက်နှာပြင်ဖတ်စက်များနှင့် လုံးဝ မတူပါကြောင်း သတိပြုပါ။
Screen reader နှင့် browser text reader ကို စမ်းသပ်ပါ။ Windows တွင် [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) သည် default အနေဖြင့် ပါရှိပြီး [JAWS](https://webaim.org/articles/jaws/) နှင့် [NVDA](https://www.nvaccess.org/about-nvda/) ကိုလည်း ထည့်သွင်းနိုင်သည်။ macOS နှင့် iOS တွင် [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) သည် default အနေဖြင့် ပါရှိသည်။
မျက်နှာပြင်ဖတ်စက်နှင့် ဘရောက်ဇာစာဖတ်စက်ကို စမ်းသပ်ကြည့်ပါ။ Windows တွင် [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) သည် ပုံမှန်ပါဝင်ပြီးသားဖြစ်ပြီး၊ [JAWS](https://webaim.org/articles/jaws/) နှင့် [NVDA](https://www.nvaccess.org/about-nvda/) ကိုလည်း ထည့်သွင်းနိုင်သည်။ macOS နှင့် iOS တွင် [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) သည် ပုံမှန်ပါဝင်ပြီးသားဖြစ်သည်။
### Zoom
### ပုံကြီးပြုလုပ်ခြင်း (Zoom)
ျက်စိမမြင်သူများအတွက် အသုံးပြုသော အခြားသော ကိရိယာတစ်ခုမှာ Zooming ဖြစ်သည်။
ြင်နိုင်မှုအခက်အခဲရှိသူများအတွက် ပုံကြီးပြုလုပ်ခြင်းသည် အများဆုံး အသုံးပြုသော ကိရိယာတစ်ခုဖြစ်သည်။ အခြေခံပုံစံအနေဖြင့် `Control + plus sign (+)` သို့မဟုတ် မျက်နှာပြင်ရုပ်ထွက်အရွယ်အစားကို လျှော့ချခြင်းဖြင့် စာမျက်နှာအားလုံးကို ကြီးမားစေသည်။ ထို့ကြောင့် [တုံ့ပြန်မှုဒီဇိုင်း](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) ကို အသုံးပြုခြင်းသည် ကြီးမားသော အရွယ်အစားတွင်လည်း သုံးစွဲသူအတွက် အတွေ့အကြုံကောင်းစေရန် အရေးကြီးသည်။
အခြေခံ Zooming သည် `Control + plus sign (+)` သို့မဟုတ် Screen resolution ကို လျှော့ချခြင်းဖြင့် စီမံနိုင်သည်။ ဤ Zooming ပုံစံသည် စာမျက်နှာတစ်ခုလုံးကို ပြောင်းလဲစေသောကြောင့် [Responsive design](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) ကို အသုံးပြုခြင်းသည် Zooming အဆင့်မြင့်များတွင် အသုံးပြုသူအတွေ့အကြုံကောင်းစေရန် အရေးပါသည်။
အခြားပုံစံတစ်ခုမှာ အထူးပရိုဂရမ်များကို အသုံးပြု၍ မျက်နှာပြင်၏ တစ်စိတ်တစ်ပိုင်းကို ကြီးမားစေပြီး ပုံမှန်မျက်မှောက်မှ ကြည့်နေသကဲ့သို့ လှည့်ပတ်ကြည့်နိုင်သည်။ Windows တွင် [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) သည် ပုံမှန်ပါဝင်ပြီးသားဖြစ်ပြီး၊ [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) သည် ပိုမိုစွမ်းဆောင်နိုင်သော အခြားပရိုဂရမ်ဖြစ်သည်။ macOS နှင့် iOS တွင်လည်း [Zoom](https://www.apple.com/accessibility/mac/vision/) သည် ပုံမှန်ပါဝင်ပြီးသားဖြစ်သည်။
အခြားသော Zooming ပုံစံသည် အထူး software ကို အသုံးပြု၍ Screen ၏ တစ်စိတ်တစ်ပိုင်းကို ကြီးမြင့်စေပြီး Pan လုပ်ခြင်းဖြစ်သည်။ Windows တွင် [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) သည် built-in ဖြစ်ပြီး [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) သည် အခြားသော third-party magnification software ဖြစ်သည်။ macOS နှင့် iOS တွင် [Zoom](https://www.apple.com/accessibility/mac/vision/) သည် built-in ဖြစ်သည်။
### အရောင်ဆိုင်ရာ စစ်ဆေးမှု
### Contrast checkers
ဝက်ဘ်ဆိုဒ်များတွင် အသုံးပြုသည့် အရောင်များကို အရောင်ကွဲခြားမှုရှိသူများ သို့မဟုတ် အနည်းအကျဉ်းအရောင်များကို မြင်ရခက်သူများအတွက် သင့်တော်စေရန် သေချာစွာ ရွေးချယ်ရမည်။
ဝက်ဘ်ဆိုက်များတွင် အသုံးပြုသော အရောင်များကို အရောင်မမြင်နိုင်သူများ သို့မဟုတ် အနည်းဆုံး contrast အရောင်များကို မြင်ရခက်သူများအတွက် သေချာစွာ ရွေးချယ်ရမည်။
✅ သင်နှစ်သက်သော ဝက်ဘ်ဆိုက်တစ်ခုကို browser extension တစ်ခုဖြစ်သော [WCAG's color checker](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon) ဖြင့် စမ်းသပ်ပါ။ သင်ဘာတွေ သင်ယူရမလဲ?
✅ သင်နှစ်သက်သော ဝက်ဘ်ဆိုဒ်တစ်ခုကို အရောင်အသုံးပြုမှုအတွက် စမ်းသပ်ကြည့်ပါ။ [WCAG အရောင်စစ်ဆေးကိရိယာ](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon) ကဲ့သို့သော ဘရောက်ဇာအထူးကိရိယာများကို အသုံးပြုပါ။ သင်ဘာတွေ သင်ယူရမလဲ?
### Lighthouse
သင်၏ ဘရောက်ဇာ၏ developer tool area တွင် Lighthouse tool ကို ရှာနိုင်သည်။ ဤ tool သည် ဝက်ဘ်ဆိုက်၏ Accessibility (အခြားသော analysis များနှင့်အတူ) ကို ပထမဆုံးအမြင်ရရန် အရေးပါသည်။ Lighthouse ကို အပြည့်အဝ အားထားသင့်မည်မဟုတ်သော်လည်း 100% score သည် အခြေခံအနေဖြင့် အထောက်အကူဖြစ်စေသည်။
သင်၏ ဘရောက်ဇာ၏ developer tool အပိုင်းတွင် Lighthouse tool ကို တွေ့နိုင်သည်။ ဤကိရိယာသည် ဝက်ဘ်ဆိုဒ်၏ အဆင်ပြေမှု (နှင့် အခြားသော စစ်ဆေးမှုများ) အပေါ် အခြေခံအချက်အလက်များကို ပေးသည်။ Lighthouse ကိုသာ အားထားမရသော်လည်း ၁၀၀% အဆင့်သည် အခြေခံအချက်အလက်အနေဖြင့် အထောက်အကူဖြစ်သည်။
✅ သင်၏ ဘရောက်ဇာ၏ developer tool panel တွင် Lighthouse ကို ရှာပြီး site တစ်ခုကို analysis လုပ်ပါ။ သင်ဘာတွေ ရှာဖွေတွေ့ရှိရမလဲ?
✅ သင်၏ ဘရောက်ဇာ၏ developer tool panel တွင် Lighthouse ကို ရှာဖွေပြီး မည်သည့်ဆိုဒ်မဆို စစ်ဆေးပါ။ သင်ဘာတွေ တွေ့ရှိရမလဲ?
## Accessibility အတွက် ဒီဇိုင်းဆွဲခြင်း
## အဆင်ပြေမှုအတွက် ဒီဇိုင်းဆွဲခြင်း
Accessibility သည် အကြီးမားသော ခေါင်းစဉ်တစ်ခုဖြစ်သည်။ သင်ကို ကူညီရန် အရင်းအမြစ်များစွာ ရှိနိုင်သည်။
အဆင်ပြေမှုသည် အကြီးမားသော ခေါင်းစဉ်တစ်ခုဖြစ်သည်။ သင်အား ကူညီရန် အရင်းအမြစ်များစွာ ရှိသည်။
- [Accessible U - University of Minnesota](https://accessibility.umn.edu/your-role/web-developers)
ကျွန်ုပ်တို့သည် ဝက်ဘ်ဆိုက်များကို လွယ်ကူစွာ အသုံးပြုနိုင်အောင် ဖန်တီးခြင်း၏ အချက်အားလုံးကို မဖော်ပြနိုင်သော်လည်း အောက်တွင် သင် အကောင်အထည်ဖော်လိုသော အဓိကအချက်များကို ဖော်ပြထားသည်။ စတင်ချိန်မှ စာမျက်နှာကို Accessibility အတွက် ဒီဇိုင်းဆွဲခြင်းသည် ရှိပြီးသား စာမျက်နှာကို ပြန်လည်ပြင်ဆင်ခြင်းထက် **အမြဲတမ်း** လွယ်ကူသည်။
ကျွန်ုပ်တို့သည် အဆင်ပြေမှုရှိသော ဆိုဒ်များ ဖန်တီးရန် အချက်အလက်အားလုံးကို မဖော်ပြနိုင်သော်လည်း အောက်တွင် ဖော်ပြထားသော အခြေခံအချက်များကို သင်အကောင်အထည်ဖော်လိုက်ပါက အဆင်ပြေမှုရှိသော စာမျက်နှာတစ်ခုကို အစမှစ၍ ဖန်တီးနိုင်မည်ဖြစ်သည်။
## ကောင်းမွန်သော Display အခြေခံသဘောတရားများ
## ကောင်းမွန်သော ပြသမှုအခြေခံချက်များ
### Color safe palettes
### အရောင်လုံခြုံသော ပလက်ဖောင်းများ
လူများသည် ကမ္ဘာကို မတူညီသောနည်းလမ်းများဖြင့် မြင်ကြသည်။ ၎င်းတွင် အရောင်များပါဝင်သည်။ သင်၏ site အတွက် အရောင်စနစ်ကို ရွေးချယ်သောအခါ ၎င်းသည် လူတိုင်းအတွက် အသုံးပြုနိုင်စေရန် သေချာစွာ ရွေးချယ်ရမည်။ [Color Safe](http://colorsafe.co/) သည် အရောင် palettes များကို ဖန်တီးရန် ကောင်းမွန်သော tool တစ်ခုဖြစ်သည်။
လူတိုင်းသည် ကမ္ဘာကို မတူညီသော နည်းလမ်းများဖြင့် မြင်ကြသည်။ ၎င်းတွင် အရောင်များပါဝင်သည်။ သင်၏ဆိုဒ်အတွက် အရောင်စနစ်ကို ရွေးချယ်ရာတွင် လူတိုင်းအတွက် သင့်တော်စေရန် သေချာရမည်။ [Color Safe](http://colorsafe.co/) သည် အရောင်ပလက်ဖောင်းများ ဖန်တီးရန် ကောင်းမွန်သော ကိရိယာတစ်ခုဖြစ်သည်။
✅ အရောင်အသုံးပြုမှုအတွက် အလွန်ပြဿနာများစွာရှိသော ဝက်ဘ်ဆိုက်တစ်ခုကို ရှာဖွေပါ။ အဘယ်ကြောင့်?
✅ အရောင်အသုံးပြုမှုအတွက် အခက်အခဲဖြစ်စေသော ဝက်ဘ်ဆိုဒ်တစ်ခုကို ရှာဖွေပါ။ အဘယ်ကြောင့်?
### မှန်ကန်သော HTML ကို အသုံးပြုပါ
CSS နှင့် JavaScript ကို အသုံးပြု၍ element မည်သည့်အမျိုးအစားကိုမဆို control အမျိုးအစားတစ်ခုလို ပြောင်းလဲနိုင်သည်။ `<span>` ကို `<button>` ဖန်တီးရန် အသုံးပြုနိုင်ပြီး `<b>` ကို hyperlink ဖြစ်စေရန် အသုံးပြုနိုင်သည်။ ဤနည်းလမ်းသည် style လုပ်ရန် လွယ်ကူသည်ဟု ယူဆနိုင်သော်လည်း Screen reader အတွက် ဘာမှ မဖော်ပြနိုင်ပါ။ စာမျက်နှာတွင် control များ ဖန်တီးသောအခါ သင့် HTML ကို မှန်ကန်စွာ အသုံးပြုပါ။ hyperlink တစ်ခုလိုလိုချင်ပါက `<a>` ကို အသုံးပြုပါ။ HTML ကို မှန်ကန်စွာ အသုံးပြုခြင်းကို Semantic HTML ကို အသုံးပြုခြင်းဟု ခေါ်သည်။
CSS နှင့် JavaScript ကို အသုံးပြု၍ မည်သည့် element ကိုမဆို မည်သည့် control အဖြစ်မဆို ပြောင်းလဲနိုင်သည်။ `<span>` ကို `<button>` အဖြစ် သို့မဟုတ် `<b>` ကို hyperlink အဖြစ် ပြောင်းနိုင်သည်။ သို့သော် ၎င်းသည် မျက်နှာပြင်ဖတ်စက်အတွက် အချက်အလက်မပေးနိုင်ပါ။ စာမျက်နှာတွင် control များ ဖန်တီးရာတွင် သင့်တော်သော HTML ကို အသုံးပြုပါ။ Hyperlink တစ်ခုလိုအပ်ပါက `<a>` ကို အသုံးပြုပါ။ မှန်ကန်သော HTML ကို အသုံးပြုခြင်းကို Semantic HTML အသုံးပြုခြင်းဟု ခေါ်သည်။
ဝက်ဘ်ဆိုက်တစ်ခုသို့ သွားပြီး designer များနှင့် developer များသည် HTML ကို မှန်ကန်စွာ အသုံးပြုထားမထား စစ်ဆေးပါ။ သင့် browser တွင် 'View Page Source' ကို ရွေးချယ်ပြီး underlying code ကို ကြည့်ပါ။
မည်သည့် ဝက်ဘ်ဆိုဒ်မဆို သွားကြည့်ပြီး ဒီဇိုင်နာများနှင့် ဒီဗလော့ပါများသည် HTML ကို မှန်ကန်စွာ အသုံးပြုထားကြောင်း စစ်ဆေးပါ။ Button တစ်ခုသည် Link ဖြစ်သင့်သည့် နေရာကို ရှာဖွေပါ။ အကြံပြုချက် - ဘရောက်ဇာတွင် 'View Page Source' ကို ရွေးချယ်ပြီး အောက်ခံကုဒ်ကို ကြည့်ပါ။
### Heading hierarchy ကို ဖော်ပြရန် ဖော်ပြချက်ကောင်းများ ဖန်တီးပါ
### ဖော်ပြချက်ပါရှိသော ခေါင်းစဉ်အဆင့်စဉ် ဖန်တီးပါ
Screen reader အသုံးပြုသူများသည် [heading များကို အလွန်အရေးပါသော](https://webaim.org/projects/screenreadersurvey8/#finding) အချက်အလက်များ ရှာဖွေရန်နှင့် စာမျက်နှာတစ်ခုလုံးကို navigation လုပ်ရန် အားကိုးကြသည်။ heading content ကို ဖော်ပြချက်ကောင်းများရေးသားခြင်းနှင့် semantic heading tags များကို အသုံးပြုခြင်းသည် Screen reader အသုံးပြုသူများအတွက် လွယ်ကူစွာ navigation လုပ်နိုင်သော site တစ်ခု ဖန်တီးရန် အရေးပါသည်။
မျက်နှာပြင်ဖတ်စက်အသုံးပြုသူများသည် [ခေါင်းစဉ်များကို အားထား](https://webaim.org/projects/screenreadersurvey8/#finding) ပြီး အချက်အလက်များကို ရှာဖွေကာ စာမျက်နှာတစ်ခုတစ်လျှောက် လမ်းညွှန်ကြသည်။ ဖော်ပြချက်ပါရှိသော ခေါင်းစဉ်အကြောင်းအရာရေးသားခြင်းနှင့် semantic heading tags များကို အသုံးပြုခြင်းသည် မျက်နှာပြင်ဖတ်စက်အသုံးပြုသူများအတွက် လွယ်ကူစွာ လမ်းညွှန်နိုင်သော ဆိုဒ်တစ်ခု ဖန်တီးရန် အရေးကြီးသည်။
### Visual clues ကောင်းများကို အသုံးပြုပါ
### ကောင်းမွန်သော ဗီဇွယ်အချက်အလက်များကို အသုံးပြုပါ
CSS သည် စာမျက်နှာပေါ်ရှိ element မည်သည့်အမျိုးအစားကိုမဆို ၎င်း၏ ရုပ်ပုံကို အပြည့်အဝ ထိန်းချုပ်နိုင်သည်။ သင် outline မပါသော text box များ သို့မဟုတ် underline မပါသော hyperlink များ ဖန်တီးနိုင်သည်။ သို့သော် ဤ clues များကို ဖယ်ရှားခြင်းသည် ၎င်းတို့ကို အားကိုးရသောသူများအတွက် control အမျိုးအစားကို မှတ်မိရန် ပိုမိုခက်ခဲစေသည်။
CSS သည် စာမျက်နှာတွင် မည်သည့် element ကိုမဆို အပြည့်အဝ ထိန်းချုပ်နိုင်သည်။ သို့သော် ဤအချက်အလက်များကို ဖယ်ရှားခြင်းသည် ၎င်းတို့ကို အားထားရသောသူများအတွက် အခက်အခဲဖြစ်စေနိုင်သည်။
## Link text ၏ အရေးပါမှု
## လင့်ခ်စာသား၏ အရေးကြီးမှု
Hyperlink များသည် ဝက်ဘ်ကို navigation လုပ်ရန် အဓိကဖြစ်သည်။ ထို့ကြောင့် Screen reader သည် link များကို သေချာစွာ ဖတ်နိုင်စေရန် သေချာစွာ ဖန်တီးရမည်။
Hyperlink များသည် ဝက်ဘ်ကို လမ်းညွှန်ရန် အဓိကဖြစ်သည်။ ထို့ကြောင့် မျက်နှာပြင်ဖတ်စက်မှ လင့်ခ်များကို မှန်ကန်စွာ ဖတ်နိုင်စေရန် သေချာရမည်။
### Screen readers နှင့် links
### မျက်နှာပြင်ဖတ်စက်များနှင့် လင့်ခ်များ
Screen reader များသည် link text ကို စာမျက်နှာပေါ်ရှိ အခြားသော စာသားများကို ဖတ်သည့်ပုံစံအတိုင်း ဖတ်သည်။ ဤအခြေအနေကို သင်မျှော်လင့်ထားသည့်အတိုင်း အောက်တွင် ဖော်ပြထားသော text သည် လုံးဝလက်ခံနိုင်သည်ဟု ခံစားရနိုင်သည်။
မျက်နှာပြင်ဖတ်စက်များသည် စာမျက်နှာတွင်ရှိသည့် အခြားစာသားများကို ဖတ်သကဲ့သို့ လင့်ခ်စာသားကိုလည်း ဖတ်သည်။ ထို့ကြောင့် အောက်တွင် ဖော်ပြထားသည့်စာသားသည် သင့်တော်သည်ဟု ခံစားရနိုင်သည်။
> The little penguin, sometimes known as the fairy penguin, is the smallest penguin in the world. [Click here](https://en.wikipedia.org/wiki/Little_penguin) for more information.
> The little penguin, sometimes known as the fairy penguin, is the smallest penguin in the world. Visit https://en.wikipedia.org/wiki/Little_penguin for more information.
> **NOTE** သင်ဖတ်မည့်အတိုင်း သင် **ဘယ်တော့မှ** အထက်ဖော်ပြထားသောပုံစံဖြင့် link မဖန်တီးသင့်ပါ။
> **NOTE** သင်ဖတ်မည့်အတိုင်း **မည်သည့်အခါမှ** အထက်ဖော်ပြထားသည့်ပုံစံဖြင့် လင့်ခ်များ မဖန်တီးသင့်ပါ။
Screen reader များသည် browser များနှင့် မတူသော interface ဖြစ်ပြီး feature များကွဲပြားသည်ကို သတိပြုပါ။
မျက်နှာပြင်ဖတ်စက်များသည် ဘရောက်ဇာများနှင့် မတူသော အင်တာဖေ့စ်ဖြစ်ကြောင်း သတိပြုပါ။
### URL ကို အသုံးပြုခြင်း၏ ပြဿနာ
Screen reader များသည် text ကို ဖတ်သည်။ URL တစ်ခု text တွင် ပါရှိပါက Screen reader သည် URL ကို ဖတ်မည်။ အများအားဖြင့် URL သည် အဓိကအချက်အလက်ကို မပေးနိုင်ဘဲ အဆင်မပြေသော အသံထွက်ဖြစ်နိုင်သည်။ သင်၏ ဖုန်းသည် URL ပါရှိသော text message ကို အသံထွက်ဖတ်ပေးသောအခါ ဤအတွေ့အကြုံကို ရရှိဖူးနိုင်သည်။
မျက်နှာပြင်ဖတ်စက်များသည် စာသားကို ဖတ်သည်။ URL တစ်ခုသည် စာသားတွင် ပါရှိပါက မျက်နှာပြင်ဖတ်စက်သည် URL ကို ဖတ်မည်။ URL သည် အဓိပ္ပာယ်ရှိသော အချက်အလက်ကို မပေးနိုင်သည့်အပြင် အနားကပ်ဖတ်ခြင်းသည် စိတ်အနှောင့်အယှက်ဖြစ်စေနိုင်သည်။
### "click here" ကို အသုံးပြုခြင်း၏ ပြဿနာ
Screen reader များသည် စာမျက်နှာပေါ်ရှိ hyperlink များကိုသာ ဖတ်နိုင်သည်။ sighted person တစ်ဦးသည် စာမျက်နှာကို link များအတွက် scan လုပ်သည့်ပုံစံအတိုင်းဖြစ်သည်။ link text အားလုံး "click here" ဖြစ်ပါက အသုံးပြုသူသည် "click here, click here, click here, click here, click here, ..." ဟုသာ ကြားရမည်။ link များအားလုံးသည် အတူတူဖြစ်သွားပြီး မည်သည့် link ကိုမဆို ခွဲခြားနိုင်မည်မဟုတ်တော့ပါ။
### Link text ကောင်းများ
Link text ကောင်းများသည် link ၏ အခြားဘက်တွင် ရှိသော အချက်အလက်ကို အတိုချုံးဖော်ပြသည်။ အထက်ဖော်ပြထားသောตัวอย่างတွင် little penguins အကြောင်း Wikipedia စာမျက်နှာကို ဖော်ပြထားသည်။ *little penguins* ဟူသော phrase သည် link text အတွက် အကောင်းဆုံးဖြစ်ပြီး သုံးစွဲသူသည် link ကို click လုပ်ပါက little penguins အကြောင်းကို သင်ယူနိုင်မည်ဟု သေချာစေသည်။
> The [little penguin](https://en.wikipedia.org/wiki/Little_penguin), sometimes known as the fairy penguin, is the smallest penguin in the world.
မျက်နှာပြင်ဖတ်စက်များသည် စာမျက်နှာတစ်ခုတွင် လင့်ခ်များကိုသာ ဖတ်နိုင်သည်။ "click here" သာလင့်ခ်စာသားအဖြစ် အသုံးပြုပါက အသုံးပြုသူသည် "click here, click here, click here..." သာ ကြားရမည်ဖြစ်သည်။ လင့်ခ်များအားလုံးသည် မည်သည့်အချက်အလက်မှ မပေးနိုင်တော့ပေ။
✅ ဝက်ဘ်ကို မိနစ်အနည်းငယ် surf လုပ်ပြီး obscure linking strategies ကို အသုံးပြုထားသော စာမျက်နှာများကို ရှာပါ။ ၎င်းတို့ကို link ကောင်းများ အသုံးပြုထားသော site များနှင့် နှိုင်းယှဉ်ပါ။ သင်ဘာတွေ သင်ယူရမလဲ?
### ကောင်းမွန်သော လင့်ခ်စာသား
#### Search engine မှတ်ချက်များ
ကောင်းမွန်သော လင့်ခ်စာသားသည် လင့်ခ်၏ အခြားဖက်တွင် ရှိမည့်အကြောင်းအရာကို အတိုချုံးဖော်ပြသည်။
သင့် site ကို လူတိုင်း အသုံးပြုနိုင်စေရန် သေချာစေရန် သင်လုပ်ဆောင်သောအရာများသည် Search engine များကိုလည်း သင့် site ကို navigation လုပ်ရန် ကူညီမည်ဖြစ်သည်။ Search engine များသည် link text ကို အသုံးပြု၍ စာမျက်နှာများ၏ ခေါင်းစဉ်များကို သင်
အစိုးရများစွာတွင် ဝင်ရောက်နိုင်မှုအပေါ် သက်ဆိုင်ရာ ဥပဒေများရှိသည်။ သင်နိုင်ငံ၏ ဝင်ရောက်နိုင်မှုဆိုင်ရာ ဥပဒေများကို လေ့လာပါ။ ဘာတွေကို ဖုံးအုပ်ထားပြီး ဘာတွေကို မဖုံးအုပ်ထားဘူးလဲ။ ဥပမာအားဖြင့် [ဒီအစိုးရဝက်ဘ်ဆိုဒ်](https://accessibility.blog.gov.uk/) ကို ကြည့်ပါ။
> The [little penguin](https://en.wikipedia.org/wiki/Little_penguin), sometimes known as the fairy
အစိုးရအများစုတွင် ဝင်ရောက်နိုင်မှုလိုအပ်ချက်များနှင့်ပတ်သက်သော ဥပဒေများရှိသည်။ သင်နိုင်ငံ၏ ဝင်ရောက်နိုင်မှုဥပဒေများကို လေ့လာပါ။ ဘာတွေကို ဖုံးလွှမ်းထားပြီး ဘာတွေကို မဖုံးလွှမ်းထားဘူးလဲ? ဥပမာတစ်ခုအနေဖြင့် [ဒီအစိုးရဝဘ်ဆိုဒ်](https://accessibility.blog.gov.uk/) ကို ကြည့်ပါ။
## လုပ်ငန်းတာဝန်
[ဝင်ရောက်နိုင်မှုမရှိသော က်ဘ်ဆိုဒ်တစ်ခုကို ခွဲခြမ်းစိတ်ဖြာပါ](assignment.md)
[ဝင်ရောက်နိုင်မှုမရှိသော ဘ်ဆိုဒ်တစ်ခုကို ခွဲခြမ်းစိတ်ဖြာပါ](assignment.md)
အရင်းအမြစ်: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) by Instrument
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့ရှိသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာရှိသောအရင်းအမြစ်အဖြစ် ရှုလေ့ရှိသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှု ဝန်ဆောင်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "fc6aef8ecfdd5b0ad2afa6e6ba52bfde",
"translation_date": "2025-08-27T22:31:44+00:00",
"original_hash": "b95fdd8310ef467305015ece1b0f9411",
"translation_date": "2025-08-28T18:42:33+00:00",
"source_file": "2-js-basics/1-data-types/README.md",
"language_code": "my"
}
@ -13,9 +13,9 @@ CO_OP_TRANSLATOR_METADATA:
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## မိန့်ခွန်းမပြောမီ စမ်းမေးခွန်း
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/7)
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/)
ဒီသင်ခန်းစာမှာ JavaScript အခြေခံများကို လေ့လာပါမယ်။ JavaScript က ဝဘ်ဆိုဒ်မှာ အပြန်အလှန်လုပ်ဆောင်မှုများကို ပေးစွမ်းတဲ့ programming language ဖြစ်ပါတယ်။
ဒီသင်ခန်းစာမှာ JavaScript အခြေခံများကို လေ့လာပါမည်။ JavaScript သည် ဝဘ်ပေါ်တွင် အပြန်အလှန်လုပ်ဆောင်မှုများကို ပေးစွမ်းသော ဘာသာစကားဖြစ်သည်။
> ဒီသင်ခန်းစာကို [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon) မှာ လေ့လာနိုင်ပါတယ်!
@ -23,139 +23,139 @@ CO_OP_TRANSLATOR_METADATA:
[![Data Types in JavaScript](https://img.youtube.com/vi/AWfA95eLdq8/0.jpg)](https://youtube.com/watch?v=AWfA95eLdq8 "Data Types in JavaScript")
> 🎥 အပေါ်ကပုံများကို နှိပ်ပြီး Variables နဲ့ Data Types အကြောင်း ဗီဒီယိုများကို ကြည့်ပါ
> 🎥 အထက်ရှိ ပုံများကို နှိပ်ပြီး Variables နှင့် Data Types အကြောင်း ဗီဒီယိုများကို ကြည့်ပါ
Variables နဲ့ ဒေတာအမျိုးအစားများကို စတင်လေ့လာကြပါစို့!
အရင်ဆုံး Variables နှင့် ဒါတွင် ပါဝင်သော ဒေတာအမျိုးအစားများကို စတင်လေ့လာကြပါစို့!
## Variables
Variables ဆိုတာ သင့်ကုဒ်မှာ တန်ဖိုးများကို သိမ်းဆည်းပြီး ပြောင်းလဲအသုံးပြုနိုင်တဲ့ အရာတွေပါ
Variables သည် သင့်ကုဒ်တွင် တစ်လျှောက်လုံး အသုံးပြုနိုင်ပြီး ပြောင်းလဲနိုင်သော တန်ဖိုးများကို သိမ်းဆည်းပေးသည်
Variable တစ်ခုကို ဖန်တီးပြီး **ကြေညာ**ဖို့အတွက် **[keyword] [name]** ဆိုတဲ့ syntax ကို အသုံးပြုရပါတယ်။ ဒါဟာ အောက်ပါ အပိုင်းနှစ်ခုပါဝင်ပါတယ်။
Variable တစ်ခုကို ဖန်တီးပြီး **ကြေညာ**ခြင်းသည် **[keyword] [name]** ဆိုသော syntax ဖြင့် ရေးသားရမည်။ ၎င်းသည် အောက်ပါ အစိတ်အပိုင်းနှစ်ခုဖြင့် ဖွဲ့စည်းထားသည်-
- **Keyword**. Keywords တွေက `let` သို့မဟုတ် `var` ဖြစ်နိုင်ပါတယ်။
- **Keyword**. Keywords တွင် `let` သို့မဟုတ် `var` ပါဝင်နိုင်သည်။
ES6 မှာ `let` ဆိုတဲ့ keyword ကို မိတ်ဆက်ခဲ့ပြီး variable ကို _block scope_ ပေးပါတယ်။ `let` ကို `var` ထက် အသုံးပြုဖို့ အကြံပြုပါတယ်။ block scopes အကြောင်းကို နောက်ပိုင်းမှာ ပိုမိုအသေးစိတ်လေ့လာပါမယ်။
- **Variable name**. Variable name က သင့်ကိုယ်တိုင်ရွေးချယ်ရတဲ့ နာမည်ပါ
`let` keyword ကို ES6 မှာ မိတ်ဆက်ခဲ့ပြီး variable ကို _block scope_ ဟုခေါ်သော အကျယ်အဝန်းပေးသည်။ `var` ထက် `let` ကို အသုံးပြုရန် အကြံပြုထားသည်။ block scopes အကြောင်းကို နောက်ပိုင်းတွင် ပိုမိုအသေးစိတ်လေ့လာပါမည်။
- **Variable name**. သင့်ကိုယ်တိုင် ရွေးချယ်ထားသော နာမည်ဖြစ်သည်
### Task - Variables နဲ့ လုပ်ဆောင်မှု
### Task - Variables နှင့် လုပ်ဆောင်ခြင်း
1. **Variable ကို ကြေညာပါ**. `let` keyword ကို အသုံးပြုပြီး variable ကို ကြေညာပါ:
1. **Variable ကို ကြေညာပါ**. `let` keyword ကို အသုံးပြု၍ Variable ကို ကြေညာပါ:
```javascript
let myVariable;
```
`myVariable` ကို `let` keyword ကို အသုံးပြုပြီး ကြေညာပြီးပါပြီ။ အခုတော့ တန်ဖိုးမရှိသေးပါဘူး
`myVariable` ကို `let` keyword ဖြင့် ကြေညာပြီးဖြစ်သည်။ ၎င်းတွင် လက်ရှိအချိန်တွင် တန်ဖိုးမရှိသေးပါ
1. **တန်ဖိုးပေးပါ**. `=` operator နဲ့ variable ထဲမှာ တန်ဖိုးကို သိမ်းဆည်းပါ။
1. **တန်ဖိုးထည့်ပါ**. `=` operator ကို အသုံးပြု၍ Variable တွင် တန်ဖိုးကို သိမ်းဆည်းပါ၊ ထို့နောက် မျှော်မှန်းထားသော တန်ဖိုးကို ထည့်ပါ။
```javascript
myVariable = 123;
```
> Note: ဒီသင်ခန်းစာမှာ `=` ကို "assignment operator" အနေနဲ့ အသုံးပြုပါတယ်။ ဒါဟာ variable ကို တန်ဖိုးပေးဖို့အတွက် အသုံးပြုတာဖြစ်ပြီး တန်းတူညီမျှမှုကို မဆိုလိုပါဘူး
> Note: ဒီသင်ခန်းစာမှာ `=` ကို အသုံးပြုခြင်းသည် Variable တွင် တန်ဖိုးကို သတ်မှတ်ရန် အသုံးပြုသော "assignment operator" ဖြစ်သည်။ ၎င်းသည် တန်းတူမှုကို မဆိုလိုပါ
`myVariable` ကို 123 တန်ဖိုးနဲ့ *initialized* လုပ်ပြီးပါပြီ
`myVariable` ကို 123 တန်ဖိုးဖြင့် *initialized* လုပ်ပြီးဖြစ်သည်
1. **Refactor**. သင့်ကုဒ်ကို အောက်ပါ statement နဲ့ အစားထိုးပါ။
1. **Refactor**. သင့်ကုဒ်ကို အောက်ပါ statement ဖြင့် အစားထိုးပါ။
```javascript
let myVariable = 123;
```
အထက်ပါကုဒ်ဟာ _explicit initialization_ လို့ခေါ်ပြီး variable ကို ကြေညာပြီး တန်ဖိုးကို တစ်ချိန်တည်းမှာပဲ ပေးထားတာဖြစ်ပါတယ်။
အထက်ပါသည် _explicit initialization_ ဟုခေါ်သည်။ Variable ကို ကြေညာပြီး တန်ဖိုးကို တစ်ချိန်တည်းတွင် သတ်မှတ်ခြင်းဖြစ်သည်။
1. **Variable တန်ဖိုးကို ပြောင်းပါ**. Variable တန်ဖိုးကို အောက်ပါနည်းလမ်းနဲ့ ပြောင်းပါ:
1. **Variable တန်ဖိုးကို ပြောင်းလဲပါ**. Variable တန်ဖိုးကို အောက်ပါနည်းဖြင့် ပြောင်းလဲပါ:
```javascript
myVariable = 321;
```
Variable ကို ကြေညာပြီးတဲ့နောက်မှာ `=` operator နဲ့ တန်ဖိုးအသစ်ကို သင့်ကုဒ်မှာ အချိန်မရွေး ပြောင်းလဲနိုင်ပါတယ်။
Variable ကို ကြေညာပြီးနောက် သင့်ကုဒ်တွင် တန်ဖိုးကို `=` operator နှင့် တန်ဖိုးအသစ်ဖြင့် အချိန်မရွေး ပြောင်းလဲနိုင်သည်။
✅ စမ်းကြည့်ပါ! သင့် browser မှာ JavaScript ကို ရေးနိုင်ပါတယ်။ Browser window ကို ဖွင့်ပြီး Developer Tools ကို သွားပါ။ Console မှာ prompt တစ်ခုကို တွေ့ပါလိမ့်မယ်။ `let myVariable = 123` လို့ ရိုက်ထည့်ပြီး return ကို နှိပ်ပါ၊ ပြီးရင် `myVariable` ကို ရိုက်ထည့်ပါ။ ဘာဖြစ်သွားလဲ? ဒီ concepts တွေကို နောက်ထပ်သင်ခန်းစာတွေမှာ ပိုမိုလေ့လာပါမယ်။
✅ စမ်းကြည့်ပါ! သင့် browser မှာ JavaScript ကို တိုက်ရိုက်ရေးနိုင်ပါတယ်။ Browser window ကို ဖွင့်ပြီး Developer Tools ကို သွားပါ။ Console တွင် prompt ကို တွေ့ပါမည်။ `let myVariable = 123` ဟု ရိုက်ထည့်ပြီး return ကို နှိပ်ပါ၊ ထို့နောက် `myVariable` ကို ရိုက်ပါ။ ဘာဖြစ်သလဲ? ဒီအကြောင်းကို နောက်ထပ် သင်ခန်းစာများတွင် ပိုမိုလေ့လာပါမည်။
## Constants
Constant ကို ကြေညာပြီး initialize လုပ်ဖို့အတွက် variable နဲ့ တူညီတဲ့ concept တွေကို လိုအပ်ပါတယ်၊ `const` keyword ကို အသုံးပြုရတာကို မျှော်လင့်ရပါတယ်။ Constants တွေကို အများအားဖြင့် အားလုံး uppercase letter နဲ့ ကြေညာပါတယ်။
Constant ကို ကြေညာခြင်းနှင့် initialization လုပ်ခြင်းသည် Variable နှင့် အခြေခံအချက်များ တူသည်။ သို့သော် `const` keyword ကို အသုံးပြုရမည်။ Constants များကို အများအားဖြင့် အကြီးစာလုံးများဖြင့် ကြေညာသည်။
```javascript
const MY_VARIABLE = 123;
```
Constants တွေဟာ variable တွေနဲ့ ဆင်တူပါတယ်၊ ဒါပေမယ့် အောက်ပါ အချက်နှစ်ခုကွာခြားပါတယ်။
Constants သည် Variable များနှင့် ဆင်တူသည်၊ သို့သော် အောက်ပါ အချက်နှစ်ခုကွာခြားသည်-
- **တန်ဖိုးရှိရမယ်**. Constants တွေကို initialize မလုပ်ရင် error ဖြစ်ပေါ်နိုင်ပါတယ်။
- **Reference ကို မပြောင်းလဲနိုင်ပါ**. Constant ကို initialize လုပ်ပြီးတဲ့နောက်မှာ reference ကို ပြောင်းလဲမရပါဘူး၊ error ဖြစ်ပေါ်နိုင်ပါတယ်။ အောက်ပါ ဥပမာနှစ်ခုကို ကြည့်ပါ:
- **ရိုးရှင်းတဲ့တန်ဖိုး**. အောက်ပါအရာကို မလုပ်နိုင်ပါ:
- **တန်ဖိုးရှိရမည်**. Constants များကို initialization မလုပ်ပါက ကုဒ်ကို run လုပ်သောအခါ error ဖြစ်ပေါ်မည်။
- **Reference ကို မပြောင်းလဲနိုင်**. Constant ကို initialization လုပ်ပြီးနောက် Reference ကို ပြောင်းလဲမရပါ၊ ပြောင်းလဲပါက error ဖြစ်ပေါ်မည်။ အောက်ပါ ဥပမာနှစ်ခုကို ကြည့်ပါ-
- **ရိုးရှင်းသော တန်ဖိုး**. အောက်ပါသည် ခွင့်မပြုပါ:
```javascript
const PI = 3;
PI = 4; // not allowed
```
- **Object reference ကို ကာကွယ်ထားပါတယ်**. အောက်ပါအရာကို မလုပ်နိုင်ပါ:
- **Object reference ကို ကာကွယ်ထားသည်**. အောက်ပါသည် ခွင့်မပြုပါ:
```javascript
const obj = { a: 3 };
obj = { b: 5 } // not allowed
```
- **Object value ကို မကာကွယ်ထားပါ**. အောက်ပါအရာကို လုပ်နိုင်ပါတယ်:
- **Object value ကို မကာကွယ်ထားပါ**. အောက်ပါသည် ခွင့်ပြုပါ:
```javascript
const obj = { a: 3 };
obj.a = 5; // allowed
```
အထက်ပါမှာ object ရဲ့ value ကို ပြောင်းလဲထားတာဖြစ်ပြီး reference ကို မပြောင်းလဲထားတာကြောင့် လုပ်နိုင်ပါတယ်။
အထက်ပါသည် Object တန်ဖိုးကို ပြောင်းလဲနေသော်လည်း Reference ကို မပြောင်းလဲသည့်အတွက် ခွင့်ပြုထားသည်။
> Note, `const` ဆိုတာ reference ကို ပြောင်းလဲမှုမှ ကာကွယ်ပေးတာဖြစ်ပါတယ်။ ဒါပေမယ့် value ကို _immutable_ မဟုတ်ပါဘူး၊ အထူးသဖြင့် object လိုမျိုး ရှုပ်ထွေးတဲ့ construct တွေမှာ value ကို ပြောင်းလဲနိုင်ပါတယ်။
> Note, `const` သည် Reference ကို ပြန်လည်သတ်မှတ်ခြင်းမှ ကာကွယ်ပေးသည်။ သို့သော် တန်ဖိုးသည် _immutable_ မဟုတ်သေးပါ၊ အထူးသဖြင့် Object ကဲ့သို့သော ရှုပ်ထွေးသော ဖွဲ့စည်းမှုများတွင် ပြောင်းလဲနိုင်သည်။
## ဒေတာအမျိုးအစားများ
Variables တွေဟာ နံပါတ်တွေ၊ စာသားတွေလိုမျိုး အမျိုးမျိုးသော တန်ဖိုးများကို သိမ်းဆည်းနိုင်ပါတယ်။ ဒီတန်ဖိုးအမျိုးအစားတွေကို **data type** လို့ခေါ်ပါတယ်။ ဒေတာအမျိုးအစားတွေဟာ software development မှာ အရေးကြီးပါတယ်၊ အကြောင်းက developer တွေကို ကုဒ်ရေးနည်းနဲ့ software ရှေ့ဆောင်ပုံကို ဆုံးဖြတ်နိုင်စေပါတယ်။ ထို့အပြင် ဒေတာအမျိုးအစားတချို့မှာ တန်ဖိုးထဲက အချက်အလက်တွေကို ပြောင်းလဲဖို့ သို့မဟုတ် ထုတ်ယူဖို့ အထူးလက္ခဏာတွေ ပါဝင်ပါတယ်။
Variables တွင် နံပါတ်များနှင့် စာသားများကဲ့သို့သော အမျိုးမျိုးသော တန်ဖိုးများကို သိမ်းဆည်းနိုင်သည်။ ဒီအမျိုးမျိုးသော တန်ဖိုးများကို **ဒေတာအမျိုးအစား** ဟုခေါ်သည်။ ဒေတာအမျိုးအစားများသည် ကုဒ်ကို ရေးသားပုံနှင့် software ကို run လုပ်ပုံအပေါ် developer များအတွက် ဆုံးဖြတ်ချက်များကို ကူညီပေးသည်။ ထို့အပြင် ဒေတာအမျိုးအစားတစ်ချို့တွင် တန်ဖိုးအတွင်းရှိ အချက်အလက်များကို ပြောင်းလဲခြင်း သို့မဟုတ် ထုတ်ယူခြင်းအတွက် ထူးခြားသော လုပ်ဆောင်ချက်များပါဝင်သည်။
✅ ဒေတာအမျိုးအစားတွေကို JavaScript data primitives လို့လည်း ခေါ်ပါတယ်၊ ဒါဟာ language မှပေးထားတဲ့ အနိမ့်ဆုံးအဆင့် ဒေတာအမျိုးအစားတွေဖြစ်ပါတယ်။ Primitive data types ၇ မျိုးရှိပါတယ်: string, number, bigint, boolean, undefined, null, symbol. ဒီ primitives တစ်ခုချင်းစီက ဘာကို ကိုယ်စားပြုနိုင်မလဲဆိုတာ စဉ်းစားကြည့်ပါ။ `zebra` ဆိုတာဘာလဲ? `0` ကော? `true` ကော?
✅ ဒေတာအမျိုးအစားများကို JavaScript data primitives ဟုလည်း ခေါ်ကြသည်၊ ဘာသာစကားမှ ပေးထားသော အနိမ့်ဆုံးအဆင့် ဒေတာအမျိုးအစားများဖြစ်သည်။ Primitive data types ၇ မျိုးရှိသည်- string, number, bigint, boolean, undefined, null နှင့် symbol။ ဒီ primitives တစ်ခုချင်းစီသည် ဘာကို ကိုယ်စားပြုနိုင်မလဲဆိုတာကို စဉ်းစားကြည့်ပါ။ `zebra` ဆိုတာဘာလဲ? `0` ကော? `true` ကော?
### Numbers
အရင်ပိုင်းက `myVariable` ရဲ့ value ဟာ number data type ဖြစ်ပါတယ်။
အရင်ပိုင်းကဏ္ဍတွင် `myVariable` ၏ တန်ဖိုးသည် number data type ဖြစ်သည်။
`let myVariable = 123;`
Variables တွေဟာ decimal နဲ့ negative numbers အပါအဝင် နံပါတ်အမျိုးမျိုးကို သိမ်းဆည်းနိုင်ပါတယ်။ Numbers တွေကို arithmetic operators တွေနဲ့လည်း အသုံးပြုနိုင်ပါတယ်၊ [နောက်ပိုင်းအပိုင်း](../../../../2-js-basics/1-data-types) မှာ လေ့လာပါမယ်။
Variables တွင် decimal သို့မဟုတ် negative numbers အပါအဝင် နံပါတ်အမျိုးမျိုးကို သိမ်းဆည်းနိုင်သည်။ Numbers များကို [နောက်ကဏ္ဍ](../../../../2-js-basics/1-data-types) တွင် ဖော်ပြထားသော arithmetic operators များနှင့်လည်း အသုံးပြုနိုင်သည်။
### Arithmetic Operators
Arithmetic function တွေကို လုပ်ဆောင်ဖို့ operator အမျိုးမျိုးရှိပြီး အချို့ကို အောက်မှာ ဖော်ပြထားပါတယ်:
Arithmetic လုပ်ဆောင်ချက်များကို ပြုလုပ်ရာတွင် အသုံးပြုနိုင်သော operator အမျိုးအစားများစွာရှိပြီး အချို့ကို အောက်တွင် ဖော်ပြထားသည်-
| Symbol | ဖော်ပြချက် | ဥပမာ |
| ------ | ------------------------------------------------------------------------ | -------------------------------- |
| `+` | **Addition**: နံပါတ်နှစ်ခုရဲ့ စုစုပေါင်းကို တွက်ချက်သည် | `1 + 2 //expected answer is 3` |
| `-` | **Subtraction**: နံပါတ်နှစ်ခုရဲ့ ကွာခြားချက်ကို တွက်ချက်သည် | `1 - 2 //expected answer is -1` |
| `*` | **Multiplication**: နံပါတ်နှစ်ခုရဲ့ ထုတ်ကုန်ကို တွက်ချက်သည် | `1 * 2 //expected answer is 2` |
| `/` | **Division**: နံပါတ်နှစ်ခုရဲ့ မျှဝေချက်ကို တွက်ချက်သည် | `1 / 2 //expected answer is 0.5` |
| `+` | **Addition**: နံပါတ်နှစ်ခု စုစုပေါင်းကို တွက်ချက်သည် | `1 + 2 //expected answer is 3` |
| `-` | **Subtraction**: နံပါတ်နှစ်ခု ကွာခြားချက်ကို တွက်ချက်သည် | `1 - 2 //expected answer is -1` |
| `*` | **Multiplication**: နံပါတ်နှစ်ခု၏ ထုတ်လဒ်ကို တွက်ချက်သည် | `1 * 2 //expected answer is 2` |
| `/` | **Division**: နံပါတ်နှစ်ခု မျှဝေချက်ကို တွက်ချက်သည် | `1 / 2 //expected answer is 0.5` |
| `%` | **Remainder**: နံပါတ်နှစ်ခုကို မျှဝေပြီး ကျန်ရှိသော တန်ဖိုးကို တွက်ချက်သည် | `1 % 2 //expected answer is 1` |
✅ စမ်းကြည့်ပါ! Browser console မှာ arithmetic operation တစ်ခုကို စမ်းကြည့်ပါ။ ရလဒ်တွေက သင့်ကို အံ့ဩစေပါသလား?
✅ စမ်းကြည့်ပါ! Browser console တွင် arithmetic operation တစ်ခုကို စမ်းကြည့်ပါ။ ရလဒ်များသည် သင့်ကို အံ့ဩစေပါသလား?
### Strings
Strings ဆိုတာ single quotes သို့မဟုတ် double quotes ကြားမှာ ရှိတဲ့ စာလုံးများဖြစ်ပါတယ်။
Strings သည် single quotes သို့မဟုတ် double quotes အတွင်းရှိ စာလုံးများဖြစ်သည်။
- `'This is a string'`
- `"This is also a string"`
- `let myString = 'This is a string value stored in a variable';`
String ရေးတဲ့အခါ quotes ကို အသုံးပြုဖို့ မမေ့ပါနဲ့၊ မဟုတ်ရင် JavaScript က variable name လို့ ထင်နိုင်ပါတယ်။
String ရေးသားရာတွင် quotes မသုံးပါက JavaScript သည် ၎င်းကို Variable name ဟုယူဆမည်။
### Formatting Strings
Strings တွေဟာ စာသားဖြစ်ပြီး အချိန်အခါတစ်ချို့မှာ format လုပ်ဖို့ လိုအပ်နိုင်ပါတယ်။
Strings သည် စာသားဖြစ်ပြီး အချိန်အခါတစ်ချို့တွင် format လုပ်ရန် လိုအပ်နိုင်သည်။
Strings နှစ်ခု သို့မဟုတ် အများကြီးကို **concatenate** လုပ်ဖို့ `+` operator ကို အသုံးပြုပါ။
Strings နှစ်ခု သို့မဟုတ် အများကြီးကို **concatenate** လုပ်ရန် `+` operator ကို အသုံးပြုပါ။
```javascript
let myString1 = "Hello";
@ -167,9 +167,9 @@ myString1 + ", " + myString2 + "!"; //Hello, World!
```
✅ ဘာကြောင့် JavaScript မှာ `1 + 1 = 2` ဖြစ်ပြီး `'1' + '1' = 11` ဖြစ်တာလဲ? စဉ်းစားကြည့်ပါ။ `'1' + 1` ကော?
✅ ဘာကြောင့် JavaScript မှာ `1 + 1 = 2` ဖြစ်ပြီး `'1' + '1' = 11` ဖြစ်လဲ? စဉ်းစားကြည့်ပါ။ `'1' + 1` ကော?
**Template literals** ဆိုတာ strings ကို format လုပ်ဖို့ နောက်ထပ်နည်းလမ်းတစ်ခုဖြစ်ပြီး quotes အစား backtick ကို အသုံးပြုပါတယ်။ Plain text မဟုတ်တဲ့ အရာအားလုံးကို `${ }` placeholder ထဲမှာ ထည့်ရပါမယ်။ ဒါမှာ string ဖြစ်နိုင်တဲ့ variable တွေပါဝင်ပါတယ်။
**Template literals** သည် strings ကို format လုပ်ရန် အခြားနည်းလမ်းတစ်ခုဖြစ်သည်။ Quotes မသုံးဘဲ backtick ကို အသုံးပြုရမည်။ Plain text မဟုတ်သော အရာအားလုံးကို `${ }` placeholder အတွင်း ထည့်ရမည်။ ၎င်းတွင် string ဖြစ်နိုင်သော Variable များပါဝင်သည်။
```javascript
let myString1 = "Hello";
@ -179,31 +179,31 @@ let myString2 = "World";
`${myString1}, ${myString2}!` //Hello, World!
```
သင့်ရဲ့ formatting ရည်ရွယ်ချက်တွေကို နည်းလမ်းနှစ်ခုလုံးနဲ့ ရနိုင်ပါတယ်၊ ဒါပေမယ့် template literals က spaces နဲ့ line breaks ကို လေးစားပေးပါမယ်။
သင့် formatting ရည်မှန်းချက်များကို နည်းလမ်းနှစ်ခုစလုံးဖြင့် ရရှိနိုင်သော်လည်း Template literals သည် space နှင့် line break များကို လေးစားမည်။
✅ Template literal ကို ဘယ်အချိန်မှာ အသုံးပြုမလဲ၊ plain string ကို ဘယ်အချိန်မှာ အသုံးပြုမလဲ?
✅ Template literal ကို Plain string ထက် ဘယ်အချိန်မှာ အသုံးပြုမလဲ?
### Booleans
Booleans တွေဟာ `true` သို့မဟုတ် `false` ဆိုတဲ့ တန်ဖိုးနှစ်ခုသာ ရှိနိုင်ပါတယ်။ Booleans တွေက အခြေအနေတစ်ခုခုကို ဖြည့်ဆည်းတဲ့အခါ ဘယ်လိုကုဒ်တွေကို run လုပ်မလဲဆိုတာ ဆုံးဖြတ်နိုင်စေပါတယ်။ အများအားဖြင့် [operators](../../../../2-js-basics/1-data-types) တွေက Boolean တန်ဖိုးကို သတ်မှတ်ဖို့ အကူအညီပေးပြီး variable တွေကို initialize လုပ်တာ သို့မဟုတ် value ကို update လုပ်တာတွေကို မကြာခဏ တွေ့ရပါမယ်။
Booleans သည် `true` သို့မဟုတ် `false` တန်ဖိုးနှစ်ခုသာ ရှိနိုင်သည်။ Booleans သည် အခြေအနေတစ်ခုခုကို ဖြည့်ဆည်းသောအခါ ဘယ်လိုကုဒ်များကို run လုပ်မည်ဆိုတာ ဆုံးဖြတ်ရန် ကူညီပေးသည်။ အများအားဖြင့် [operators](../../../../2-js-basics/1-data-types) များသည် Boolean တန်ဖိုးကို သတ်မှတ်ရာတွင် ကူညီပေးပြီး Variable များကို initialization လုပ်ခြင်း သို့မဟုတ် ၎င်းတို့၏ တန်ဖိုးများကို update လုပ်ခြင်းတွင် မကြာခဏ တွေ့ရမည်။
- `let myTrueBool = true`
- `let myFalseBool = false`
✅ Variable တစ်ခုကို boolean `true` အဖြစ် သတ်မှတ်နိုင်ရင် 'truthy' ဖြစ်တယ်လို့ ဆိုနိုင်ပါတယ်။ အံ့ဩစရာက JavaScript မှာ [falsy အဖြစ် သတ်မှတ်ထားတဲ့ value များအပြင် value အားလုံးကို truthy ဖြစ်တယ်](https://developer.mozilla.org/docs/Glossary/Truthy) လို့ သတ်မှတ်ပါတယ်
✅ Variable တစ်ခုသည် boolean `true` ဟု အကဲဖြတ်နိုင်ပါက 'truthy' ဟုဆိုနိုင်သည်။ အံ့ဩစရာကောင်းသည်မှာ JavaScript တွင် [falsy ဟု သတ်မှတ်ထားသော တန်ဖိုးများမှလွဲ၍ တန်ဖိုးအားလုံးသည် truthy ဖြစ်သည်](https://developer.mozilla.org/docs/Glossary/Truthy)။
---
## 🚀 စိန်ခေါ်မှု
JavaScript ဟာ တစ်ခါတစ်လေ ဒေတာအမျိုးအစားတွေကို handle လုပ်တဲ့နည်းလမ်းတွေကြောင့် အံ့ဩစရာများဖြစ်တတ်ပါတယ်။ ဒီ 'gotchas' တွေကို သုတေသနလုပ်ကြည့်ပါ။ ဥပမာ - case sensitivity က အခက်အခဲဖြစ်နိုင်ပါတယ်! Console မှာ ဒီလိုစမ်းကြည့်ပါ: `let age = 1; let Age = 2; age == Age` (ရလဒ် `false` -- ဘာကြောင့်လဲ?) အခြား gotchas တွေကို ရှာဖွေကြည့်ပါ။
JavaScript သည် တစ်ခါတစ်ရံ ဒေတာအမျိုးအစားများကို handle လုပ်ပုံအပေါ် အံ့ဩစရာများကြောင့် နာမည်ကြီးသည်။ ဒီ 'gotchas' များအကြောင်း သုတေသနလုပ်ပါ။ ဥပမာ- case sensitivity သည် အခက်အခဲဖြစ်စေနိုင်သည်! Console တွင် ဒီလို စမ်းကြည့်ပါ- `let age = 1; let Age = 2; age == Age` (ရလဒ် `false` -- ဘာကြောင့်လဲ?) အခြား gotchas များကို ရှာဖွေပါ။
## မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/8)
[Post-lecture quiz](https://ff-quizzes.netlify.app)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
[JavaScript exercises](https://css-tricks.com/snippets/javascript/) စာရင်းကို ကြည့်ပြီး တစ်ခုကို စမ်းကြည့်ပါ။ ဘာတွေ သင်ယူနိုင်ခဲ့လဲ?
[JavaScript exercises များ](https://css-tricks.com/snippets/javascript/) စာရင်းကို ကြည့်ပြီး တစ်ခုကို စမ်းကြည့်ပါ။ သင်ဘာလေ့လာရသလဲ?
## အိမ်စာ
@ -212,4 +212,4 @@ JavaScript ဟာ တစ်ခါတစ်လေ ဒေတာအမျိုး
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှုမှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b4612bbb9ace984f374fcc80e3e035ad",
"translation_date": "2025-08-27T22:28:44+00:00",
"original_hash": "92e136090efc4341b1d51c37924c1802",
"translation_date": "2025-08-28T18:41:24+00:00",
"source_file": "2-js-basics/2-functions-methods/README.md",
"language_code": "my"
}
@ -12,26 +12,26 @@ CO_OP_TRANSLATOR_METADATA:
![JavaScript Basics - Functions](../../../../translated_images/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.my.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## မိန့်ခွန်းမပြောမီ စမ်းမေးခွန်း
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/9)
## မိန့်ခွန်းမပြောမီ Quiz
[Pre-lecture quiz](https://ff-quizzes.netlify.app)
ကိုယ်ရေးသားတဲ့ကုဒ်ကို စဉ်ဆက်မပြတ်ဖတ်ရလွယ်အောင်လုပ်ဖို့ Developer တစ်ဦးအနေနဲ့ အမြဲလိုအပ်ပါတယ်။ ကုဒ်ကိုရေးတာထက် ဖတ်တာပိုများတယ်ဆိုတာ အနည်းငယ်ဆန့်ကျင်ဘက်ဖြစ်ပေမယ့် အမှန်တရားပါ။ **Function** ဆိုတာကတော့ Developer တွေရဲ့ ကုဒ်ကို ထိန်းသိမ်းဖို့အတွက် အရေးကြီးတဲ့ Tools တစ်ခုဖြစ်ပါတယ်။
Code ရေးသားတဲ့အခါမှာ အမြဲတမ်း code ကိုဖတ်ရလွယ်အောင်လုပ်ဖို့လိုအပ်ပါတယ်။ ဒါဟာ အနည်းငယ်ဆန့်ကျင်ဖွယ်ရှိပေမယ့် code ကိုရေးသားတာထက် ဖတ်တာပိုများပါတယ်။ Developer တွေရဲ့ toolbox မှာ code ကို maintain လုပ်ဖို့အတွက် အရေးကြီးတဲ့ tool တစ်ခုက **function** ဖြစ်ပါတယ်။
[![Methods and Functions](https://img.youtube.com/vi/XgKsD6Zwvlc/0.jpg)](https://youtube.com/watch?v=XgKsD6Zwvlc "Methods and Functions")
> 🎥 အထက်ကပုံကိုနှိပ်ပြီး methods နဲ့ functions အကြောင်း ဗီဒီယိုကြည့်ပါ။
> 🎥 အထက်ပါပုံကို click လုပ်ပြီး methods နှင့် functions အကြောင်း video ကြည့်ပါ။
> ဒီသင်ခန်းစာကို [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon) မှာလည်း လေ့လာနိုင်ပါတယ်။
> Microsoft Learn မှာ ဒီသင်ခန်းစာကို [ယူနိုင်ပါတယ်](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon)!
## Functions
Function ဆိုတာက အဓိကအားဖြင့် လိုအပ်တဲ့အချိန်မှာ ပြန်ခေါ်သုံးနိုင်တဲ့ ကုဒ်တစ်ပိုင်းဖြစ်ပါတယ်။ တစ်ခုတည်းသောအလုပ်ကို မကြိမ်ကြိမ်လုပ်ဖို့လိုတဲ့အခါမှာ Function က အလွန်အသုံးဝင်ပါတယ်။ Function ကိုတစ်နေရာတည်းမှာ စုစည်းထားပြီး လိုအပ်တဲ့အချိန်မှာ ခေါ်သုံးနိုင်ပါတယ်။ Function တစ်ခုက Function တစ်ခုကိုပါ ခေါ်သုံးနိုင်ပါတယ်။
Function ဆိုတာ အခြေခံအားဖြင့် လိုအပ်တဲ့အခါမှာ run လုပ်နိုင်တဲ့ code block တစ်ခုဖြစ်ပါတယ်။ ဒီဟာက တစ်ခါထက်မက အလုပ်တစ်ခုကိုလုပ်ဖို့လိုအပ်တဲ့အခါ အထူးသင့်တော်ပါတယ်။ Logic ကိုနေရာတစ်ခုထက်မကမှာ ထပ်တူရေးသားမယ်ဆိုရင် (နောက်ပိုင်းမှာ update လုပ်ဖို့ခက်ခဲနိုင်ပါတယ်) function ကိုတစ်နေရာမှာ centralized လုပ်ပြီး လိုအပ်တဲ့အခါမှာ call လုပ်နိုင်ပါတယ်။ Function တွေကို function အခြား function တွေထဲကနေပါ call လုပ်နိုင်ပါတယ်။
Function ကိုမည်ပေးနိုင်ခြင်းလည်း အရေးကြီးပါတယ်။ Function အမည်က ကုဒ်တစ်ပိုင်းကို အလွယ်တကူ နားလည်နိုင်စေပါတယ်။ ဥပမာ - "Cancel timer" ဆိုတဲ့ Button ကိုနှိပ်လိုက်ရင် Timer ရပ်မယ်ဆိုတာ သိနိုင်ပါတယ်။
Function ကိုနာမည်ပေးနိုင်ခြင်းလည်း အရေးကြီးပါတယ်။ ဒါဟာ အနည်းငယ်အရေးမကြီးသလိုထင်ရပေမယ့် နာမည်က code ရဲ့အပိုင်းတစ်ခုကို documentation လုပ်ဖို့အတွက် အလွယ်တကူနည်းလမ်းပေးပါတယ်။ Button ရဲ့ label တစ်ခုလိုပဲ။ "Cancel timer" ဆိုတဲ့ button ကို click လုပ်ရင် timer ကိုရပ်မယ်ဆိုတာသိနိုင်ပါတယ်။
## Function တစ်ခုကို ဖန်တီးခြင်းနှင့် ခေါ်သုံးခြင်း
## Function တစ်ခုကိုဖန်တီးခြင်းနှင့် call လုပ်ခြင်း
Function ရဲ့ Syntax က အောက်ပါအတိုင်းဖြစ်ပါတယ်-
Function ရဲ့ syntax က အောက်ပါအတိုင်းဖြစ်ပါတယ်-
```javascript
function nameOfFunction() { // function definition
@ -39,7 +39,7 @@ function nameOfFunction() { // function definition
}
```
Greeting ပြသဖို့ Function တစ်ခု ဖန်တီးချင်တယ်ဆိုရင်-
Greeting ပြသဖို့ function တစ်ခုဖန်တီးချင်တယ်ဆိုရင် အောက်ပါအတိုင်းဖြစ်နိုင်ပါတယ်-
```javascript
function displayGreeting() {
@ -47,28 +47,28 @@ function displayGreeting() {
}
```
Function ကိုခေါ်သုံးချင်တဲ့အခါမှာ Function နာမည်နဲ့ `()` ကိုသုံးရပါတယ်။ Function ကို ဖန်တီးထားတဲ့နေရာက အစဉ်အတိုင်းမဟုတ်ရင်တောင် JavaScript Compiler က Function ကိုရှာပေးပါလိမ့်မယ်။
Function ကို call (invoke) လုပ်ချင်တဲ့အခါ function ရဲ့နာမည်နောက်မှာ `()` သုံးပါ။ Function ကို define လုပ်တာက call လုပ်တာမတိုင်မီလည်းဖြစ်နိုင်ပါတယ်၊ call လုပ်ပြီးနောက်မှာလည်းဖြစ်နိုင်ပါတယ်။ JavaScript compiler က function ကိုရှာပေးပါလိမ့်မယ်။
```javascript
// calling our function
displayGreeting();
```
> **NOTE:** Function ရဲ့ အထူးအမျိုးအစားတစ်ခုကို **Method** လို့ခေါ်ပါတယ်။ ဥပမာ - `console.log` ကို သုံးတဲ့အခါမှာ Method ကိုသုံးနေပါတယ်။ Method က Object တစ်ခု (`console`) နဲ့ ပတ်သက်ပြီးရှိတာဖြစ်ပြီး Function ကတော့ လွတ်လပ်ပါတယ်။ Developer အများစုက Method နဲ့ Function ဆိုတာကို အလွယ်တကူ အစားထိုးသုံးတတ်ကြပါတယ်။
> **NOTE:** Function ရဲ့အထူးအမျိုးအစားတစ်ခုကို **method** လို့ခေါ်ပါတယ်၊ ဒါကိုသင်ပြီးသားသုံးနေပါတယ်! ဥပမာအားဖြင့် `console.log` ကိုသုံးတဲ့အခါမှာ method ကိုသုံးနေပါတယ်။ Method က object (`console` က ဥပမာ) တစ်ခုနဲ့ပတ်သက်ပြီးရှိပါတယ်၊ function ကတော့ independent ဖြစ်ပါတယ်။ Developer အများစုက method နဲ့ function ဆိုတာကို အတူတူသုံးတတ်ပါတယ်။
### Function ဖန်တီးရာမှာ အကောင်းဆုံးအကြံပြုချက်များ
### Function ရေးသားရာမှာအကောင်းဆုံးနည်းလမ်းများ
Function ဖန်တီးရာမှာ အောက်ပါအချက်များကို သတိပြုပါ-
Function ဖန်တီးတဲ့အခါမှာ အောက်ပါအချက်များကိုသတိထားပါ-
- အမြဲတမ်း ဖော်ပြချက်ပေးတဲ့ နာမည်များကို သုံးပါ။
- စကားလုံးများကို ပေါင်းစပ်ရာမှာ **camelCasing** ကိုသုံးပါ။
- Function တစ်ခုကို အထူးအလုပ်တစ်ခုအတွက်သာ အာရုံစိုက်ပါ။
- အမြဲတမ်း နာမည်ကိုရှင်းလင်းပြီး function ရဲ့လုပ်ဆောင်မှုကိုသိနိုင်အောင်ရေးပါ
- **camelCasing** ကိုအသုံးပြုပြီး စကားလုံးများကိုပေါင်းစည်းပါ
- Function ကို အထူးလုပ်ဆောင်မှုတစ်ခုအပေါ်အာရုံစိုက်အောင်ထားပါ
## Function ကို အချက်အလက်များဖြင့် ဖြည့်စွက်ခြင်း
## Function ကိုသို့မဟုတ် parameter ထည့်ခြင်း
Function တစ်ခုကို ပိုမိုအသုံးဝင်စေဖို့ အချက်အလက်များ (parameters) ကို ဖြည့်စွက်နိုင်ပါတယ်။ ဥပမာ - `displayGreeting` Function က **Hello, world!** ကိုသာ ပြသနိုင်ပါတယ်။ Function ကို ပိုမိုပြောင်းလွယ်ပြုလွယ်စေဖို့ အမည်တစ်ခုကို parameter အနေနဲ့ ထည့်သွင်းနိုင်ပါတယ်။
Function ကိုပိုပြီးအသုံးဝင်အောင်လုပ်ဖို့ parameter ထည့်သွင်းတတ်ရပါမယ်။ ဥပမာအားဖြင့် `displayGreeting` function က **Hello, world!** ကိုသာပြသနိုင်ပါတယ်။ Function ကိုပိုပြီး flexible ဖြစ်အောင်လုပ်ချင်ရင် parameter (sometimes called **argument**) ထည့်သွင်းနိုင်ပါတယ်။
Parameter တွေကို Function ရဲ့ parenthesis အတွင်းမှာ comma ဖြင့် ခွဲပြီး သတ်မှတ်ရပါတယ်-
Parameter တွေကို parenthesis အတွင်းမှာ comma ဖြင့်ခွဲပြီးရေးပါ-
```javascript
function name(param, param2, param3) {
@ -76,7 +76,7 @@ function name(param, param2, param3) {
}
```
`displayGreeting` Function ကို အမည်တစ်ခုကို parameter အနေနဲ့ ထည့်သွင်းပြီး ပြောင်းလဲနိုင်ပါတယ်
`displayGreeting` ကို update လုပ်ပြီး name ကိုပြသနိုင်အောင်လုပ်ပါ
```javascript
function displayGreeting(name) {
@ -85,7 +85,7 @@ function displayGreeting(name) {
}
```
Function ကိုခေါ်သုံးတဲ့အခါမှာ parameter ကို parenthesis အတွင်းမှာ သတ်မှတ်ရပါတယ်
Function ကို call လုပ်ပြီး parameter ထည့်ချင်ရင် parenthesis အတွင်းမှာရေးပါ
```javascript
displayGreeting('Christopher');
@ -94,7 +94,7 @@ displayGreeting('Christopher');
## Default values
Function ကို ပိုမိုပြောင်းလွယ်ပြုလွယ်စေဖို့ parameter တွေကို ပိုထည့်နိုင်ပါတယ်။ သို့သော် parameter တစ်ခုချင်းစီကို မလိုအပ်လျှင် Default Value ကို သတ်မှတ်နိုင်ပါတယ်။ ဥပမာ - Greeting ကို Default Value အဖြစ် သတ်မှတ်နိုင်ပါတယ်။
Function ကိုပိုပြီး flexible ဖြစ်အောင် parameter တွေထပ်ထည့်နိုင်ပါတယ်။ ဒါပေမယ့် parameter တစ်ခုစီကိုမဖြည့်ရမယ်ဆိုရင် default value ကိုပေးနိုင်ပါတယ်။ ဥပမာအားဖြင့် name ကိုလိုအပ်တဲ့ parameter အဖြစ်ထားပြီး salutation ကို optional default value ပေးနိုင်ပါတယ်။
```javascript
function displayGreeting(name, salutation='Hello') {
@ -102,7 +102,7 @@ function displayGreeting(name, salutation='Hello') {
}
```
Function ကိုခေါ်သုံးတဲ့အခါမှာ `salutation` ကို သတ်မှတ်မလား မသတ်မှတ်ဘူးဆိုတာ ဆုံးဖြတ်နိုင်ပါတယ်။
Function ကို call လုပ်တဲ့အခါ salutation ကိုပေးမလားမပေးမလားဆုံးဖြတ်နိုင်ပါတယ်။
```javascript
displayGreeting('Christopher');
@ -114,15 +114,15 @@ displayGreeting('Christopher', 'Hi');
## Return values
ယခင် Function တွေက console မှာ output ပြသဖို့သာ ရည်ရွယ်ထားပါတယ်။ သို့သော် Calculation လုပ်ပြီး အဖြေကို ပြန်ပေးစေချင်ရင် **return value** ကို သုံးနိုင်ပါတယ်။
Function တွေဟာ console output ပေးနိုင်ပါတယ်။ ဒါဟာတစ်ခါတစ်ရံမှာလိုအပ်တဲ့အရာဖြစ်နိုင်ပါတယ်။ ဒါပေမယ့် calculation လုပ်ပြီး value ကိုပြန်ပေးချင်ရင် return value ကိုအသုံးပြုနိုင်ပါတယ်။
Function တစ်ခုက value တစ်ခုကို return လုပ်မယ်ဆိုရင် `return` keyword ကို သုံးရပါတယ်။
Function တစ်ခု return value ပေးမယ်ဆိုရင် `return` keyword ကိုအသုံးပြုပါ။ `return` keyword က value သို့မဟုတ် reference ကိုပြန်ပေးပါမယ်။
```javascript
return myVariable;
```
Greeting message တစ်ခုကို ဖန်တီးပြီး value ကို ပြန်ပေးတဲ့ Function တစ်ခုကို ဖန်တီးနိုင်ပါတယ်။
Greeting message တစ်ခုဖန်တီးပြီး value ကိုပြန်ပေးတဲ့ function ကိုဖန်တီးနိုင်ပါတယ်-
```javascript
function createGreetingMessage(name) {
@ -131,7 +131,7 @@ function createGreetingMessage(name) {
}
```
Function ကိုခေါ်သုံးတဲ့အခါမှာ value ကို variable တစ်ခုထဲမှာ သိမ်းဆည်းနိုင်ပါတယ်။
Function ကို call လုပ်တဲ့အခါ value ကို variable ထဲမှာသိမ်းနိုင်ပါတယ်။
```javascript
const greetingMessage = createGreetingMessage('Christopher');
@ -139,7 +139,9 @@ const greetingMessage = createGreetingMessage('Christopher');
## Functions as parameters for functions
Programming လောကမှာ Function တစ်ခုကို Function တစ်ခုရဲ့ parameter အဖြစ် သုံးရတဲ့အခါတွေ ရှိတတ်ပါတယ်။ ဥပမာ - [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) က Timer တစ်ခုကို စတင်ပြီး အချိန်ကုန်လို့ ပြီးဆုံးတဲ့အခါမှာ Function တစ်ခုကို ခေါ်သုံးစေပါတယ်။
Programming အတတ်ပညာမှာ function တွေကို parameter အဖြစ်အသုံးပြုနိုင်ပါတယ်။ ဥပမာအားဖြင့် [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) က timer ကိုစပြီး timer ပြီးတဲ့အခါ code ကို run လုပ်ပါမယ်။
Code ကို run လုပ်ပါက ၃ စက္ကန့်အကြာမှာ **3 seconds has elapsed** ဆိုတဲ့ message ကိုတွေ့ပါမယ်။
```javascript
function displayDone() {
@ -151,7 +153,7 @@ setTimeout(displayDone, 3000);
### Anonymous functions
Function တစ်ခုကို တစ်ကြိမ်သာ သုံးမယ်ဆိုရင် အမည်မပေးဘဲ Anonymous Function အဖြစ် ဖန်တီးနိုင်ပါတယ်။
Function တစ်ခုကိုနာမည်ပေးပြီး တစ်ခါသာအသုံးပြုမယ်ဆိုရင် anonymous function ကိုအသုံးပြုနိုင်ပါတယ်။
```javascript
setTimeout(function() {
@ -161,7 +163,7 @@ setTimeout(function() {
### Fat arrow functions
JavaScript မှာ `=>` ကို သုံးပြီး Fat Arrow Function ကို ဖန်တီးနိုင်ပါတယ်။
Fat arrow function သည် `=>` ကိုအသုံးပြုပြီး function ကိုရေးသားနိုင်ပါတယ်။
```javascript
setTimeout(() => {
@ -169,28 +171,28 @@ setTimeout(() => {
}, 3000);
```
### ဘယ်အခါမှာ ဘယ်နည်းကို သုံးမလဲ
### Strategy အသုံးပြုရန်အချိန်
Function ကို တစ်ကြိမ်ထက်ပိုသုံးမယ်ဆိုရင် ပုံမှန် Function အဖြစ် ဖန်တီးပါ။ တစ်နေရာတည်းမှာသာ သုံးမယ်ဆိုရင် Anonymous Function သုံးပါ။ Fat Arrow Function သို့မဟုတ် ပုံမှန် Syntax ကို သုံးမယ်ဆိုတာ သင့်ရွေးချယ်မှုပါ
Function ကိုတစ်ခါထက်မကအသုံးပြုမယ်ဆိုရင် နာမည်ပေးပြီးဖန်တီးပါ။ တစ်ခါသာအသုံးပြုမယ်ဆိုရင် anonymous function ကိုသုံးပါ။ Fat arrow function သို့မဟုတ် traditional syntax ကိုသုံးမယ်ဆိုတာ developer ရဲ့ရွေးချယ်မှုဖြစ်ပါတယ်
---
## 🚀 စိန်ခေါ်မှု
Function နဲ့ Method တို့ရဲ့ ကွာခြားချက်ကို စာကြောင်းတစ်ကြောင်းနဲ့ ရှင်းပြနိုင်မလား? ကြိုးစားကြည့်ပါ။
Function နဲ့ method ရဲ့ကွာခြားချက်ကို တစ်ကြောင်းစာနဲ့ရှင်းပြနိုင်ပါသလား?
## မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/10)
## မိန့်ခွန်းပြီး Quiz
[Post-lecture quiz](https://ff-quizzes.netlify.app)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
[Arrow functions](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) အကြောင်း ပိုမိုလေ့လာဖို့ တန်ဖိုးရှိပါတယ်။ Function တစ်ခုကိုရေးပြီး Arrow Function နဲ့ ပြန်ရေးကြည့်ပါ။
[Arrow functions](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) အကြောင်းပိုမိုလေ့လာပါ။ Function တစ်ခုရေးပြီး arrow syntax နဲ့ပြန်ရေးပါ။
## လုပ်ငန်းတာဝန်
## အိမ်စာ
[Fun with Functions](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,59 +1,59 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "888609c48329c280ca2477d2df40f2e5",
"translation_date": "2025-08-27T22:29:48+00:00",
"original_hash": "f7009631b73556168ca435120a231c98",
"translation_date": "2025-08-28T18:41:49+00:00",
"source_file": "2-js-basics/3-making-decisions/README.md",
"language_code": "my"
}
-->
# JavaScript အခြေခံများ: ဆုံးဖြတ်ချက်များချခြင်း
![JavaScript Basics - Making decisions](../../../../translated_images/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.my.png)
![JavaScript အခြေခံများ - ဆုံးဖြတ်ချက်များချခြင်း](../../../../translated_images/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.my.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## မိန့်ခွန်းမတင်မီ စမ်းမေးခွန်း
## မိန့်ခွန်းမတိုင်မီ စစ်ဆေးမှု
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/11)
[မိန့်ခွန်းမတိုင်မီ စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/11)
ဆုံးဖြတ်ချက်များချခြင်းနှင့် သင့်ကုဒ်ကို အစီအစဉ်တကျ လည်ပတ်စေခြင်းသည် သင့်ကုဒ်ကို ပြန်လည်အသုံးပြုနိုင်စေပြီး ခိုင်မာစေပါသည်။ ဤအပိုင်းတွင် JavaScript တွင် ဒေတာလှည့်ပတ်မှုကို ထိန်းချုပ်ရန် syntax နှင့် Boolean ဒေတာအမျိုးအစားများနှင့် တွဲဖက်အသုံးပြုသောအခါ ၎င်း၏ အရေးပါမှုကို ဖော်ပြထားသည်။
ဆုံးဖြတ်ချက်များချခြင်းနှင့် သင့်ကုဒ်ကို အစဉ်လိုက်အောင် စီမံခြင်းသည် သင့်ကုဒ်ကို ပြန်လည်အသုံးပြုနိုင်စေပြီး ခိုင်မာစေသည်။ ဤအပိုင်းတွင် JavaScript တွင် ဒေတာလှည့်ပတ်မှုကို ထိန်းချုပ်ရန် သုံးသည့် သဒ္ဒါနှင့် Boolean ဒေတာအမျိုးအစားများနှင့်အတူ အသုံးပြုသောအခါ ၎င်း၏ အရေးပါမှုကို ဖော်ပြထားသည်။
[![Making Decisions](https://img.youtube.com/vi/SxTp8j-fMMY/0.jpg)](https://youtube.com/watch?v=SxTp8j-fMMY "Making Decisions")
[![ဆုံးဖြတ်ချက်များချခြင်း](https://img.youtube.com/vi/SxTp8j-fMMY/0.jpg)](https://youtube.com/watch?v=SxTp8j-fMMY "ဆုံးဖြတ်ချက်များချခြင်း")
> 🎥 အထက်ပါပုံကို နှိပ်ပြီး ဆုံးဖြတ်ချက်များချခြင်းအကြောင်း ဗီဒီယိုကို ကြည့်ပါ။
> 🎥 အထက်ပါပုံကို နှိပ် ဆုံးဖြတ်ချက်များချခြင်းအကြောင်း ဗီဒီယိုကို ကြည့်ပါ။
> ဤသင်ခန်းစာကို [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-if-else/?WT.mc_id=academic-77807-sagibbon) တွင်လည်း လေ့လာနိုင်ပါသည်။
> ဤသင်ခန်းစာကို [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-if-else/?WT.mc_id=academic-77807-sagibbon) တွင် လေ့လာနိုင်ပါသည်။
## Boolean များအကြောင်း အကျဉ်းချုပ်
Boolean များတွင် `true` သို့မဟုတ် `false` ဆိုသော တန်ဖိုးနှစ်ခုသာ ရှိနိုင်သည်။ Boolean များသည် အခြေအနေတစ်ခုခုဖြင့် သတ်မှတ်ထားသောအခါ သင့်ကုဒ်၏ ဘယ်လိုလိုင်းများကို လည်ပတ်စေမည်ကို ဆုံးဖြတ်ရန် အထောက်အကူပြုသည်။
Boolean များတွင် `true` သို့မဟုတ် `false` ဆိုသည့် တန်ဖိုးနှစ်ခုသာ ရှိနိုင်သည်။ Boolean များသည် အခြေအနေတစ်ခုခုဖြင့် သတ်မှတ်ထားသောအခါ သင့်ကုဒ်၏ ဘယ်လိုလိုင်းများကို အလုပ်လုပ်မည်ကို ဆုံးဖြတ်ရန် အထောက်အကူပြုသည်။
သင့် Boolean ကို `true` သို့မဟုတ် `false` အဖြစ် သတ်မှတ်ပါ-
`let myTrueBool = true`
`let myFalseBool = false`
✅ Boolean များကို အင်္ဂလိပ် သင်္ချာပညာရှင်၊ အတွေးအခေါ်ပညာရှင်နှင့် သီအိုရီပညာရှင် George Boole (18151864) ၏ နာမည်မှ ဆောင်ယူထားသည်။
✅ Boolean များကို အင်္ဂလိပ် သင်္ချာပညာရှင်၊ ဒဿနပညာရှင်နှင့် သဘောတရားပညာရှင် George Boole (18151864) ၏ နာမည်မှ ဆောင်ယူထားသည်။
## နှိုင်းယှဉ်မှု Operator များနှင့် Boolean များ
Operator များကို အခြေအနေများကို နှိုင်းယှဉ်ရန် အသုံးပြုပြီး Boolean တန်ဖိုးတစ်ခုကို ဖန်တီးသည်။ အောက်တွင် မကြာခဏ အသုံးပြုသော Operator များစာရင်းကို ဖော်ပြထားသည်။
Operator များကို အခြေအနေများကို သုံးသပ်ရန် အသုံးပြုပြီး Boolean တန်ဖိုးကို ဖန်တီးရန် နှိုင်းယှဉ်မှုများ ပြုလုပ်သည်။ အောက်တွင် မကြာခဏ အသုံးပြုသော Operator များစာရင်းကို ဖော်ပြထားသည်။
| သင်္ကေတ | ဖော်ပြချက် | ဥပမာ |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `<` | **နည်းသော**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်တန်ဖိုးသည် ညာဘက်ထက် နည်းသောအခါ `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 < 6 // true` |
| `<=` | **နည်းသော်လည်း ညီမျှသော**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်တန်ဖိုးသည် ညာဘက်ထက် နည်းသော်လည်း ညီမျှသောအခါ `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 <= 6 // true` |
| `>` | **ကြီးသော**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်တန်ဖိုးသည် ညာဘက်ထက် ကြီးသောအခါ `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 > 6 // false` |
| `>=` | **ကြီးသော်လည်း ညီမျှသော**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်တန်ဖိုးသည် ညာဘက်ထက် ကြီးသော်လည်း ညီမျှသောအခါ `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 >= 6 // false` |
| `===` | **တိကျသော ညီမျှမှု**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်နှင့် ညာဘက်တန်ဖိုးများသည် တူညီပြီး ဒေတာအမျိုးအစားလည်း တူညီသောအခါ `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 === 6 // false` |
| `!==` | **မညီမျှမှု**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး တိကျသော ညီမျှမှု operator ၏ ဆန့်ကျင်ဘက် Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 !== 6 // true` |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| `<` | **ငယ်သည်**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်တန်ဖိုးသည် ညာဘက်ထက် ငယ်လျှင် `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 < 6 // true` |
| `<=` | **ငယ်သည် သို့မဟုတ် ငြိမ်သည်**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်တန်ဖိုးသည် ညာဘက်ထက် ငယ် သို့မဟုတ် ငြိမ်လျှင် `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 <= 6 // true` |
| `>` | **ကြီးသည်**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်တန်ဖိုးသည် ညာဘက်ထက် ကြီးလျှင် `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 > 6 // false` |
| `>=` | **ကြီးသည် သို့မဟုတ် ငြိမ်သည်**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်တန်ဖိုးသည် ညာဘက်ထက် ကြီး သို့မဟုတ် ငြိမ်လျှင် `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 >= 6 // false` |
| `===` | **တိကျသော တန်းတူမှု**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး ဘယ်ဘက်နှင့် ညာဘက်တန်ဖိုးများသည် တူပြီး ဒေတာအမျိုးအစားလည်း တူလျှင် `true` Boolean တန်ဖိုးကို ပြန်ပေးသည် | `5 === 6 // false` |
| `!==` | **တူညီမှု**: တန်ဖိုးနှစ်ခုကို နှိုင်းယှဉ်ပြီး တိကျသော တန်းတူမှု Operator ပြန်ပေးမည့် Boolean တန်ဖိုး၏ ဆန့်ကျင်ဘက်ကို ပြန်ပေးသည် | `5 !== 6 // true` |
✅ သင့် browser console တွင် နှိုင်းယှဉ်မှုအချို့ကို ရေးသားပြီး သင့်အသိပညာကို စစ်ဆေးပါ။ ပြန်လာသောဒေတာများထဲတွင် အံ့အားသင့်စရာတစ်ခုခု ရှိပါသလား?
✅ သင့် browser console တွင် နှိုင်းယှဉ်မှုများကို ရေးသားပြီး သင့်အသိပညာကို စစ်ဆေးပါ။ ပြန်ပေးသော ဒေတာများထဲတွင် အံ့ဩစရာရှိပါသလား။
## If Statement
`if` statement သည် အခြေအနေတစ်ခု `true` ဖြစ်ပါက ၎င်း၏ block များအတွင်းရှိကုဒ်ကို လည်ပတ်စေပါသည်။
`if` statement သည် အခြေအနေသည် `true` ဖြစ်ပါက ၎င်း၏ block များအတွင်းရှိ ကုဒ်ကို အလုပ်လုပ်စေသည်။
```javascript
if (condition) {
@ -61,7 +61,7 @@ if (condition) {
}
```
အခြေအနေဖွဲ့စည်းရာတွင် Logical operator များကို မကြာခဏ အသုံးပြုသည်။
အခြေအနေဖွဲ့စည်းရာတွင် Logical Operator များကို မကြာခဏ အသုံးပြုသည်။
```javascript
let currentMoney;
@ -75,7 +75,7 @@ if (currentMoney >= laptopPrice) {
## If..Else Statement
`else` statement သည် အခြေအနေတစ်ခု `false` ဖြစ်ပါက ၎င်း၏ block များအတွင်းရှိကုဒ်ကို လည်ပတ်စေပါသည်။ ၎င်းသည် `if` statement နှင့်အတူ ရွေးချယ်စရာဖြစ်သည်။
`else` statement သည် အခြေအနေသည် `false` ဖြစ်ပါက ၎င်း၏ block များအတွင်းရှိ ကုဒ်ကို အလုပ်လုပ်စေသည်။ ၎င်းသည် `if` statement နှင့်အတူ ရွေးချယ်စရာဖြစ်သည်။
```javascript
let currentMoney;
@ -90,11 +90,11 @@ if (currentMoney >= laptopPrice) {
}
```
✅ ဤကုဒ်နှင့် အောက်ပါကုဒ်ကို browser console တွင် လည်ပတ်စေပြီး သင့်နားလည်မှုကို စမ်းသပ်ပါ။ `currentMoney` နှင့် `laptopPrice` variable များ၏ တန်ဖိုးများကို ပြောင်းလဲပြီး `console.log()` ၏ output ကို ပြောင်းလဲကြည့်ပါ။
✅ ဤကုဒ်နှင့် အောက်ပါကုဒ်ကို browser console တွင် အလုပ်လုပ်စေပြီး သင့်နားလည်မှုကို စစ်ဆေးပါ။ `currentMoney` နှင့် `laptopPrice` variable များ၏ တန်ဖိုးများကို ပြောင်းလဲပြီး `console.log()` ပြန်ပေးသောအရာကို ပြောင်းလဲကြည့်ပါ။
## Switch Statement
`switch` statement သည် အခြေအနေအမျိုးမျိုးအပေါ် မူတည်၍ ကွဲပြားသော လုပ်ဆောင်မှုများကို ပြုလုပ်ရန် အသုံးပြုသည်။ `switch` statement ကို အသုံးပြု၍ လည်ပတ်စေလိုသော code block တစ်ခုကို ရွေးချယ်ပါ။
`switch` statement ကို အခြေအနေအမျိုးမျိုးအပေါ် မူတည်၍ ကွဲပြားသော လုပ်ဆောင်မှုများကို ပြုလုပ်ရန် အသုံးပြုသည်။ `switch` statement ကို အသုံးပြု၍ အလုပ်လုပ်စေမည့် ကုဒ် block တစ်ခုကို ရွေးချယ်ပါ။
```javascript
switch (expression) {
@ -127,21 +127,21 @@ switch (a) {
console.log(`The value is ${a}`);
```
✅ ဤကုဒ်နှင့် အောက်ပါကုဒ်ကို browser console တွင် လည်ပတ်စေပြီး သင့်နားလည်မှုကို စမ်းသပ်ပါ။ `a` variable ၏ တန်ဖိုးကို ပြောင်းလဲပြီး `console.log()` ၏ output ကို ပြောင်းလဲကြည့်ပါ။
✅ ဤကုဒ်နှင့် အောက်ပါကုဒ်ကို browser console တွင် အလုပ်လုပ်စေပြီး သင့်နားလည်မှုကို စစ်ဆေးပါ။ `a` variable ၏ တန်ဖိုးများကို ပြောင်းလဲပြီး `console.log()` ပြန်ပေးသောအရာကို ပြောင်းလဲကြည့်ပါ။
## Logical Operator များနှင့် Boolean များ
ဆုံးဖြတ်ချက်များသည် တစ်ခုထက်ပိုသော နှိုင်းယှဉ်မှုများလိုအပ်နိုင်ပြီး Logical operator များဖြင့် string တစ်ခုအဖြစ် ပေါင်းစပ်၍ Boolean တန်ဖိုးတစ်ခုကို ဖန်တီးနိုင်သည်။
ဆုံးဖြတ်ချက်များသည် တစ်ခုထက်ပိုသော နှိုင်းယှဉ်မှုများကို လိုအပ်နိုင်ပြီး Logical Operator များဖြင့် ဆက်စပ်၍ Boolean တန်ဖိုးကို ထုတ်နိုင်သည်။
| သင်္ကေတ | ဖော်ပြချက် | ဥပမာ |
| ------ | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `&&` | **Logical AND**: Boolean အထုတ်ဖော်ချက်နှစ်ခုကို နှိုင်းယှဉ်သည်။ နှစ်ဖက်လုံး `true` ဖြစ်ပါကသာ `true` ကို ပြန်ပေးသည် | `(5 > 6) && (5 < 6 ) //တစ်ဖက် false, တစ်ဖက် true. false ကို ပြန်ပေးသည်` |
| `\|\|` | **Logical OR**: Boolean အထုတ်ဖော်ချက်နှစ်ခုကို နှိုင်းယှဉ်သည်။ အနည်းဆုံးတစ်ဖက် `true` ဖြစ်ပါက `true` ကို ပြန်ပေးသည် | `(5 > 6) \|\| (5 < 6) //တစ်ဖက် false, တစ်ဖက် true. true ကို ပြန်ပေးသည်` |
| `!` | **Logical NOT**: Boolean အထုတ်ဖော်ချက်၏ ဆန့်ကျင်ဘက်တန်ဖိုးကို ပြန်ပေးသည် | `!(5 > 6) // 5 သည် 6 ထက် ကြီးမဟုတ်သော်လည်း "!" သည် true ကို ပြန်ပေးသည်` |
| -------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `&&` | **Logical AND**: Boolean ဖော်ပြချက်နှစ်ခုကို နှိုင်းယှဉ်သည်။ နှစ်ဖက်လုံး `true` ဖြစ်လျှင်သာ `true` ပြန်ပေးသည် | `(5 > 6) && (5 < 6 ) //ဖက်တစ်ဖက်သည် false, ဖက်တစ်ဖက်သည် true. false ပြန်ပေးသည်` |
| `\|\|` | **Logical OR**: Boolean ဖော်ပြချက်နှစ်ခုကို နှိုင်းယှဉ်သည်။ ဖက်တစ်ဖက် `true` ဖြစ်လျှင် `true` ပြန်ပေးသည် | `(5 > 6) \|\| (5 < 6) //ဖက်တစ်ဖက်သည် false, ဖက်တစ်ဖက်သည် true. true ပြန်ပေးသည်` |
| `!` | **Logical NOT**: Boolean ဖော်ပြချက်၏ ဆန့်ကျင်ဘက်တန်ဖိုးကို ပြန်ပေးသည် | `!(5 > 6) // 5 သည် 6 ထက် ကြီးမဟုတ်ပါ, သို့သော် "!" သည် true ပြန်ပေးမည်` |
## Logical Operator များဖြင့် အခြေအနေများနှင့် ဆုံးဖြတ်ချက်များ
## Logical Operator များနှင့် If..Else Statement များဖြင့် ဆုံးဖြတ်ချက်များ
Logical operator များကို `if..else` statement များတွင် အခြေအနေဖွဲ့စည်းရန် အသုံးပြုနိုင်သည်။
Logical Operator များကို If..Else Statement များတွင် အခြေအနေဖွဲ့စည်းရန် အသုံးပြုနိုင်သည်။
```javascript
let currentMoney;
@ -157,9 +157,9 @@ if (currentMoney >= laptopPrice || currentMoney >= laptopDiscountPrice) {
}
```
### Negation operator
### Negation Operator
ယခင်တွင် သင်သည် `if...else` statement ကို အသုံးပြု၍ conditional logic ဖန်တီးနိုင်ကြောင်း မြင်ခဲ့ပါသည်။ `if` အတွင်းသို့ ဝင်သောအရာအားလုံးသည် `true/false` အဖြစ် အကဲဖြတ်ရမည်ဖြစ်သည်။ `!` operator ကို အသုံးပြု၍ အထုတ်ဖော်ချက်ကို _ဆန့်ကျင်_ ပြုလုပ်နိုင်သည်။ ၎င်းသည် အောက်ပါအတိုင်း ဖြစ်ပါမည်-
`if...else` statement ကို အသုံးပြု၍ အခြေအနေဆိုင်ရာ logical ကို ဖန်တီးနိုင်ပုံကို ယခင်က ကြည့်ခဲ့ပါသည်။ `if` အတွင်းသို့ သွားသော အရာအားလုံးသည် `true/false` အဖြစ် သတ်မှတ်ရမည်။ `!` operator ကို အသုံးပြု၍ ဖော်ပြချက်ကို _ဆန့်ကျင်_ ပြုလုပ်နိုင်သည်။ ၎င်းသည် အောက်ပါအတိုင်း ဖြစ်မည်-
```javascript
if (!condition) {
@ -169,9 +169,9 @@ if (!condition) {
}
```
### Ternary expressions
### Ternary Expression များ
`if...else` သည် ဆုံးဖြတ်ချက် logic ကို ဖော်ပြရန် တစ်ခုတည်းသော နည်းလမ်းမဟုတ်ပါ။ သင်သည် ternary operator ဟုခေါ်သော အရာတစ်ခုကိုလည်း အသုံးပြုနိုင်သည်။ ၎င်း၏ syntax သည် အောက်ပါအတိုင်း ဖြစ်ပါသည်-
`if...else` သည် ဆုံးဖြတ်ချက် logical ကို ဖော်ပြရန် တစ်ခုတည်းသော နည်းလမ်းမဟုတ်ပါ။ Ternary Operator ဟုခေါ်သော အရာတစ်ခုကိုလည်း အသုံးပြုနိုင်သည်။ ၎င်း၏ သဒ္ဒါသည် အောက်ပါအတိုင်း ဖြစ်သည်-
```javascript
let variable = condition ? <return this if true> : <return this if false>
@ -185,15 +185,15 @@ let secondNumber = 10;
let biggestNumber = firstNumber > secondNumber ? firstNumber : secondNumber;
```
✅ ဤကုဒ်ကို အချိန်ယူဖတ်ပါ။ Operator များသည် ဘယ်လို လည်ပတ်နေသည်ကို နားလည်ပါသလား?
✅ ဤကုဒ်ကို အချိန်ယူဖတ်ပါ။ Operator များအလုပ်လုပ်ပုံကို နားလည်ပါသလား။
အထက်ပါကုဒ်သည်-
အထက်ပါကုဒ်သည် အောက်ပါအတိုင်း ဆိုလိုသည်-
- `firstNumber` သည် `secondNumber` ထက် ကြီးပါက
- `firstNumber` သည် `secondNumber` ထက် ကြီးလျှင်
- `firstNumber` ကို `biggestNumber` သို့ သတ်မှတ်ပါ
- မဟုတ်ပါက `secondNumber` ကို သတ်မှတ်ပါ။
- မဟုတ်လျှင် `secondNumber` ကို သတ်မှတ်ပါ။
Ternary expression သည် အောက်ပါကုဒ်ကို ရေးသားရန် အကျဉ်းချုပ်နည်းလမ်းသာဖြစ်သည်-
Ternary Expression သည် အောက်ပါကုဒ်ကို ရေးသားရန် အတိုချုံးနည်းလမ်းသာဖြစ်သည်-
```javascript
let biggestNumber;
@ -208,19 +208,19 @@ if (firstNumber > secondNumber) {
## 🚀 စိန်ခေါ်မှု
Logical operator များကို အသုံးပြု၍ ရေးသားထားသော အစီအစဉ်တစ်ခုကို ဖန်တီးပါ၊ ထို့နောက် ၎င်းကို ternary expression အသုံးပြု၍ ပြန်ရေးပါ။ သင့်အကြိုက်ဆုံး syntax သည် ဘယ်ဟာလဲ?
Logical Operator များကို အသုံးပြု၍ ရေးသားထားသော ပရိုဂရမ်တစ်ခုကို ဖန်တီးပါ၊ ထို့နောက် Ternary Expression ကို အသုံးပြု၍ ထပ်မံရေးသားပါ။ သင့်အကြိုက်ဆုံး သဒ္ဒါသည် ဘယ်ဟာလဲ?
---
## မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း
## မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/12)
[မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/12)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
အသုံးပြုသူအတွက် ရရှိနိုင်သော operator များစွာအကြောင်းကို [MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators) တွင် ဖတ်ရှုပါ။
အသုံးပြုသူအတွက် ရရှိနိုင်သော Operator များစွာအကြောင်းကို [MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators) တွင် ဖတ်ရှုပါ။
Josh Comeau ၏ အံ့သြဖွယ် [operator lookup](https://joshwcomeau.com/operator-lookup/) ကို လေ့လာပါ!
Josh Comeau ၏ အလွန်အမင်းအထောက်အကူပြုသော [operator lookup](https://joshwcomeau.com/operator-lookup/) ကို လေ့လာပါ
## လုပ်ငန်းတာဝန်
@ -229,4 +229,4 @@ Josh Comeau ၏ အံ့သြဖွယ် [operator lookup](https://joshwcomea
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေပါသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွဲအချော်အချော်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "3f7f87871312cf6cc12662da7d973182",
"translation_date": "2025-08-27T22:32:51+00:00",
"original_hash": "9029f96b0e034839c1799f4595e4bb66",
"translation_date": "2025-08-28T18:43:09+00:00",
"source_file": "2-js-basics/4-arrays-loops/README.md",
"language_code": "my"
}
@ -15,7 +15,7 @@ CO_OP_TRANSLATOR_METADATA:
## မိန့်ခွန်းမပြောမီ Quiz
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/13)
ဒီသင်ခန်းစာမှာ JavaScript အခြေခံများကို လေ့လာပါမည်။ JavaScript သည် ဝဘ်ပေါ်တွင် အပြန်အလှန်လုပ်ဆောင်မှုများကို ပေးစွမ်းသော ဘာသာစကားဖြစ်သည်။ ဒီသင်ခန်းစာတွင် သင်သည် ဒေတာများကို စီမံခန့်ခွဲရန် အသုံးပြုသော arrays နှင့် loops အကြောင်းကို လေ့လာပါမည်။
ဒီသင်ခန်းစာမှာ JavaScript အခြေခံများကို လေ့လာပါမည်။ JavaScript သည် ဝဘ်ပေါ်တွင် အပြန်အလှန်လုပ်ဆောင်မှုများကို ပေးစွမ်းသော ဘာသာစကားဖြစ်သည်။ ဒီသင်ခန်းစာတွင် သင်သည် arrays နှင့် loops အကြောင်းကို လေ့လာမည်ဖြစ်ြီး၊ ဒါများကို ဒေတာကို စီမံခန့်ခွဲရန် အသုံးပြုသည်။
[![Arrays](https://img.youtube.com/vi/1U4qTyq02Xw/0.jpg)](https://youtube.com/watch?v=1U4qTyq02Xw "Arrays")
@ -27,9 +27,9 @@ CO_OP_TRANSLATOR_METADATA:
## Arrays
ဒေတာများနှင့် အလုပ်လုပ်ခြင်းသည် ဘာသာစကားတစ်ခုအတွက် အများဆုံးလုပ်ဆောင်ရသောအရာဖြစ်ပြီး ဒေတာများကို စနစ်တကျ စီစဉ်ထားသော ဖွဲ့စည်းမှု (arrays) တွင် သိမ်းဆည်းထားပါက ပိုမိုလွယ်ကူစေပါသည်။ Arrays တွင် ဒေတာများကို စာရင်းတစ်ခုလိုမျိုး ဖွဲ့စည်းထားသော ပုံစံတွင် သိမ်းဆည်းထားသည်။ Arrays ၏ အဓိကအားသာချက်တစ်ခုမှာ array တစ်ခုတွင် ဒေတာအမျိုးအစားများစွာကို သိမ်းဆည်းနိုင်ခြင်းဖြစ်သည်။
ဒေတာနှင့်အလုပ်လုပ်ခြင်းသည် ဘာသာစကားတိုင်းအတွက် ရိုးရိုးရှင်းရှင်းလုပ်ဆောင်ရမည့်အလုပ်ဖြစ်ပြီး၊ ဒေတာကို စနစ်တကျဖွဲ့စည်းထားသော ပုံစံ (ဥပမာ arrays) တွင် စီစဉ်ထားပါက ပိုမိုလွယ်ကူသည်။ Arrays တွင် ဒေတာကို စာရင်းပုံစံနှင့် ဆင်တူသော ဖွဲ့စည်းမှုတစ်ခုတွင် သိမ်းဆည်းထားသည်။ Arrays ၏ အရေးကြီးသော အကျိုးကျေးဇူးတစ်ခုမှာ တစ်ခုတည်းသော array တွင် ဒေတာအမျိုးအစားများစွာကို သိမ်းဆည်းနိုင်ခြင်းဖြစ်သည်။
✅ Arrays သည် ကျွန်ုပ်တို့၏ နေ့စဉ်ဘဝတွင် တွေ့ရသည်။ Solar panel array ကဲ့သို့ array တစ်ခုကို သင်စဉ်းစားနိုင်ပါသလား?
✅ Arrays သည် ကျွန်ုပ်တို့ပတ်ဝန်းကျင်တွင် အများကြီးရှိသည်! Solar panel array ကဲ့သို့သော အမှန်တကယ်ရှိသော array တစ်ခုကို သင်စဉ်းစားနိုင်ပါသလား?
Array ရေးသားရန် syntax သည် square brackets တစ်စုံဖြစ်သည်။
@ -37,36 +37,36 @@ Array ရေးသားရန် syntax သည် square brackets တစ်စ
let myArray = [];
```
ဤသည်မှာ အလွတ် array ဖြစ်သည်။ သို့သော် arrays များကို ဒေတာများဖြင့် ပြည့်စုံစွာ ကြေညာနိုင်ပါသည်။ Array တွင် ဒေတာများကို comma ဖြင့် ခွဲထားသည်။
ဤသည်မှာ အလွတ် array ဖြစ်သည်။ သို့သော် arrays များကို ဒေတာဖြင့် ပြည့်စုံပြီးသားအနေဖြင့် ကြေညာနိုင်သည်။ Array တွင်ရှိသော တန်ဖိုးများကို comma ဖြင့် ခွဲထားသည်။
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
```
Array တွင်ရှိသော ဒေတာများသည် **index** ဟုခေါ်သော တစ်ခုတည်းသော တန်ဖိုးကို ပေးထားသည်။ Index သည် array ၏အစမှ အကွာအဝေးအပေါ် မူတည်၍ သတ်မှတ်ထားသော ကိန်းဂဏန်းဖြစ်သည်။ အထက်ပါဥပမာတွင် "Chocolate" သည် index 0 ရှိပြီး "Rocky Road" သည် index 4 ရှိသည်။ Square brackets နှင့် index ကို အသုံးပြု၍ array တန်ဖိုးများကို ရယူ၊ ပြောင်းလဲ၊ သို့မဟုတ် ထည့်သွင်းနိုင်သည်။
Array တွင်ရှိသော တန်ဖိုးများကို **index** ဟုခေါ်သော တန်ဖိုးတစ်ခုဖြင့် သတ်မှတ်ထားသည်။ Index သည် array ၏အစမှ အကွာအဝေးအပေါ် မူတည်၍ သတ်မှတ်ထားသော ကိန်းဂဏန်းဖြစ်သည်။ အထက်ပါဥပမာတွင် "Chocolate" ဟုရေးထားသော string တန်ဖိုးသည် index 0 ရှိပြီး၊ "Rocky Road" ၏ index သည် 4 ဖြစ်သည်။ Square brackets နှင့် index ကို အသုံးပြု၍ array တန်ဖိုးများကို ရယူ၊ ပြောင်းလဲ၊ သို့မဟုတ် ထည့်သွင်းနိုင်သည်။
✅ Arrays သည် 0 index မှ စတင်သည်ဟု သင်အံ့ဩပါသလား? အချို့ programming languages တွင် index များသည် 1 မှ စတင်သည်။ ဤအကြောင်းအရာကို [Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering) တွင် ဖတ်ရှုနိုင်ပါသည်။
✅ Arrays သည် 0 index မှ စတင်သည်ဟု သင်အံ့ဩပါသလား? အချို့ programming languages တွင် index များသည် 1 မှ စတင်သည်။ ဤအကြောင်းအရာနှင့်ပတ်သက်သော စိတ်ဝင်စားဖွယ်ရာ သမိုင်းကြောင်းကို [Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering) တွင် ဖတ်ရှုနိုင်ပါသည်။
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
iceCreamFlavors[2]; //"Vanilla"
```
Index ကို အသုံးပြု၍ တန်ဖိုးကို ပြောင်းလဲနိုင်သည်
Index ကို အသုံးပြု၍ တန်ဖိုးကို ပြောင်းလဲနိုင်သည်၊ ဥပမာအားဖြင့်:
```javascript
iceCreamFlavors[4] = "Butter Pecan"; //Changed "Rocky Road" to "Butter Pecan"
```
Index တစ်ခုတွင် တန်ဖိုးအသစ်ကို ထည့်သွင်းနိုင်သည်
သတ်မှတ်ထားသော index တွင် တန်ဖိုးအသစ်ကို ထည့်သွင်းနိုင်သည်၊ ဥပမာအားဖြင့်:
```javascript
iceCreamFlavors[5] = "Cookie Dough"; //Added "Cookie Dough"
```
✅ Array တွင် တန်ဖိုးများကို push လုပ်ရန် array.push() ကဲ့သို့သော array operators ကို အသုံးပြုခြင်းသည် ပိုမိုရိုးရှင်းသည်။
✅ Array တွင် တန်ဖိုးများကို push လုပ်ရန် array.push() ကဲ့သို့သော array operators များကို အသုံးပြုခြင်းသည် ပိုမိုရိုးရှင်းသော နည်းလမ်းဖြစ်သည်။
Array တွင်ရှိသော item အရေအတွက်ကို သိရန် `length` property ကို အသုံးပြုပါ။
Array တွင်ရှိသော items အရေအတွက်ကို သိရန် `length` property ကို အသုံးပြုပါ။
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
@ -77,14 +77,14 @@ iceCreamFlavors.length; //5
## Loops
Loops များသည် ထပ်တလဲလဲလုပ်ဆောင်မှုများ (repetitive tasks) ကို လုပ်ဆောင်ရန် အချိန်နှင့် ကုဒ်များကို သက်သာစေသည်။ Iteration တစ်ခုစီသည် variable, value, condition များအပေါ် မူတည်၍ ကွဲပြားနိုင်သည်။ JavaScript တွင် loops အမျိုးအစားများစွာရှိပြီး အနည်းငယ်ကွဲပြားသော်လည်း အဓိကအားဖြင့် တူညီသောအရာကို လုပ်ဆောင်သည်
Loops များသည် ထပ်တလဲလဲလုပ်ဆောင်မှုများ သို့မဟုတ် **iterative** အလုပ်များကို လုပ်ဆောင်ရန် ခွင့်ပြုသည်။ ဒါက အချိန်နှင့် ကုဒ်များကို သိမ်းဆည်းပေးနိုင်သည်။ Loop တစ်ခု၏ iteration တစ်ခုစီသည် variable, value, နှင့် condition များအပေါ် မူတည်၍ ကွဲပြားနိုင်သည်။ JavaScript တွင် loops အမျိုးအစားများစွာရှိပြီး အနည်းငယ်ကွဲပြားမှုများရှိသော်လည်း အဓိကအားဖြင့် တူညီသောအလုပ်ကို လုပ်ဆောင်သည်: ဒေတာကို loop လုပ်ခြင်း
### For Loop
`for` loop သည် iteration ပြုလုပ်ရန် အချက် ၃ ခုလိုအပ်သည်
`for` loop သည် iteration လုပ်ရန် အချက် ၃ ခုလိုအပ်သည်:
- `counter` Iteration အရေအတွက်ကို ရေတွက်ရန် သတ်မှတ်ထားသော variable
- `condition` Comparison operators ကို အသုံးပြု၍ `false` ဖြစ်သောအခါ loop ကို ရပ်တန့်စေသော expression
- `iteration-expression` Iteration တစ်ခုစီ၏ အဆုံးတွင် run လုပ်ပြီး counter value ကို ပြောင်းလဲရန် အသုံးပြုသည်
- `iteration-expression` Iteration တစ်ခုစီ၏ အဆုံးတွင် run လုပ်ပြီး counter value ကို ပြောင်းလဲရန် အသုံးပြုသည်
```javascript
// Counting up to 10
@ -93,11 +93,11 @@ for (let i = 0; i < 10; i++) {
}
```
✅ ဤကုဒ်ကို browser console တွင် run လုပ်ပါ။ Counter, condition, iteration expression ကို အနည်းငယ်ပြောင်းလဲပါက ဘာဖြစ်မည်ကို စမ်းသပ်ပါ။ Countdown ပြုလုပ်ရန် နောက်ပြန် run လုပ်နိုင်ပါသလား?
✅ ဤကုဒ်ကို browser console တွင် run လုပ်ပါ။ Counter, condition, iteration expression တို့ကို အနည်းငယ်ပြောင်းလဲပါက ဘာဖြစ်မည်ကို စမ်းသပ်ပါ။ Loop ကို နောက်ပြန်လည်လုပ်ပြီး countdown ဖန်တီးနိုင်ပါသလား?
### While loop
`for` loop ၏ syntax နှင့် မတူကွဲပြားပြီး `while` loop သည် condition တစ်ခုသာ လိုအပ်သည်။ Condition သည် `false` ဖြစ်သောအခါ loop ကို ရပ်တန့်စေသည်။ Loop တွင် condition များသည် counter ကဲ့သို့သော တန်ဖိုးများကို အခြေခံပြီး loop အတွင်းတွင် စီမံရမည်။ Counter များကို loop အပြင်တွင် စတင်ဖန်တီးရမည်။
`for` loop ၏ syntax နှင့် မတူကွဲပြားပြီး `while` loop သည် condition တစ်ခုသာလိုအပ်သည်။ Condition သည် `false` ဖြစ်သောအခါ loop ကို ရပ်တန့်စေသည်။ Loop များတွင် condition များသည် counter ကဲ့သို့သော တန်ဖိုးများကို အခြေခံထားပြီး၊ loop အတွင်းတွင် စီမံခန့်ခွဲရမည်။ Counter များအတွက် starting value များကို loop အပြင်တွင် ဖန်တီးရမည်။ Condition ကို ဖြည့်ဆည်းရန် expression များကို loop အတွင်းတွင် ထိန်းသိမ်းရမည်။
```javascript
//Counting up to 10
@ -108,11 +108,11 @@ while (i < 10) {
}
```
✅ For loop နှင့် while loop ကို ဘာကြောင့် ရွေးချယ်ရမည်ဟု သင်ထင်ပါသလဲ? StackOverflow တွင် 17K ကြည့်ရှုသူများ၏ အမြင်များကို [ဖတ်ရှုနိုင်ပါသည်](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript)။
✅ For loop နှင့် while loop ကို ဘာကြောင့် ရွေးချယ်မည်ဆိုတာ သင်စဉ်းစားပါ။ StackOverflow တွင် 17,000 ကျော်သော viewers မေးမြန်းခဲ့ပြီး၊ [အမြင်အချို့](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript) သင်စိတ်ဝင်စားနိုင်သည်
## Loops နှင့် Arrays
Loops များသည် arrays နှင့် အတူ အသုံးပြုလေ့ရှိသည်။ အများဆုံး condition များသည် array ၏ length ကို loop ရပ်တန့်ရန် လိုအပ်ပြီး index ကို counter value အဖြစ် အသုံးပြုနိုင်သည်။
Arrays များသည် loops နှင့် အတူ အသုံးပြုလေ့ရှိသည်။ အများအားဖြင့် condition များသည် loop ကို ရပ်တန့်စေသော array ၏ length ကို လိုအပ်ပြီး၊ index သည် counter value ဖြစ်နိုင်သည်။
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
@ -128,14 +128,14 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
## 🚀 စိန်ခေါ်မှု
For နှင့် while loops များအပြင် arrays ကို loop လုပ်ရန် နည်းလမ်းများရှိသည်။ [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of), [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map) ကဲ့သို့သော နည်းလမ်းများကို အသုံးပြု၍ သင်၏ array loop ကို ပြန်ရေးပါ။
For နှင့် while loops များအပြင် arrays ကို loop လုပ်ရန် နည်းလမ်းများရှိသည်။ [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of), နှင့် [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map) တို့ဖြစ်သည်။ သင်၏ array loop ကို ဤနည်းလမ်းများထဲမှ တစ်ခုကို အသုံးပြုပြီး ပြန်ရေးပါ။
## မိန့်ခွန်းပြီးနောက် Quiz
## မိန့်ခွန်းပြီး Quiz
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/14)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်ပိုင်လေ့လာမှု
JavaScript တွင် arrays များသည် ဒေတာများကို စီမံခန့်ခွဲရန် အသုံးဝင်သော method များစွာပါရှိသည်။ [ဤ method များကို ဖတ်ရှုပါ](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)။ Push, pop, slice, splice ကဲ့သို့သော method များကို ကိုယ်ပိုင် array တွင် စမ်းသပ်ပါ။
JavaScript တွင် arrays များသည် ဒေတာကို စီမံခန့်ခွဲရန် အလွန်အသုံးဝင်သော methods များစွာပါရှိသည်။ [ဤ methods များကို ဖတ်ရှုပါ](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)၊ push, pop, slice, splice ကဲ့သို့သော methods များကို ကိုယ်ပိုင် array တစ်ခုတွင် စမ်းသပ်ပါ။
## အလုပ်ပေးစာ
@ -143,5 +143,5 @@ JavaScript တွင် arrays များသည် ဒေတာများက
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
**ဝက်ဘ်ဆိုက်မှတ်ချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှန်ကန်မှုအတွက် ကြိုးစားနေပါသော်လည်း၊ အလိုအလျောက်ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူလဘာသာစကားဖြင့် အာဏာတည်သောရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပြန်ဆိုမှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော နားလည်မှုမှားများ သို့မဟုတ် အဓိပ္ပာယ်မှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,85 +1,84 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "46a0639e719b9cf1dfd062aa24cad639",
"translation_date": "2025-08-27T22:35:33+00:00",
"original_hash": "89f7f9f800ce7c9f149e98baaae8491a",
"translation_date": "2025-08-28T18:43:36+00:00",
"source_file": "3-terrarium/1-intro-to-html/README.md",
"language_code": "my"
}
-->
# Terrarium Project Part 1: HTML ကိုမိတ်ဆက်ခြင်း
# Terrarium Project Part 1: HTML အကြောင်းအရာ
![Introduction to HTML](../../../../translated_images/webdev101-html.4389c2067af68e98280c1bde52b6c6269f399eaae3659b7c846018d8a7b0bbd9.my.png)
![HTML အကြောင်းအရာ](../../../../translated_images/webdev101-html.4389c2067af68e98280c1bde52b6c6269f399eaae3659b7c846018d8a7b0bbd9.my.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## မိန့်ခွန်းမတင်မီ Quiz
## မိန့်ခွန်းမတိုင်မီ စစ်ဆေးမေးခွန်း
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/15)
[မိန့်ခွန်းမတိုင်မီ စစ်ဆေးမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/15)
> ဗီဒီယိုကိုကြည့်ပါ
> ဗီဒီယိုကို ကြည့်ပါ
>
> [![Git and GitHub basics video](https://img.youtube.com/vi/1TvxJKBzhyQ/0.jpg)](https://www.youtube.com/watch?v=1TvxJKBzhyQ)
> [![Git နှင့် GitHub အခြေခံဗီဒီယို](https://img.youtube.com/vi/1TvxJKBzhyQ/0.jpg)](https://www.youtube.com/watch?v=1TvxJKBzhyQ)
### မိတ်ဆက
### အကျဉ်းချုပ
HTML, သို့မဟုတ် HyperText Markup Language, သည် ဝက်ဘ်၏ 'အရိုး' ဖြစ်သည်။ CSS သည် HTML ကို 'အလှဆင်' ပြုလုပ်ပေးပြီး JavaScript သည် အသက်သွင်းပေးသည်ဟုဆိုပါက HTML သည် သင့်ဝက်ဘ်အက်ပလီကေးရှင်း၏ ကိုယ်ခန္ဓာဖြစ်သည်။ HTML ၏ syntax သည် "head", "body", နှင့် "footer" တိုက်တန်းများပါဝင်သောကြောင့် အဆိုပါအယူအဆကိုပင် ရှင်းလင်းစွာဖော်ပြသည်။
HTML, သို့မဟုတ် HyperText Markup Language သည် ဝက်ဘ်၏ 'အရိုး' ဖြစ်သည်။ CSS သည် HTML ကို 'အလှဆင်' ပေးပြီး JavaScript သည် အသက်သွင်းပေးသည်ဟု ဆိုရမည်။ HTML သည် သင့်ဝက်ဘ်အက်ပလီကေးရှင်း၏ ကိုယ်ခန္ဓာဖြစ်သည်။ HTML ရဲ့ syntax ကလည်း အဲဒီအယူအဆကို ပြန်လည်ရိုက်ပြထားပြီး "head", "body", "footer" တို့ကို ထည့်သွင်းထားသည်။
ဒီသင်ခန်းစာမှာတော့ HTML ကိုအသုံးပြုပြီး သင့် virtual terrarium interface ၏ 'အရိုး' ကို layout ပြုလုပ်သွားမှာဖြစ်ပါတယ်။ အဆိုပါ interface တွင် ခေါင်းစဉ်တစ်ခုနှင့် သုံးခုတန်းရှိမည်ဖြစ်ပြီး- draggable plants တွေရှိတဲ့ ညာဘက်နှင့် ဘယ်ဘက်တန်းနှင့် အလယ်တန်းမှာတော့ အမှန်တကယ်သော ဖန်ပုံစံ terrarium ဖြစ်မည်။ ဒီသင်ခန်းစာအဆုံးမှာတော့ သင်သည် columns တွင် အပင်များကိုမြင်နိုင်မည်ဖြစ်သော်လည်း interface သည် အနည်းငယ်ထူးဆန်းနေမည်။ စိတ်မပူပါနဲ့၊ နောက်ဆုံးပိုင်းမှာ CSS styles တွေကို အသုံးပြုပြီး interface ကို ပိုမိုလှပအောင် ပြုလုပ်သွားမည်။
ဒီသင်ခန်းစာမှာတော့ HTML ကို အသုံးပြုပြီး သင့် virtual terrarium ရဲ့ interface ရဲ့ 'အရိုး' ကို ဖွဲ့စည်းသွားမှာဖြစ်ပါတယ်။ ဒီ interface မှာ ခေါင်းစဉ်တစ်ခုနဲ့ အတန်းသုံးခုပါမယ်။ ညာဘက်နဲ့ ဘယ်ဘက်အတန်းတွေမှာ draggable plants တွေရှိပြီး အလယ်မှာတော့ အမှန်တကယ်သော ဖန်ပုံစံ terrarium ဖြစ်မယ်။ ဒီသင်ခန်းစာအဆုံးမှာ သင့်အတန်းတွေမှာ အပင်တွေကို မြင်နိုင်ပါမယ်၊ ဒါပေမယ့် interface က အနည်းငယ် ထူးထူးဆန်းဆန်း ဖြစ်နေပါမယ်။ စိတ်မပူပါနဲ့၊ နောက်ပိုင်းမှာ CSS styles တွေကို ထည့်သွင်းပြီး interface ကို ပိုမိုလှပအောင် ပြင်ဆင်သွားမှာဖြစ်ပါတယ်။
### လုပ်ဆောင်ရန်
သင့်ကွန်ပျူတာတွင် 'terrarium' ဟုခေါ်သော folder တစ်ခုဖန်တီးပြီး ထို folder အတွင်း 'index.html' ဟုခေါ်သော ဖိုင်တစ်ခုဖန်တီးပါ။ သင်၏ terrarium folder ကို Visual Studio Code တွင်ဖွင့်ပြီး 'open folder' ကိုနှိပ်ကာ ဖိုင်အသစ်ကို Explorer pane တွင် ဖန်တီးနိုင်ပါသည်
သင့်ကွန်ပျူတာမှာ 'terrarium' folder တစ်ခုဖန်တီးပြီး အဲဒီ folder အတွင်းမှာ 'index.html' ဖိုင်တစ်ခု ဖန်တီးပါ။ Visual Studio Code မှာ terrarium folder ကို ဖန်တီးပြီးနောက် VS Code window အသစ်ကို ဖွင့်ပြီး 'open folder' ကို နှိပ်ပါ၊ သင့် folder အသစ်ကို ရွေးချယ်ပါ။ Explorer pane မှာ 'file' ခလုတ်ကို နှိပ်ပြီး ဖိုင်အသစ်ကို ဖန်တီးပါ
![explorer in VS Code](../../../../translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.my.png)
![VS Code မှာ explorer](../../../../translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.my.png)
သို့မဟုတ်
git bash တွင် အောက်ပါ command များကို အသုံးပြုပါ:
git bash မှာ အောက်ပါ command တွေကို အသုံးပြုပါ:
* `mkdir terrarium`
* `cd terrarium`
* `touch index.html`
* `code index.html` or `nano index.html`
> index.html ဖိုင်များသည် browser ကို folder ၏ default ဖိုင်ဖြစ်ကြောင်းပြောပြသည်။ ဥပမာ `https://anysite.com/test` URL သည် `test` folder နှင့် `index.html` ဖိုင်ကို အသုံးပြု၍ ဖွဲ့စည်းထားနိုင်သည်။ `index.html` သည် URL တွင် မပေါ်လွင်လည်း ရနိုင်သည်။
> index.html ဖိုင်တွေက browser ကို folder ရဲ့ default ဖိုင်ဖြစ်ကြောင်း ပြောပြပေးပါတယ်။ ဥပမာ `https://anysite.com/test` ဆိုရင် test folder ရဲ့ အတွင်းမှာ `index.html` ဖိုင်ရှိနိုင်ပါတယ်။ `index.html` ကို URL မှာ မဖော်ပြရင်လည်း ရပါတယ်။
---
## DocType နှင့် html tags
HTML ဖိုင်၏ ပထမဆုံးလိုင်းသည် DocType ဖြစ်သည်။ အဆိုပါလိုင်းကို ဖိုင်၏ အပေါ်ဆုံးတွင် ထည့်ရန်လိုအပ်သည်။ အဟောင်း browser များကို page ကို လက်ရှိ HTML specification အတိုင်း render ပြုလုပ်ရန် ပြောပြသည်။
HTML ဖိုင်ရဲ့ ပထမဆုံးလိုင်းက DocType ဖြစ်ပါတယ်။ ဒီလိုင်းကို ဖိုင်ရဲ့ အပေါ်ဆုံးမှာ ထည့်သွင်းဖို့ လိုအပ်ပါတယ်။ ဒါက browser ကို page ကို standard mode မှာ render လုပ်ဖို့ ပြောပြပေးပါတယ်၊ အခု html specification ကို လိုက်နာဖို့ ဖြစ်ပါတယ်။
> အကြံပြုချက်- VS Code တွင် tag အပေါ်တွင် hover ပြုလုပ်ပါက MDN Reference guide မှ tag ၏ အသုံးအများကို ကြည့်နိုင်သည်။
> အကြံပြုချက်: VS Code မှာ tag ကို hover လုပ်ပြီး MDN Reference guide မှာ tag ရဲ့ အသုံးအနှုန်းကို ကြည့်နိုင်ပါတယ်။
ဒုတိယလိုင်းတွင် `<html>` tag ၏ ဖွင့်လှစ် tag ကို ထည့်ပြီး `</html>` tag ဖြင့် ပိတ်ထားရမည်။ အဆိုပါ tags များသည် သင့် interface ၏ root elements ဖြစ်သည်။
ဒုတိယလိုင်းမှာ `<html>` tag ရဲ့ ဖွင့်လှစ် tag ကို ထည့်သွင်းပြီး အခုအချိန်မှာတော့ `</html>` ဆိုတဲ့ ပိတ်သွားတဲ့ tag ကို ထည့်သွင်းပါ။ ဒီ tag တွေက သင့် interface ရဲ့ root elements ဖြစ်ပါတယ်။
### လုပ်ဆောင်ရန်
သင့် `index.html` ဖိုင်၏ အပေါ်ဆုံးတွင် အောက်ပါလိုင်းများကို ထည့်ပါ:
သင့် `index.html` ဖိုင်ရဲ့ အပေါ်ဆုံးမှာ အောက်ပါလိုင်းတွေကို ထည့်သွင်းပါ:
```HTML
<!DOCTYPE html>
<html></html>
```
✅ DocType ကို query string ဖြင့် mode များကို သတ်မှတ်နိုင်သည်။ [Quirks Mode and Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode) ကို ဖတ်ပါ။ အဟောင်း browser များကို အထောက်အပံ့ပေးရန် mode များကို အသုံးပြုခဲ့သည်။ ယနေ့တွင် Netscape Navigator 4 နှင့် Internet Explorer 5 ကဲ့သို့သော browser များကို မသုံးတော့ပါ။ သင်သည် standard doctype declaration ကို အသုံးပြုနိုင်သည်။
✅ DocType ကို query string ဖြင့် သတ်မှတ်ခြင်းအားဖြင့် mode အမျိုးမျိုးကို သတ်မှတ်နိုင်ပါတယ်။ [Quirks Mode နှင့် Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode) ကို ဖတ်ရှုပါ။ ဒီ mode တွေက အရမ်းဟောင်းနေတဲ့ browser တွေကို ပံ့ပိုးပေးဖို့ ဖြစ်ပါတယ် (ဥပမာ Netscape Navigator 4 နှင့် Internet Explorer 5)။ သင်တော့ standard doctype declaration ကို အသုံးပြုနိုင်ပါတယ်။
---
## document ၏ 'head'
## ဖိုင်ရဲ့ 'head'
HTML document ၏ 'head' အပိုင်းတွင် သင့်ဝက်ဘ်ပေ့ဂျ်အကြောင်း အရေးကြီးသော အချက်အလက်များ (metadata) ပါဝင်သည်။ ဥပမာအားဖြင့်:
HTML ဖိုင်ရဲ့ 'head' အပိုင်းမှာ သင့်ဝက်ဘ်ပေ့ဂျ်အကြောင်း အရေးကြီးသော အချက်အလက်များ (metadata) ပါဝင်ပါတယ်။ ဥပမာ [metadata](https://developer.mozilla.org/docs/Web/HTML/Element/meta) တွေပါဝင်ပါတယ်။ ဒီအပိုင်းမှာတော့ ဝက်ဘ် server ကို အောက်ပါအချက်လက် ၄ ခုကို ပြောပြပေးပါတယ်။
- ပေ့ဂျ် ခေါင်းစဉ်
- ပေ့ဂျ်ရဲ့ ခေါင်းစဉ်
- metadata အချက်အလက်များ:
- 'character set' သည် page တွင် အသုံးပြုထားသော character encoding ကို ပြောပြသည်။
- browser အချက်အလက်များ `x-ua-compatible` သည် IE=edge browser ကို အထောက်အပံ့ပေးသည်
- viewport သည် page ကို load လုပ်သောအခါ ဘယ်လိုပြုမည်ကို ပြောပြသည်။ viewport ကို initial scale of 1 သတ်မှတ်ခြင်းသည် ပေ့ဂျ်ကို ပထမဆုံး load လုပ်သောအခါ zoom level ကို ထိန်းချုပ်သည်
- 'character set' - ပေ့ဂျ်မှာ အသုံးပြုထားတဲ့ character encoding
- browser အချက်အလက်များ - `x-ua-compatible` သည် IE=edge browser ကို ပံ့ပိုးပေးသည်
- viewport ရဲ့ အစောပိုင်း scale ကို သတ်မှတ်ခြင်း - ပေ့ဂျ်ကို ပထမဆုံးဖွင့်တဲ့အခါ zoom level ကို ထိန်းချုပ်ပေးသည်
### လုပ်ဆောင်ရန်
ဖွင့်လှစ် `<html>` tag နှင့် ပိတ်ထားသော `</html>` tag အကြားတွင် 'head' block ကို ထည့်ပါ။
ဖွင့်လှစ် `<html>` tag နှင့် ပိတ်သွားတဲ့ `<html>` tag အကြားမှာ 'head' block ကို ထည့်သွင်းပါ။
```html
<head>
@ -90,15 +89,15 @@ HTML document ၏ 'head' အပိုင်းတွင် သင့်ဝက်
</head>
```
`<meta name="viewport" content="width=600">` ကဲ့သို့ viewport meta tag ကို သတ်မှတ်ပါက ဘာဖြစ်မည်ကို စဉ်းစားပါ။ [viewport](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag) ကို ဖတ်ပါ။
`<meta name="viewport" content="width=600">` ဆိုတဲ့ viewport meta tag ကို သတ်မှတ်ရင် ဘာဖြစ်မလဲ? [viewport](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag) အကြောင်းကို ဖတ်ရှုပါ။
---
## document ၏ `body`
## ဖိုင်ရဲ့ `body`
### HTML Tags
HTML တွင် tag များကို သင့် .html ဖိုင်တွင် ထည့်ကာ ဝက်ဘ်ပေ့ဂျ်၏ elements များကို ဖန်တီးသည်။ tag တစ်ခုစီတွင် ဖွင့်လှစ် tag နှင့် ပိတ်ထားသော tag ရှိသည်။ ဥပမာ `<p>hello</p>` သည် paragraph ကို ဖော်ပြသည်။ `<body>` tag များကို `<html>` tag pair အတွင်း ထည့်ကာ interface ၏ body ကို ဖန်တီးပါ
HTML မှာ tag တွေကို သင့် .html ဖိုင်မှာ ထည့်သွင်းပြီး ဝက်ဘ်ပေ့ဂျ်ရဲ့ elements တွေကို ဖန်တီးနိုင်ပါတယ်။ tag တစ်ခုစီမှာ ဖွင့်လှစ် tag နဲ့ ပိတ်သွားတဲ့ tag ရှိတတ်ပါတယ်၊ ဥပမာ `<p>hello</p>` ဆိုရင် paragraph ကို ဖော်ပြပါတယ်။ သင့် interface ရဲ့ body ကို ဖွင့်လှစ် `<body>` tag တွေကို `<html>` tag တွေထဲမှာ ထည့်သွင်းပါ။ သင့် markup က အခုလို ဖြစ်နေပါမယ်
### လုပ်ဆောင်ရန်
@ -115,17 +114,17 @@ HTML တွင် tag များကို သင့် .html ဖိုင်
</html>
```
ယခု သင်သည် သင့်ပေ့ဂျ်ကို ဖန်တီးနိုင်ပါပြီ။ ပုံမှန်အားဖြင့် `<div>` tag များကို အသုံးပြုကာ ပေ့ဂျ်၏ အပိုင်းများကို ဖန်တီးသည်။ `<div>` element များကို ဖန်တီးပြီး images များကို ထည့်ပါ
အခု သင့်ပေ့ဂျ်ကို ဖန်တီးဖို့ စတင်နိုင်ပါပြီ။ ပုံမှန်အားဖြင့် `<div>` tag တွေကို အသုံးပြုပြီး ပေ့ဂျ်ရဲ့ အပိုင်းအစတွေကို ဖန်တီးပါတယ်။ အခုတော့ `<div>` element တွေကို ဖန်တီးပြီး အဲဒီအတွင်းမှာ ပုံတွေကို ထည့်သွင်းပါမယ်
### Images
### ပုံများ
ပိတ်ထားသော tag မလိုအပ်သော HTML tag တစ်ခုမှာ `<img>` tag ဖြစ်သည်။ အဆိုပါ tag တွင် `src` element ပါဝင်ပြီး page ကို render ပြုလုပ်ရန် လိုအပ်သော အချက်အလက်များကို ပေးသည်။
ပိတ်သွားတဲ့ tag မလိုအပ်တဲ့ HTML tag တစ်ခုက `<img>` tag ဖြစ်ပါတယ်၊ အဲဒီ tag ရဲ့ `src` element က ပေ့ဂျ်ကို item ကို render လုပ်ဖို့ လိုအပ်တဲ့ အချက်အလက်အားလုံးကို ပေးပါတယ်။
သင့် app တွင် `images` folder တစ်ခုဖန်တီးပြီး [source code folder](../../../../3-terrarium/solution/images) တွင်ရှိသော အပင်ပုံများ (14 ပုံ) ကို ထည့်ပါ။
သင့် app မှာ `images` folder တစ်ခု ဖန်တီးပြီး [source code folder](../../../../3-terrarium/solution/images) မှာရှိတဲ့ ပုံတွေကို ထည့်သွင်းပါ။ (အပင်ပုံ ၁၄ ခုရှိပါတယ်)
### လုပ်ဆောင်ရန်
အပင်ပုံများကို `<body></body>` tag များအတွင်းရှိ columns နှစ်ခုတွင် ထည့်ပါ:
အပင်ပုံတွေကို `<body></body>` tag တွေကြားမှာ အတန်းနှစ်ခုအတွင်း ထည့်သွင်းပါ:
```html
<div id="page">
@ -178,37 +177,37 @@ HTML တွင် tag များကို သင့် .html ဖိုင်
</div>
```
> မှတ်ချက်- Spans နှင့် Divs. Divs သည် 'block' elements ဖြစ်ပြီး Spans သည် 'inline' ဖြစ်သည်။ Divs များကို Spans သို့ ပြောင်းလဲပါက ဘာဖြစ်မည်ကို စဉ်းစားပါ။
> မှတ်ချက်: Spans နှင့် Divs. Divs တွေကို 'block' elements အဖြစ် သတ်မှတ်ပြီး Spans တွေကို 'inline' elements အဖြစ် သတ်မှတ်ပါတယ်။ ဒီ divs တွေကို spans တွေပြောင်းလဲရင် ဘာဖြစ်မလဲ?
ဤ markup ဖြင့် အပင်များသည် screen ပေါ်တွင် ပြသမည်။ သို့သော် CSS ဖြင့် style မပြုလုပ်သေးသောကြောင့် အလှမရှိသေးပါ။ CSS ကို နောက်ဆုံးပိုင်းတွင် သင်ယူမည်။
ဒီ markup နဲ့ အပင်တွေကို screen ပေါ်မှာ မြင်နိုင်ပါပြီ။ ဒါပေမယ့် CSS နဲ့ style မလုပ်သေးလို့ အရမ်းမလှပသေးပါဘူး။ CSS ကို နောက်သင်ခန်းစာမှာ ထည့်သွင်းပါမယ်။
image တစ်ခုစီတွင် alt text ပါဝင်ပြီး image ကို မမြင်နိုင်ပါက ထို alt text ကို ပြသမည်။ accessibility အတွက် အရေးကြီး attribute ဖြစ်သည်။ accessibility အကြောင်းကို နောက်ဆုံးပိုင်းတွင် သင်ယူပါမည်။ အခုတော့ alt attribute သည် image ကို မမြင်နိုင်သောအခါ alternative အချက်အလက်ကို ပေးသည်ဟု သိထားပါ။
ပုံတစ်ခုစီမှာ alt text ပါဝင်ပြီး ပုံကို မမြင်နိုင်တဲ့အခါမှာပင် alt text ကို မြင်နိုင်ပါတယ်။ ဒီ attribute ကို accessibility အတွက် ထည့်သွင်းဖို့ အရေးကြီးပါတယ်။ accessibility အကြောင်းကို နောက်သင်ခန်းစာတွေမှာ ပိုမိုလေ့လာနိုင်ပါတယ်။ အခုတော့ alt attribute က ပုံကို မမြင်နိုင်တဲ့အခါမှာ alternative အချက်အလက်ကို ပေးစွမ်းပေးတယ်ဆိုတာ သတိထားပါ။
image တစ်ခုစီတွင် တူညီသော alt tag ရှိသည်ကို သတိပြုပါ။ ဤအလေ့အထသည် ကောင်းပါသလား? အဘယ်ကြောင့်? ဤ code ကို တိုးတက်အောင် ပြုလုပ်နိုင်ပါသလား?
ပုံတစ်ခုစီမှာ alt tag တူညီနေတယ်ဆိုတာ သတိထားမိပါသလား? ဒီဟာက အကောင်းဆုံးလေ့ကျင့်မှုလား? ဘာကြောင့်လဲ? ဒီ code ကို ပိုမိုကောင်းမွန်အောင် ပြင်ဆင်နိုင်မလား?
---
## Semantic markup
HTML ရေးသားရာတွင် အဓိပ္ပာယ်ရှိသော 'semantics' ကို အသုံးပြုရန် အကြံပြုသည်။ ၎င်းသည် data သို့မဟုတ် interaction ၏ အမျိုးအစားကို ကိုယ်စားပြုရန် ရည်ရွယ်ထားသော HTML tag များကို အသုံးပြုခြင်းဖြစ်သည်။ ဥပမာအားဖြင့် ပေ့ဂျ်၏ အဓိကခေါင်းစဉ် text သည် `<h1>` tag ကို အသုံးပြုသင့်သည်။
အထွေထွေအားဖြင့် HTML ရေးသားတဲ့အခါမှာ အဓိပ္ပာယ်ရှိတဲ့ 'semantics' ကို အသုံးပြုဖို့ ပိုမိုကောင်းမွန်ပါတယ်။ အဓိပ္ပာယ်ရှိတဲ့ semantics ဆိုတာ ဘာလဲ? ဒါက HTML tag တွေကို သူတို့ရဲ့ data အမျိုးအစား သို့မဟုတ် interaction အမျိုးအစားအတွက် ဖန်တီးထားတဲ့အတိုင်း အသုံးပြုဖို့ ဖြစ်ပါတယ်။ ဥပမာ အဓိကခေါင်းစဉ် text ကို `<h1>` tag ကို အသုံးပြုသင့်ပါတယ်။
ဖွင့်လှစ် `<body>` tag ၏ အောက်တွင် အောက်ပါလိုင်းကို ထည့်ပါ:
ဖွင့်လှစ် `<body>` tag ရဲ့ အောက်မှာ အောက်ပါလိုင်းကို ထည့်သွင်းပါ:
```html
<h1>My Terrarium</h1>
```
semantic markup ကို အသုံးပြုခြင်းသည် screen reader များအတွက် ပေ့ဂျ်ကို navigation ပြုလုပ်ရန် အထောက်အပံ့ပေးသည်။ ဥပမာအားဖြင့် button များကို `<button>` နှင့် list များကို `<li>` ဖြင့် ရေးသားသင့်သည်။ specially styled `<span>` element များကို click handler ဖြင့် button အဖြစ် mock ပြုလုပ်နိုင်သော်လည်း disabled user များအတွက် button ရှိရာကို ရှာဖွေရန်နှင့် interaction ပြုလုပ်ရန် ပိုမိုလွယ်ကူသည်။ ထို့ကြောင့် semantic markup ကို အမြဲအသုံးပြုရန် ကြိုးစားပါ။
Semantic markup ကို အသုံးပြုခြင်း (ဥပမာ header တွေကို `<h1>` သုံးခြင်း၊ unordered lists တွေကို `<ul>` သုံးခြင်း) က screen reader တွေကို ဝက်ဘ်ပေ့ဂျ်တစ်ခုကို navigation လုပ်ဖို့ အကူအညီပေးပါတယ်။ ပုံမှန်အားဖြင့် button တွေကို `<button>` သုံးပြီး lists တွေကို `<li>` သုံးသင့်ပါတယ်။ `<span>` element တွေကို specially styled click handler တွေဖြင့် button အဖြစ် mock လုပ်နိုင်ပေမယ့် disabled user တွေက button ရှိတဲ့နေရာကို ဖော်ထုတ်ဖို့ နည်းပညာတွေကို အသုံးပြုနိုင်ဖို့ `<button>` element ကို သုံးသင့်ပါတယ်။ ဒီအကြောင်းကြောင့် semantic markup ကို အမြဲအသုံးပြုဖို့ ကြိုးစားပါ။
screen reader [ဘယ်လို ဝက်ဘ်ပေ့ဂျ်နှင့် interaction ပြုလုပ်သည်ကို](https://www.youtube.com/watch?v=OUDV1gqs9GA) ကြည့်ပါ။ semantic markup မရှိပါက user အတွက် အခက်အခဲဖြစ်နိုင်ကြောင်း မြင်နိုင်ပါသလား?
Screen reader တစ်ခုကို ကြည့်ပြီး [ဝက်ဘ်ပေ့ဂျ်တစ်ခုနဲ့ ဘယ်လို interaction လုပ်သလဲ](https://www.youtube.com/watch?v=OUDV1gqs9GA) ကို ကြည့်ပါ။ Non semantic markup ရေးသားခြင်းက user ကို ဘာကြောင့် စိတ်ညစ်စေမလဲ?
## Terrarium
ဤ interface ၏ နောက်ဆုံးအပိုင်းတွင် terrarium ကို ဖန်တီးရန် style ပြုလုပ်မည့် markup ကို ဖန်တီးပါမည်။
ဒီ interface ရဲ့ နောက်ဆုံးအပိုင်းမှာ terrarium ကို ဖန်တီးဖို့ style လုပ်မယ့် markup ကို ဖန်တီးပါမယ်။
### လုပ်ဆောင်ရန်:
နောက်ဆုံး `</div>` tag အပေါ်တွင် အောက်ပါ markup ကို ထည့်ပါ:
နောက်ဆုံး `</div>` tag ရဲ့ အပေါ်မှာ အောက်ပါ markup ကို ထည့်သွင်းပါ:
```html
<div id="terrarium">
@ -222,29 +221,29 @@ semantic markup ကို အသုံးပြုခြင်းသည် scree
</div>
```
markup ကို screen ပေါ်တွင် ထည့်ထားသော်လည်း render မဖြစ်သောကြောင့် ဘာဖြစ်မည်ကို စဉ်းစားပါ။
ဒီ markup ကို screen ပေါ်မှာ ထည့်သွင်းပြီးနောက် ဘာမှ မမြင်ရဘူးဆိုတာ သတိထားမိပါသလား? ဘာကြောင့်လဲ?
---
## 🚀Challenge
## 🚀စိန်ခေါ်မှု
HTML တွင် 'အဟောင်း' tag များရှိပြီး အချို့သည် စိတ်ဝင်စားဖွယ်ကောင်းသည်။ သို့သော် [deprecated tag များ](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) ကို မသုံးသင့်ပါ။ `<marquee>` tag ကို အသုံးပြုပြီး h1 ခေါင်းစဉ်ကို အလျားလိုက် scroll ပြုလုပ်နိုင်ပါသလား? (ပြုလုပ်ပါက နောက်ဆုံးတွင် ဖယ်ရှားရန် မမေ့ပါနှင့်)
HTML မှာ 'ဟောင်း' tag တွေရှိပြီး အခုထိ စမ်းသပ်ဖို့ အရမ်းစိတ်ဝင်စားစရာကောင်းပါတယ်၊ သို့သော် [ဒီ tag တွေ](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) ကဲ့သို့ deprecated tag တွေကို သင့် markup မှာ မသုံးသင့်ပါ။ သို့သော် `<marquee>` tag ကို အသုံးပြုပြီး h1 ခေါင်းစဉ်ကို အလျားလိုက် scroll လုပ်နိုင်မလား? (သုံးပြီးနောက်မှာ tag ကို ဖယ်ရှားဖို့ မမေ့ပါနဲ့)
## မိန့်ခွန်းပြီး Quiz
## မိန့်ခွန်းပြီးနောက် စစ်ဆေးမေးခွန်း
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/16)
[မိန့်ခွန်းပြီးနောက် စစ်ဆေးမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/16)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
HTML သည် ဝက်ဘ်ကို ယနေ့အထိ တိုးတက်စေခဲ့သော 'စမ်းသပ်ပြီးအောင်မြင်သော' အဆောက်အအုံစနစ်ဖြစ်သည်။ အဟောင်းနှင့် အသစ် tag များကို လေ့လာကာ ၎င်း၏ သမိုင်းကို သိပါ။ အချို့ tag များကို အဘယ်ကြောင့် deprecated ဖြစ်ခဲ့ပြီး အချို့ကို ထည့်သွင်းခဲ့သည်ကို သိနိုင်ပါသလား? အနာဂတ်တွင် tag များကို ထည့်သွင်းနိုင်မည်ကို စဉ်းစားပါ။
HTML သည် ဝက်ဘ်ကို ယနေ့အထိ ဖွံ့ဖြိုးတိုးတက်စေတဲ့ 'ယုံကြည်စိတ်ချရသော' အဆောက်အအုံစနစ်ဖြစ်သည်။ tag ဟောင်းများနှင့် အသစ်များကို လေ့လာခြင်းအားဖြင့် သမိုင်းအကြောင်းကို သိရှိပါ။ ဘာကြောင့် tag တစ်ချို့ကို deprecated လုပ်ပြီး တစ်ချို့ကို ထည့်သွင်းခဲ့တာလဲ? အနာဂတ်မှာ ဘယ် tag တွေကို ထည့်သွင်းနိုင်မလဲ?
ဝက်ဘ်နှင့် မိုဘိုင်း device များအတွက် site များကို ဖန်တီးခြင်းအကြောင်း [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon) တွင် လေ့လာပါ။
ဝက်ဘ်နှင့် မိုဘိုင်းစက်များအတွက် site တွေ ဖန်တီးခြင်းအကြောင်းကို [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon) မှာ ပိုမိုလေ့လာပါ။
## လုပ်ငန်း
## လုပ်ငန်းတာဝန်
[သင HTML ကိုလေ့ကျင့်ပါ: Blog mockup တစ်ခုကို ဖန်တီးပါ](assignment.md)
[သင် HTML ကို လေ့ကျင့်ပါ: Blog mockup တစ်ခု ဖန်တီးပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေပါသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွဲအချော်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
**ဝက်ဘ်ဆိုက်မှတ်ချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှန်ကန်မှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက်ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်ကြောင်း သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူလဘာသာစကားဖြင့် အာဏာတည်သောရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပြန်ဆိုမှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော နားလည်မှုမှားများ သို့မဟုတ် အဓိပ္ပါယ်မှားများအတွက် ကျွန်ုပ်တို့ တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e375c2aeb94e2407f2667633d39580bd",
"translation_date": "2025-08-27T22:37:24+00:00",
"original_hash": "acb5ae00cde004304296bb97da8ff4c3",
"translation_date": "2025-08-28T18:44:18+00:00",
"source_file": "3-terrarium/2-intro-to-css/README.md",
"language_code": "my"
}
@ -10,32 +10,32 @@ CO_OP_TRANSLATOR_METADATA:
# Terrarium Project Part 2: CSS ကိုမိတ်ဆက်ခြင်း
![Introduction to CSS](../../../../translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.my.png)
> [Tomomi Imura](https://twitter.com/girlie_mac) ၏ Sketchnote
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## မိန့်ခွန်းမတင်မီ စစ်ဆေးမှု
## မိန့်ခွန်းမတင်မီ စမ်းမေးခွန်း
[မိန့်ခွန်းမတင်မီ စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/17)
[မိန့်ခွန်းမတင်မီ စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/17)
### မိတ်ဆက်
CSS, သို့မဟုတ် Cascading Style Sheets သည် ဝဘ်ဆိုင်ရာ ဖွံ့ဖြိုးတိုးတက်မှုတွင် အရေးကြီးသော ပြဿနာတစ်ခုဖြစ်သည့် ဝဘ်ဆိုဒ်ကို လှပစေရန် ပြဿနာကို ဖြေရှင်းပေးသည်။ သင့်အက်ပ်များကို အဆင်ပြေစေရန်နှင့် လှပစေရန် CSS ကို အသုံးပြုနိုင်သလို၊ Responsive Web Design (RWD) ကို ဖန်တီးရန်လည်း အသုံးပြုနိုင်သည်။ RWD သည် မည်သည့် မျက်နှာပြင်အရွယ်အစားတွင် မဆို သင့်အက်ပ်များကို သင့်တော်စွာ ပြသနိုင်စေသည်။ CSS သည် သင့်အက်ပ်ကို လှပစေရန်သာမက၊ အလှပြင်များနှင့် ပြောင်းလဲမှုများကိုလည်း ထည့်သွင်းထားပြီး သင့်အက်ပ်များအတွက် ရှုပ်ထွေးသော အပြန်အလှန်ဆက်သွယ်မှုများကို ဖန်တီးနိုင်စေသည်။ CSS Working Group သည် လက်ရှိ CSS သတ်မှတ်ချက်များကို ထိန်းသိမ်းပေးနေပြီး၊ [World Wide Web Consortium's site](https://www.w3.org/Style/CSS/members) တွင် သူတို့၏ အလုပ်များကို လိုက်နာကြည့်ရှုနိုင်သည်။
CSS, သို့မဟုတ် Cascading Style Sheets သည် ဝဘ်ဖွံ့ဖြိုးရေးတွင် အရေးကြီးသော ပြဿနာတစ်ခုဖြစ်သည့် ဝဘ်ဆိုဒ်ကို လှပစေခြင်းကို ဖြေရှင်းပေးသည်။ သင့်အက်ပ်များကို အဆင်ပြေစေပြီး လှပစေခြင်းအပြင် CSS ကို အသုံးပြု၍ Responsive Web Design (RWD) ကို ဖန်တီးနိုင်သည်။ ဒါကြောင့် မည်သည့် မျက်နှာပြင်အရွယ်အစားတွင် ပြသထားပါက အက်ပ်များကို လှပစေပါသည်။ CSS သည် သင့်အက်ပ်ကို လှပစေခြင်းအတွက်သာမက၊ အနုစိတ်အပြောင်းအလဲများနှင့် အပြောင်းအလဲများကိုပါ ဖန်တီးနိုင်စေသော animation နှင့် transform များပါဝင်သည်။ CSS Working Group သည် လက်ရှိ CSS သတ်မှတ်ချက်များကို ထိန်းသိမ်းပေးသည်။ သူတို့၏အလုပ်ကို [World Wide Web Consortium's site](https://www.w3.org/Style/CSS/members) တွင် လိုက်နာကြည့်ရှုနိုင်သည်။
> မှတ်ချက် - CSS သည် ဝဘ်ပေါ်ရှိ အရာအားလုံးကဲ့သို့ တိုးတက်ပြောင်းလဲနေသော ဘာသာစကားဖြစ်ပြီး၊ ဘရောက်ဇာအားလုံးက သတ်မှတ်ချက်၏ အသစ်သော အပိုင်းများကို မထောက်ပံ့နိုင်ပါ။ သင့်အကောင်အထည်ဖော်မှုများကို [CanIUse.com](https://caniuse.com) ကို ကြည့်ရှုခြင်းဖြင့် အမြဲစစ်ဆေးပါ။
> [!NOTE] CSS သည် ဝဘ်ပေါ်ရှိ အရာအားလုံးကဲ့သို့ တိုးတက်ပြောင်းလဲနေသော ဘာသာစကားတစ်ခုဖြစ်ပြီး၊ ဘရောက်ဇာအားလုံးသည် သတ်မှတ်ချက်၏ အသစ်သော အပိုင်းများကို မထောက်ပံ့နိုင်ပါ။ သင့်အကောင်အထည်ဖော်မှုများကို [CanIUse.com](https://caniuse.com) ကို ကိုးကား၍ အမြဲစစ်ဆေးပါ။
ဒီသင်ခန်းစာတွင်၊ ကျွန်ုပ်တို့သည် CSS ၏ အခြေခံအယူအဆများဖြစ်သည့် cascade, inheritance, selector များ၏ အသုံးပြုမှု၊ positioning နှင့် layout ဖန်တီးမှုတို့ကို လေ့လာပြီး၊ သင့်အွန်လိုင်း terrarium ကို အလှဆင်သွားမည်ဖြစ်သည်။ ဒီလုပ်ငန်းစဉ်အတွင်း ကျွန်ုပ်တို့သည် terrarium ကို layout ပြုလုပ်ပြီး အမှန်တကယ်သော terrarium ကို ဖန်တီးသွားမည်ဖြစ်သည်။
ဒီသင်ခန်းစာတွင်၊ ကျွန်ုပ်တို့၏ အွန်လိုင်း terrarium ကို အလှဆင်ပြီး CSS ၏ အဓိကအချက်အချာများဖြစ်သည့် cascade, inheritance, selector များ၏ အသုံးပြုမှု၊ positioning နှင့် layout ဖန်တီးခြင်းတို့ကို လေ့လာသွားမည်ဖြစ်သည်။ ဒီလုပ်ငန်းစဉ်အတွင်း ကျွန်ုပ်တို့သည် terrarium ကို layout ပြုလုပ်ပြီး အမှန်တကယ်သော terrarium ကို ဖန်တီးသွားမည်ဖြစ်သည်။
### ကြိုတင်လိုအပ်ချက်
သင့် terrarium အတွက် HTML ကို ဖန်တီးပြီး အလှဆင်ရန် အသင့်ဖြစ်ထားရမည်။
သင့် terrarium အတွက် HTML ကို ဖန်တီးပြီး အလှဆင်ရန် အသင့်ဖြစ်ထားရမည်။
> ဗီဒီယိုကြည့်ရန်
>
> [![Git နှင့် GitHub အခြေခံဗီဒီယို](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I)
> [![Git and GitHub basics video](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I)
### လုပ်ငန်း
သင့် terrarium ဖိုလ်ဒါတွင် `style.css` ဟုခေါ်သော ဖိုင်အသစ်တစ်ခု ဖန်တီးပါ။ ထိုဖိုင်ကို `<head>` အပိုင်းတွင် ထည့်သွင်းပါ-
သင့် terrarium ဖိုလ်ဒါတွင် `style.css` ဟုခေါ်သော ဖိုင်အသစ်တစ်ခု ဖန်တီးပါ။ အဆိုပါဖိုင်ကို `<head>` အပိုင်းတွင် import ပြုလုပ်ပါ-
```html
<link rel="stylesheet" href="./style.css" />
@ -45,17 +45,17 @@ CSS, သို့မဟုတ် Cascading Style Sheets သည် ဝဘ်ဆ
## The Cascade
Cascading Style Sheets တွင် "cascade" ဆိုသော အယူအဆကို ထည့်သွင်းထားပြီး၊ အလှဆင်မှုတစ်ခု၏ အဓိကကျမှုအလိုက် အလှဆင်မှုကို လိုက်နာသည်။ ဝဘ်ဆိုဒ်ရေးသားသူက သတ်မှတ်ထားသော အလှဆင်မှုများသည် ဘရောက်ဇာက သတ်မှတ်ထားသော အလှဆင်မှုများထက် အဓိကကျသည်။ External style sheet တွင် သတ်မှတ်ထားသော အလှဆင်မှုများထက် inline style များသည် ပိုမိုအဓိကကျသည်။
Cascading Style Sheets တွင် 'cascade' ဆိုသော အယူအဆပါဝင်ပြီး၊ style များကို အသုံးချရာတွင် ဦးစားပေးမှုအလိုက် လမ်းညွှန်ပေးသည်။ ဝဘ်ဆိုဒ်ရေးသားသူမှ သတ်မှတ်ထားသော style များသည် ဘရောက်ဇာမှ သတ်မှတ်ထားသော style များထက် ဦးစားပေးသည်။ 'inline' မှ သတ်မှတ်ထားသော style များသည် အပြင်ပန်း style sheet တွင် သတ်မှတ်ထားသော style များထက် ဦးစားပေးသည်။
### လုပ်ငန်း
သင့် `<h1>` tag တွင် "color: red" inline style ကို ထည့်သွင်းပါ-
သင့် `<h1>` tag တွင် "color: red" inline style ကို ထည့်ပါ-
```HTML
<h1 style="color: red">My Terrarium</h1>
```
ထို့နောက်၊ သင့် `style.css` ဖိုင်တွင် အောက်ပါကုဒ်ကို ထည့်သွင်းပါ-
ထို့နောက်၊ သင့် `style.css` ဖိုင်တွင် အောက်ပါကုဒ်ကို ထည့်ပါ-
```CSS
h1 {
@ -63,13 +63,13 @@ h1 {
}
```
✅ သင့်ဝဘ်အက်ပ်တွင် မည်သည့်အရောင်ကို ပြသနေသနည်း။ အဘယ်ကြောင့်လဲ။ အလှဆင်မှုများကို override ပြုလုပ်နိုင်မည့် နည်းလမ်းကို ရှာဖွေပါ။ သင်သည် မည်သည့်အချိန်တွင် ဒါကို ပြုလုပ်လိုမည်နည်း၊ သို့မဟုတ် မပြုလုပ်သင့်သည့် အကြောင်းရင်းများကို ရှာဖွေပါ။
✅ သင့်ဝဘ်အက်ပ်တွင် မည်သည့်အရောင်ကို ပြသပါသလဲ? အဘယ်ကြောင့်? Style များကို override ပြုလုပ်နိုင်သော နည်းလမ်းတစ်ခု ရှာနိုင်ပါသလား? ဘယ်အချိန်တွင် ဒါကို ပြုလုပ်လိုမည်၊ သို့မဟုတ် မပြုလုပ်သင့်ပါသလဲ?
---
## Inheritance
Styles များသည် မိဘအလှဆင်မှုမှ သားအလှဆင်မှုသို့ အမွေဆက်ခံပြီး၊ nested elements များသည် မိဘ၏ အလှဆင်မှုများကို အမွေဆက်ခံသည်။
Style များသည် မူရင်း ancestor style မှ ဆက်ခံပြီး၊ nested element များသည် သူတို့၏ parent များ၏ style များကို ဆက်ခံသည်။
### လုပ်ငန်း
@ -81,11 +81,11 @@ body {
}
```
သင့်ဘရောက်ဇာ၏ console တွင် 'Elements' tab ကို ဖွင့်ပြီး H1 ၏ font ကို ကြည့်ပါ။ ၎င်းသည် body မှ အမွေဆက်ခံထားသည်ကို ဘရောက်ဇာတွင် ဖော်ပြထားသည်-
သင့်ဘရောက်ဇာ၏ console တွင် 'Elements' tab ကို ဖွင့်ပြီး H1 ၏ font ကို ကြည့်ပါ။ ၎င်းသည် body မှ font ကို ဆက်ခံထားသည်ဟု ဘရောက်ဇာတွင် ဖော်ပြထားသည်-
![inherited font](../../../../translated_images/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.my.png)
✅ Nested style တစ်ခုကို အခြားသော property ကို အမွေဆက်ခံစေရန် ပြုလုပ်နိုင်ပါသလား။
✅ Nested style တစ်ခုကို အခြား property တစ်ခုကို ဆက်ခံစေနိုင်ပါသလား?
---
@ -93,7 +93,7 @@ body {
### Tags
ယခုအချိန်ထိ သင့် `style.css` ဖိုင်တွင် tag အနည်းငယ်သာ အလှဆင်ထားပြီး၊ အက်ပ်သည် အနည်းငယ် ထူးဆန်းနေသည်-
ယခုအချိန်ထိ သင့် `style.css` ဖိုင်တွင် tag အနည်းငယ်သာ style ပြုလုပ်ထားပြီး၊ အက်ပ်သည် အနည်းငယ်ထူးဆန်းနေသည်-
```CSS
body {
@ -106,11 +106,11 @@ h1 {
}
```
ဒီလို tag ကို အလှဆင်ခြင်းသည် တစ်ခုတည်းသော element များကို ထိန်းချုပ်နိုင်စေသော်လည်း၊ သင့် terrarium တွင် အပင်များစွာ၏ အလှဆင်မှုကို ထိန်းချုပ်ရန် လိုအပ်သည်။ ဒါကို ပြုလုပ်ရန် CSS selectors ကို အသုံးပြုရမည်။
ဒီလို tag ကို style ပြုလုပ်ခြင်းသည် unique element များကို ထိန်းချုပ်နိုင်စေသော်လည်း၊ သင့် terrarium တွင် အပင်များစွာ၏ style များကို ထိန်းချုပ်ရန်လိုအပ်သည်။ ဒါကို ပြုလုပ်ရန် CSS selector များကို အသုံးပြုရမည်။
### Ids
ဘယ်ဘက်နှင့် ညာဘက် containers များကို layout ပြုလုပ်ရန် အလှဆင်မှုကို ထည့်သွင်းပါ။ Markup တွင် တစ်ခုတည်းသော ဘယ်ဘက် container နှင့် တစ်ခုတည်းသော ညာဘက် container ရှိသောကြောင့်၊ ၎င်းတို့ကို ids ဖြင့် သတ်မှတ်ထားသည်။ ၎င်းတို့ကို အလှဆင်ရန် `#` ကို အသုံးပြုပါ-
ဘယ်ဘက်နှင့် ညာဘက် container များကို layout ပြုလုပ်ရန် style ထည့်ပါ။ Markup တွင် တစ်ခုတည်းသော left container နှင့် တစ်ခုတည်းသော right container ရှိသောကြောင့်၊ ၎င်းတို့ကို id များဖြင့် သတ်မှတ်ထားသည်။ style ပြုလုပ်ရန် `#` ကို အသုံးပြုပါ-
```CSS
#left-container {
@ -134,9 +134,9 @@ h1 {
}
```
ဒီမှာ၊ သင်သည် ဒီ containers များကို မျက်နှာပြင်၏ အလယ်ဘက်နှင့် ညာဘက်သို့ absolute positioning ဖြင့်ထားပြီး၊ ၎င်းတို့၏ အကျယ်ကို ရာခိုင်နှုန်းများဖြင့် သတ်မှတ်ထားသည်။ ဒါကြောင့် ၎င်းတို့သည် မိုဘိုင်းမျက်နှာပြင်အသေးများအတွက်လည်း အဆင်ပြေစေသည်။
ဒီမှာ၊ container များကို မျက်နှာပြင်၏ ဘယ်ဘက်နှင့် ညာဘက်အဆုံးတွင် absolute positioning ဖြင့်ထားပြီး၊ width များကို ရာခိုင်နှုန်းဖြင့် သတ်မှတ်ထားသည်။ ဒါကြောင့် မိုဘိုင်းမျက်နှာပြင်အသေးများအတွက်လည်း အရွယ်အစားကို အလိုအလျောက် ချိန်ညှိနိုင်သည်။
✅ ဒီကုဒ်သည် အတော်လေး ထပ်တလဲလဲဖြစ်နေသည်၊ ထို့ကြောင့် "DRY" (Don't Repeat Yourself) မဟုတ်ပါ။ ဒီ ids များကို အလှဆင်ရန် ပိုမိုကောင်းမွန်သော နည်းလမ်းကို ရှာဖွေပါ၊ ဥပမာ id နှင့် class တစ်ခုကို ပေါင်းစပ်အသုံးပြုခြင်း။ သင်သည် markup ကို ပြောင်းလဲပြီး CSS ကို ပြန်လည်ပြင်ဆင်ရမည်-
✅ ဒီကုဒ်သည် အတော်လေး ထပ်နေသည်၊ "DRY" (Don't Repeat Yourself) မဟုတ်ပါ။ id နှင့် class တစ်ခုဖြင့် ဒီ id များကို ပိုမိုကောင်းမွန်စွာ style ပြုလုပ်နိုင်မည့် နည်းလမ်းတစ်ခု ရှာနိုင်ပါသလား? သင်သည် markup ကို ပြောင်းလဲပြီး CSS ကို ပြန်လည်ပြုပြင်ရမည်-
```html
<div id="left-container" class="container"></div>
@ -144,9 +144,9 @@ h1 {
### Classes
အထက်ပါ ဥပမာတွင်၊ သင်သည် မျက်နှာပြင်ပေါ်ရှိ တစ်ခုတည်းသော element နှစ်ခုကို အလှဆင်ထားသည်။ မျက်နှာပြင်ပေါ်ရှိ element များစွာကို အလှဆင်မှုများ သက်ရောက်စေရန်၊ CSS classes ကို အသုံးပြုနိုင်သည်။ ဒါကို ဘယ်ဘက်နှင့် ညာ container များတွင် အပင်များကို layout ပြုလုပ်ရန် ပြုလုပ်ပါ။
အထက်ပါ ဥပမာတွင်၊ သင်သည် မျက်နှာပြင်ပေါ်ရှိ unique element နှစ်ခုကို style ပြုလုပ်ထားသည်။ မျက်နှာပြင်ပေါ်ရှိ element များစွာကို style ပြုလုပ်လိုပါက CSS class များကို အသုံးပြုနိုင်သည်။ ဒါကို left နှင့် right container များတွင် အပင်များကို layout ပြုလုပ်ရန် ပြုလုပ်ပါ။
HTML markup တွင် အပင်တစ်ခုစီတွင် ids နှင့် classes တို့၏ ပေါင်းစပ်ကို သုံးထားသည်ကို သတိပြုပါ။ ဒီမှာ ids များကို နောက်ပိုင်းတွင် JavaScript ဖြင့် terrarium အပင်များ၏ တည်နေရာကို ပြောင်းလဲရန် အသုံးပြုမည်။ Classes များကတော့ အပင်အားလုံးကို သတ်မှတ်ထားသော အလှဆင်မှုကို ပေးသည်။
HTML markup တွင် အပင်တစ်ခုစီတွင် id များနှင့် class များပေါင်းစပ်ထားသည်ကို သတိပြုပါ။ id များကို JavaScript မှ အသုံးပြု၍ terrarium အပင်များ၏ placement ကို ပြောင်းလဲရန် အသုံးပြုမည်။ class များသည် အပင်အားလုံးကို သတ်မှတ်ထားသော style ကို ပေးသည်။
```html
<div class="plant-holder">
@ -154,7 +154,7 @@ HTML markup တွင် အပင်တစ်ခုစီတွင် ids န
</div>
```
သင့် `style.css` ဖိုင်တွင် အောက်ပါအတိုင်း ထည့်သွင်းပါ-
သင့် `style.css` ဖိုင်တွင် အောက်ပါအတိုင်း ထည့်ပါ-
```CSS
.plant-holder {
@ -171,37 +171,35 @@ HTML markup တွင် အပင်တစ်ခုစီတွင် ids န
}
```
ဒီ snippet တွင် relative နှင့် absolute positioning များ၏ ပေါင်းစပ်ကို သတိပြုပါ၊ ကျွန်ုပ်တို့သည် နောက်ပိုင်းတွင် ၎င်းတို့ကို ဆွေးနွေးမည်။ Heights များကို ရာခိုင်နှုန်းဖြင့် စီမံထားပုံကိုလည်း သတိပြုပါ-
ဒီ snippet တွင် relative နှင့် absolute positioning တို့၏ ပေါင်းစပ်မှုကို သတိပြုပါ။ အပင်များကို vertical container တစ်ခုစီတွင် scrolling မလိုအပ်ဘဲ ပြသနိုင်ရန်အတွက် အပင် holder ၏ height ကို 13% သတ်မှတ်ထားသည်။
သင်သည် plant holder ၏ အမြင့်ကို 13% သတ်မှတ်ထားသည်၊ ၎င်းသည် vertical container တစ်ခုစီတွင် scrolling မလိုအပ်ဘဲ အပင်အားလုံးကို ပြသနိုင်ရန် သင့်တော်သော အရေအတွက်ဖြစ်သည်။
အပင် holder ကို left သို့ရွှေ့ထားပြီး၊ container အတွင်းတွင် အပင်များကို ပိုမိုအလယ်ကျစေရန် ပြုလုပ်ထားသည်။ အပင်များ၏ ပုံများတွင် transparent background အများကြီးပါဝင်သောကြောင့်၊ မျက်နှာပြင်ပေါ်တွင် ပိုမိုသင့်တော်စေရန် left သို့ရွှေ့ထားရန် လိုအပ်သည်။
Plant holder ကို ဘယ်ဘက်သို့ ရွှေ့ထားပြီး၊ container အတွင်းတွင် အပင်များကို ပိုမိုအလယ်တန်းကျစေရန် ပြုလုပ်ထားသည်။ Images များတွင် drag လုပ်နိုင်စေရန် အများကြီးသော transparent background ရှိသောကြောင့်၊ မျက်နှာပြင်ပေါ်တွင် ပိုမိုသင့်တော်စေရန် ဘယ်ဘက်သို့ ရွှေ့ထားရန် လိုအပ်သည်။
ထို့နောက်၊ အပင်ကို max-width 150% သတ်မှတ်ထားသည်။ ဒါကြောင့် ဘရောက်ဇာအရွယ်အစားကို ချိန်ညှိသည့်အခါ အပင်များသည် container အတွင်းတွင်နေပြီး အရွယ်အစားကို လိုက်လျောညီထွေဖြစ်စေသည်။
ထို့နောက်၊ plant ကို max-width 150% သတ်မှတ်ထားသည်။ ၎င်းသည် ဘရောက်ဇာအရွယ်အစားကို လိုက်လျောညီထွေဖြင့် ကျယ်ပြန့်စေသည်။ သင့်ဘရောက်ဇာကို အရွယ်အစားပြောင်းကြည့်ပါ၊ အပင်များသည် container အတွင်းတွင်သာရှိပြီး၊ အရွယ်အစားကို လိုက်လျောညီထွေဖြင့် ကျယ်ပြန့်နေသည်ကို တွေ့ရမည်
z-index ၏ အသုံးပြုမှုကိုလည်း သတိပြုပါ။ ၎င်းသည် element ၏ အမြင့်ကို ထိန်းချုပ်ပေးပြီး (အပင်များသည် container အပေါ်တွင်နေပြီး terrarium အတွင်းတွင်ရှိသကဲ့သို့ ပြသသည်)
ထို့အပြင် z-index ကို အသုံးပြုထားသည်ကိုလည်း သတိပြုပါ၊ ၎င်းသည် element တစ်ခု၏ အမြင့်ကို ထိန်းချုပ်ပြီး၊ အပင်များသည် container အပေါ်တွင် ထိုင်နေသကဲ့သို့ ပြသစေသည်။
✅ Plant holder နှင့် plant CSS selector နှစ်ခုလုံးကို ဘာကြောင့် လိုအပ်သနည်း။
✅ အဘယ်ကြောင့် plant holder နှင့် plant CSS selector နှစ်ခုလုံးလိုအပ်သနည်း?
## CSS Positioning
Position properties (static, relative, fixed, absolute, sticky) များကို ပေါင်းစပ်အသုံးပြုခြင်းသည် အနည်းငယ်ရှုပ်ထွေးနိုင်သော်လည်း၊ သင့်မျက်နှာပြင်ပေါ်ရှိ element များကို ထိန်းချုပ်ရန် ကောင်းမွန်သော ထိန်းချုပ်မှုကို ပေးသည်။
Position property များ (static, relative, fixed, absolute, sticky) ကို ပေါင်းစပ်အသုံးပြုခြင်းသည် အနည်းငယ်ခက်ခဲနိုင်သော်လည်း၊ မှန်ကန်စွာ ပြုလုပ်ပါက မျက်နှာပြင်ပေါ်ရှိ element များကို ကောင်းစွာထိန်းချုပ်နိုင်စေသည်။
Absolute positioned elements များသည် ၎င်းတို့၏ အနီးဆုံး positioned ancestor များအပေါ်တွင် တည်နေရာချထားသည်၊ အကယ်၍ positioned ancestor မရှိပါက၊ document body အပေါ်တွင် တည်နေရာချထားသည်။
Absolute positioned element များသည် သူတို့၏ အနီးဆုံး positioned ancestor များအပေါ်မူတည်၍ position ပြုလုပ်သည်။ အကယ်၍ positioned ancestor မရှိပါက၊ document body အပေါ်မူတည်၍ position ပြုလုပ်သည်။
Relative positioned elements များသည် ၎င်းတို့၏ မူလတည်နေရာမှ CSS ၏ ညွှန်ကြားချက်အတိုင်း တည်နေရာကို ပြောင်းလဲထားသည်။
Relative positioned element များသည် သူတို့၏ မူလ position မှ CSS ၏ ညွှန်ကြားချက်အတိုင်း အနေအထားကို ပြောင်းလဲသည်။
ကျွန်ုပ်တို့၏ ဥပမာတွင်၊ `plant-holder` သည် relative-positioned element ဖြစ်ပြီး၊ absolute-positioned container အတွင်းတွင် တည်နေရာချထားသည်။ ၎င်း၏ အကျိုးသက်ရောက်မှုမှာ side bar containers များသည် ဘယ်ဘက်နှင့် ညာဘက်တွင် pin လုပ်ထားပြီး၊ plant-holder သည် side bars အတွင်းတွင် nested ဖြစ်ကာ၊ အပင်များကို vertical row အဖြစ်ထားရန် နေရာပေးထားသည်။
ကျွန်ုပ်တို့၏ ဥပမာတွင်၊ `plant-holder` သည် relative-positioned element တစ်ခုဖြစ်ပြီး၊ absolute-positioned container အတွင်းတွင် position ပြုလုပ်ထားသည်။ ၎င်း၏ရလဒ်မှာ side bar container များသည် ဘယ်ဘက်နှင့် ညာဘက်တွင် pin လုပ်ထားပြီး၊ plant-holder သည် nested ဖြစ်ကာ၊ side bar များအတွင်းတွင် အပင်များကို vertical row အဖြစ်ထားရန်နေရာပေးထားသည်။
> `plant` ကို absolute positioning ဖြင့်ထားထားပြီး၊ ၎င်းကို draggable ဖြစ်စေရန် လိုအပ်သည်၊ ၎င်းကို နောက်သင်ခန်းစာတွင် လေ့လာမည်။
> [!NOTE] `plant` ကိုလည်း absolute positioning ဖြင့်ထားထားပြီး၊ ၎င်းကို draggable ဖြစ်စေရန် လိုအပ်သည်။ ၎င်းကို နောက်သင်ခန်းစာတွင် ရှင်းပြမည်။
✅ Side containers နှင့် plant-holder ၏ positioning အမျိုးအစားများကို ပြောင်းလဲကြည့်ပါ။ ဘာဖြစ်သနည်း။
✅ Side container များနှင့် plant-holder ၏ positioning အမျိုးအစားများကို ပြောင်းလဲကြည့်ပါ။ ဘာဖြစ်သလဲ?
## CSS Layouts
ယခု သင်လေ့လာခဲ့သည့် အရာများကို အသုံးပြု၍ CSS ဖြင့်ပဲ terrarium ကို ဖန်တီးပါ။
ယခု သင်လေ့လာခဲ့သည့်အရာများကို အသုံးပြု၍ CSS ဖြင့် terrarium ကို ဖန်တီးပါ!
ပထမဦးစွာ၊ `.terrarium` div ၏ children များကို CSS ဖြင့် rounded rectangle အဖြစ် အလှဆင်ပါ-
ပထမဦးစွာ၊ `.terrarium` div ၏ children များကို CSS ဖြင့် rounded rectangle အဖြစ် style ပြုလုပ်ပါ-
```CSS
.jar-walls {
@ -250,29 +248,29 @@ Relative positioned elements များသည် ၎င်းတို့၏
}
```
ဒီမှာ ရာခိုင်နှုန်းများကို အသုံးပြုထားပုံကို သတိပြုပါ။ သင့်ဘရောက်ဇာကို အရွယ်အစားကျယ်ပြန့်စေပါက၊ jar သည်လည်း အရွယ်အစားကျယ်ပြန့်နေသည်ကို တွေ့ရမည်။ ထို့အပြင် jar elements များ၏ width နှင့် height ရာခိုင်နှုန်းများနှင့်၊ element တစ်ခုစီကို absolutely positioned ဖြစ်ကာ viewport ၏ အောက်ခြေတွင် pin လုပ်ထားပုံကိုလည်း သတိပြုပါ။
ဒီမှာ percentage များကို အသုံးပြုထားသည်ကို သတိပြုပါ။ သင့်ဘရောက်ဇာကို အရွယ်အစားသေးသွားအောင် ချိန်ညှိပါက၊ jar သည်လည်း အရွယ်အစားကို လိုက်လျောညီထွေဖြစ်သည်ကို တွေ့ရမည်။ jar element များ၏ width နှင့် height percentage များနှင့်၊ viewport ၏ အောက်ခြေတွင် pin လုပ်ထားသော absolute positioning ကိုလည်း သတိပြုပါ။
၎င်းတို့၏ border-radius အတွက် `rem` ကို အသုံးပြုထားသည်ကိုလည်း သတိပြုပါ၊ ၎င်းသည် font-relative length ဖြစ်သည်။ ဒီ relative measurement အမျိုးအစားအကြောင်းကို [CSS spec](https://www.w3.org/TR/css-values-3/#font-relative-lengths) တွင် ဖတ်ရှုနိုင်သည်။
ထို့အပြင် `rem` ကို border-radius အတွက် အသုံးပြုထားသည်။ ၎င်းသည် font-relative length တစ်ခုဖြစ်သည်။ ဒီ relative measurement အမျိုးအစားအကြောင်းကို [CSS spec](https://www.w3.org/TR/css-values-3/#font-relative-lengths) တွင် ဖတ်ရှုနိုင်သည်။
✅ Jar ၏ အရောင်များနှင့် opacity ကို dirt ၏ အရောင်များနှင့် opacity နှင့် ပြောင်းလဲကြည့်ပါ။ ဘာဖြစ်သနည်း။ အဘယ်ကြောင့်လဲ။
✅ Jar ၏ အရောင်များနှင့် opacity ကို dirt ၏ အရောင်များနှင့် opacity နှင့် ပြောင်းလဲကြည့်ပါ။ ဘာဖြစ်သလဲ? အဘယ်ကြောင့်?
---
## 🚀 စိန်ခေါ်မှု
Jar ၏ ဘယ်ဘက်အောက်ခြေတွင် 'bubble' shine တစ်ခု ထည့်သွင်းပြီး၊ ၎င်းကို ဖန်မှန်ကဲ့သို့ ပုံစံဖြစ်စေရန် ပြုလုပ်ပါ။ `.jar-glossy-long` နှင့် `.jar-glossy-short` ကို အလှဆင်ပြီး၊ ၎င်းကို အလင်းပြန်သော shine တစ်ခုကဲ့သို့ ပြုလုပ်ပါ။ ၎င်းသည် အောက်ပါပုံကဲ့သို့ ဖြစ်ရမည်-
Jar ၏ ဘယ်ဘက်အောက်ခြေတွင် 'bubble' shine တစ်ခု ထည့်၍၊ ၎င်းကို ဖန်သားမျက်နှာပြင်ကဲ့သို့ ပြုလုပ်ပါ။ `.jar-glossy-long` နှင့် `.jar-glossy-short` ကို reflected shine ကဲ့သို့ ပြုလုပ်ရန် style ပြုလုပ်ရမည်။ ၎င်းသည် အောက်ပါအတိုင်း ဖြစ်မည်-
![finished terrarium](../../../../translated_images/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.my.png)
Post-lecture quiz ကို ပြီးမြောက်စေရန်၊ ဒီ Learn module ကို လေ့လာပါ- [Style your HTML app with CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
Post-lecture quiz ကို ပြီးမြောက်ရန်၊ ဒီ Learn module ကို လေ့လာပါ- [Style your HTML app with CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
## မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု
## မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း
[မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/18)
[မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/18)
## ပြန်လည်သုံးသပ်မှုနှင့် ကိုယ်တိုင်လေ့လာမှု
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
CSS သည် ရိုးရှင်းသည့်အရာတစ်ခုကဲ့သို့ ထင်ရသော်လည်း၊ အက်ပ်ကို ဘရောက်ဇာအားလုံးနှင့် မျက်နှာပြင်အရွယ်အစားအားလုံးအတွက် ပြီးပြည့်စုံစွာ အလှဆင်ရန် အခက်အခဲများစွာ ရှိသည်။ CSS-Grid နှင့် Flexbox သည် အလုပ်ကို ပိုမိုစနစ်တကျဖြစ်စေရန်နှင့် ယုံကြည်စိတ်ချစေရန် ဖန်တီးထားသော ကိရိယာများဖြစ်သည်။ ဒီကိရိယာများကို [Flexbox Froggy](https://flexboxfroggy.com/) နှင့် [Grid Garden](https://codepip.com/games/grid-garden/) တွင် ကစားခြင်းဖြင့် လေ့လာပါ။
CSS သည် ရိုးရှင်းလွယ်ကူသည်ဟု ထင်ရသော်လည်း၊ ဘရောက်ဇာအားလုံးနှင့် မျက်နှာပြင်အရွယ်အစားအားလုံးအတွက် အက်ပ်ကို ပြီးပြည့်စုံစွာ style ပြုလုပ်ရန် အခက်အခဲများစွာ ရှိသည်။ CSS-Grid နှင့် Flexbox သည် အလုပ်ကို ပိုမိုစနစ်တကျဖြစ်စေပြီး ယုံကြည်စိတ်ချစေသော ကိရိယာများဖြစ်သည်။ ဒီကိရိယာများကို [Flexbox Froggy](https://flexboxfroggy.com/) နှင့် [Grid Garden](https://codepip.com/games/grid-garden/) တွင် ကစားပြီး လေ့လာပါ။
## လုပ်ငန်း
@ -280,5 +278,5 @@ CSS သည် ရိုးရှင်းသည့်အရာတစ်ခုက
---
**ဝက်ဘ်ဆိုက်မှတ်ချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှန်ကန်မှုအတွက် ကြိုးစားနေပါသော်လည်း၊ အလိုအလျောက်ဘာသာပြန်ဆိုမှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို ကျေးဇူးပြု၍ သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူလဘာသာစကားဖြင့် အာဏာတည်သောရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ အတည်ပြုထားသော ဘာသာပြန်ဆိုမှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်ဆိုမှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော နားလည်မှုမှားများ သို့မဟုတ် အဓိပ္ပာယ်မှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "30f8903a1f290e3d438dc2c70fe60259",
"translation_date": "2025-08-27T22:39:14+00:00",
"original_hash": "61c14b27044861e5e69db35dd52c4403",
"translation_date": "2025-08-28T18:45:03+00:00",
"source_file": "3-terrarium/3-intro-to-DOM-and-closures/README.md",
"language_code": "my"
}
@ -12,46 +12,46 @@ CO_OP_TRANSLATOR_METADATA:
![DOM and a closure](../../../../translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.my.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## မိမိသင်ခန်းစာမတိုင်မီ စမ်းမေးခွန်း
## မိမိကိုယ်ကို စမ်းမေးခွန်း
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/19)
### အကျဉ်းချုပ်
DOM (Document Object Model) ကိုပြောင်းလဲခြင်းသည် ဝဘ်ဖွံ့ဖြိုးတိုးတက်မှုတွင် အရေးပါသောအပိုင်းတစ်ခုဖြစ်သည်။ [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) အဆိုအရ "Document Object Model (DOM) သည် ဝဘ်ပေါ်တွင် စာရွက်တစ်ရွက်၏ ဖွဲ့စည်းပုံနှင့် အကြောင်းအရာကို ဖော်ပြထားသော အရာများ၏ ဒေတာကို ကိုယ်စားပြုခြင်းဖြစ်သည်။" DOM ကို JavaScript frameworks များဖြင့် စီမံခန့်ခွဲရန်အစား သာမန် JavaScript ကို အသုံးပြု၍ စီမံခန့်ခွဲရန် အခက်အခဲများသည် အဓိကအကြောင်းရင်းဖြစ်လာခဲ့သည်။ သို့သော် ကျွန်ုပ်တို့သည် ကိုယ်တိုင် စီမံခန့်ခွဲမည်။
DOM (Document Object Model) ကို ပြောင်းလဲခြင်းသည် ဝဘ်ဖွံ့ဖြိုးတိုးတက်မှုတွင် အရေးပါသော အပိုင်းတစ်ခုဖြစ်သည်။ [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) အဆိုအရ "Document Object Model (DOM) သည် ဝဘ်ပေါ်တွင် စာရွက်၏ ဖွဲ့စည်းပုံနှင့် အကြောင်းအရာကို ဖော်ပြထားသော အရာများ၏ ဒေတာကို ကိုယ်စားပြုခြင်းဖြစ်သည်။" DOM ကို JavaScript ဖြင့် စီမံခန့်ခွဲရာတွင် အခက်အခဲများကြောင့် JavaScript frameworks များကို အသုံးပြုရန် အကြောင်းဖန်တီးခဲ့သည်။ သို့သော် ဒီသင်ခန်းစာတွင် ကျွန်ုပ်တို့သည် ကိုယ်တိုင် စီမံခန့်ခွဲသွားည်ဖြစ်သည်။
ထို့အပြင် ဒီသင်ခန်းစာတွင် [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures) ၏ အကြောင်းအရာကို မိတ်ဆက်ပေးမည်ဖြစ်ပြီး၊ ၎င်းကို အပြင်ဘက် function ၏ scope ကို အတွင်း function မှ access လုပ်နိုင်ရန် function တစ်ခုကို အခြား function တစ်ခုဖြင့် ပတ်လည်ဖုံးအုပ်ထားသောအဖြစ် စဉ်းစားနိုင်သည်။
ထို့အပြင် ဒီသင်ခန်းစာတွင် [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures) ၏ အကြောင်းကို မိတ်ဆက်ပေးမည်ဖြစ်ပြီး၊ closure ကို အပြင် function တစ်ခု၏ scope ကို အတွင်း function တစ်ခုမှ access လုပ်နိုင်ရန် ဖန်တီးထားသော function တစ်ခုအဖြစ် စဉ်းစားနိုင်သည်။
> JavaScript closures သည် ကျယ်ပြန့်ပြီး ရှုပ်ထွေးသောအကြောင်းအရာဖြစ်သည်။ ဒီသင်ခန်းစာသည် terrarium ၏ code တွင် closure တစ်ခုကို တွေ့နိုင်မည့် အခြေခံအကြောင်းအရာကိုသာ ထိတွေ့သည်။ ၎င်းသည် အတွင်း function နှင့် အပြင် function တစ်ခုကို အတွင်း function သည် အပြင် function ၏ scope ကို access လုပ်နိုင်ရန် ဖွဲ့စည်းထားသောပုံစံဖြစ်သည်။ ၎င်းအကြောင်းအရာကို နားလည်ရန် [ကျယ်ကျယ်ပြန့်ပြန့်သော documentation](https://developer.mozilla.org/docs/Web/JavaScript/Closures) ကို သွားရောက်လေ့လာပါ။
> JavaScript closures သည် ကျယ်ပြန့်ပြီး ရှုပ်ထွေးသော အကြောင်းအရာဖြစ်သည်။ ဒီသင်ခန်းစာတွင် terrarium ရဲ့ code အတွင်းရှိ closure ၏ အခြေခံအကြောင်းအရာကိုသာ ထိတွေ့မည်ဖြစ်သည်။ အတွင်း function နှင့် အပြင် function တစ်ခုကို ဖန်တီးထားပြီး အတွင်း function သည် အပြင် function ၏ scope ကို access လုပ်နိုင်ရန် ဖန်တီးထားသည်။ ဒီအကြောင်းအရာကို ပိုမိုနားလည်ရန် [အကျယ်အဝန်းရှိသော documentation](https://developer.mozilla.org/docs/Web/JavaScript/Closures) ကို သွားလေ့လာပါ။
ကျွန်ုပ်တို့သည် DOM ကို ပြောင်းလဲရန် closure ကို အသုံးပြုမည်။
ကျွန်ုပ်တို့သည် closure ကို အသုံးပြု၍ DOM ကို ပြောင်းလဲည်ဖြစ်သည်။
DOM ကို ဝဘ်စာရွက်စာတမ်းကို ပြောင်းလဲနိုင်သော နည်းလမ်းများကို ကိုယ်စားပြုသော သစ်ပင်တစ်ပင်အဖြစ် စဉ်းစားပါ။ ဝဘ်စာရွက်စာတမ်းကို access လုပ်ပြီး ပြင်ဆင်၊ ပြောင်းလဲ၊ ပြန်လည်စီစဉ်ခြင်းနှင့် အခြားစီမံခန့်ခွဲမှုများကို ပြုလုပ်နိုင်ရန် အမျိုးမျိုးသော API (Application Program Interfaces) များကို ရေးသားထားသည်။
DOM ကို သစ်ပင်တစ်ပင်အဖြစ် စဉ်းစားပါ၊ ၎င်းသည် ဝဘ်စာရွက်ကို ပြောင်းလဲနိုင်သော နည်းလမ်းများအားလုံးကို ကိုယ်စားပြုသည်။ ဝဘ်စာရွက်ကို access လုပ်ပြီး ပြင်ဆင်၊ ပြောင်းလဲ၊ ပြန်လည်စီမံခြင်းနှင့် စီမံခန့်ခွဲနိုင်ရန် အမျိုးမျိုးသော API များကို ဖန်တီးထားသည်။
![DOM tree representation](../../../../translated_images/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.my.png)
> DOM နှင့် ၎င်းကို ကိုးကားထားသော HTML markup ၏ ကိုယ်စားပြုမှု။ [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites) မှ
ဒီသင်ခန်းစာတွင် ကျွန်ုပ်တို့၏ interactive terrarium project ကို ပြီးစီးရန် JavaScript ကို ဖန်တီးပြီး ဝဘ်စာမျက်နှာပေါ်တွင် အပင်များကို ပြောင်းလဲနိုင်ရန် အသုံးပြုမည်။
ဒီသင်ခန်းစာတွင် ကျွန်ုပ်တို့သည် interactive terrarium project ကို JavaScript ဖြင့် ပြီးစီးအောင်လုပ်ပြီး၊ အသုံးပြုသူများသည် စာမျက်နှာပေါ်တွင် အပင်များကို ပြောင်းလဲနိုင်ရန် ဖန်တီးမည်ဖြစ်သည်။
### ကြိုတင်လိုအပ်ချက်
သင်၏ terrarium အတွက် HTML နှင့် CSS ကို ဖန်တီးပြီးဖြစ်ရမည်။ ဒီသင်ခန်းစာအဆုံးတွင် သင်သည် အပင်များကို drag လုပ်၍ terrarium ထဲသို့ ထည့်ခြင်းနှင့် ထုတ်ခြင်းကို ပြုလုပ်နိုင်မည်ဖြစ်သည်။
သင်၏ terrarium အတွက် HTML နှင့် CSS ကို ဖန်တီးပြီးထားရမည်။ ဒီသင်ခန်းစာအဆုံးတွင် သင်သည် အပင်များကို terrarium အတွင်းသို့ နှင့် အပြင်သို့ ဆွဲထုတ်နိုင်မည်ဖြစ်သည်။
### လုပ်ဆောင်ရန်
သင်၏ terrarium folder တွင် `script.js` ဟုခေါ်သော ဖိုင်အသစ်တစ်ခု ဖန်တီးပါ။ ၎င်းကို `<head>` အပိုင်းတွင် import လုပ်ပါ။
သင်၏ terrarium folder အတွင်း `script.js` ဆိုသော ဖိုင်အသစ်တစ်ခု ဖန်တီးပါ။ ၎င်းကို `<head>` အပိုင်းတွင် import လုပ်ပါ။
```html
<script src="./script.js" defer></script>
```
> Note: HTML ဖိုင်ကို အပြည့်အစုံ load ပြီးနောက်မှ JavaScript ကို run ဖို့ `defer` ကို အသုံးပြုပါ။ `async` attribute ကိုလည်း အသုံးပြုနိုင်ပြီး၊ ၎င်းသည် HTML ဖိုင်ကို parsing လုပ်နေစဉ် script ကို run လုပ်နိုင်စေသည်။ သို့သော် ကျွန်ုပ်တို့၏အခြေအနေတွင် drag script ကို run လုပ်မီ HTML elements အားလုံးကို ပြည့်စုံစွာ အသုံးပြုနိုင်ရန်လိုအပ်သည်။
> Note: HTML ဖိုင်အားလုံး load ပြီးဆုံးမှ JavaScript ကို run လုပ်ရန် `defer` attribute ကို အသုံးပြုပါ။ `async` attribute ကိုလည်း အသုံးပြုနိုင်ပြီး၊ HTML ဖိုင် parsing ဖြစ်နေစဉ် script ကို run လုပ်နိုင်သည်။ သို့သော် ဒီအခါတွင် drag script ကို run လုပ်မည်မတိုင်မီ HTML elements အားလုံးကို ပြင်ဆင်ထားရန် အရေးကြီးသည်။
---
## DOM elements
DOM တွင် ပြောင်းလဲလိုသော elements များကို reference ဖန်တီးရန် အရေးကြီးသည်။ ကျွန်ုပ်တို့၏အခြေအနေတွင်၊ ၎င်းတို့သည် side bars တွင်ရှိသော 14 ခုသော အပင်များဖြစ်သည်။
ပထမဆုံး သင်သည် DOM တွင်းရှိ ပြောင်းလဲလိုသော elements များကို reference လုပ်ရန် လိုအပ်သည်။ ကျွန်ုပ်တို့၏ အခါတွင် ၎င်းတို့သည် side bars အတွင်းရှိ 14 ခုသော အပင်များဖြစ်သည်။
### လုပ်ဆောင်ရန်
@ -72,7 +72,7 @@ dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
```
ဒီမှာ ဘာဖြစ်နေလဲ? သင်သည် document ကို reference လုပ်ပြီး DOM တွင် Id တစ်ခုရှိသော element ကို ရှာဖွေနေသည်။ HTML သင်ခန်းစာပထမပိုင်းတွင် အပင်ပုံရိပ်တစ်ခုစီကို individual Ids (`id="plant1"`) ပေးခဲ့သည်ကို သတိရပါ။ အခုတော့ ၎င်းကို အသုံးပြုမည်။ Element တစ်ခုကို identify ပြီးနောက်၊ ၎င်းကို `dragElement` ဟုခေါ်သော function သို့ pass လုပ်သည်။ သင်မကြာမီ ဖန်တီးမည့် function ဖြစ်သည်။ ထို့ကြောင့် HTML ၏ element သည် drag-enabled ဖြစ်လာသည်။
ဒီမှာ ဘာဖြစ်နေလဲ? သင်သည် document ကို reference လုပ်ပြီး DOM တွင်းရှိ particular Id ရှိသော element ကို ရှာဖွေနေသည်။ HTML lesson ပထမပိုင်းတွင် သင်သည် အပင် image တစ်ခုစီကို individual Ids (`id="plant1"`) ပေးခဲ့သည်ကို သတိရပါ။ အခုတော့ ၎င်းကို အသုံးပြုမည်ဖြစ်သည်။ Element တစ်ခုစီကို identify လုပ်ပြီး `dragElement` ဆိုသော function သို့ pass လုပ်သည်။ ဒီ function ကို မကြာမီ ဖန်တီးမည်ဖြစ်သည်။ ထို့ကြောင့် HTML အတွင်းရှိ element သည် drag-enabled ဖြစ်လာမည်။
✅ အဘယ်ကြောင့် elements များကို Id ဖြင့် reference လုပ်သနည်း? CSS class ဖြင့် reference မလုပ်ဘဲ အဘယ်ကြောင့်?
@ -80,9 +80,9 @@ dragElement(document.getElementById('plant14'));
## Closure
အခုတော့ သင်သည် dragElement closure ကို ဖန်တီးရန် ပြင်ဆင်ပြီးဖြစ်သည်။ ၎င်းသည် အတွင်း function (သို့) functions များကို ပတ်လည်ဖုံးအုပ်ထားသော အပြင် function တစ်ခုဖြစ်သည်။ (ကျွန်ုပ်တို့၏အခြေအနေတွင် သုံးခုရှိမည်)
အခုတော့ သင်သည် dragElement closure ကို ဖန်တီးရန် ပြင်ဆင်ပြီးဖြစ်သည်။ ၎င်းသည် အတွင်း function (သို့မဟုတ် functions) ကို enclosure လုပ်ထားသော အပြင် function တစ်ခုဖြစ်သည်။
Closures သည် function တစ်ခု (သို့) function များသည် အပြင် function ၏ scope ကို access လုပ်ရန် အသုံးဝင်သည်။ ဥပမာအားဖြင့်:
Closures သည် function တစ်ခု (သို့မဟုတ် functions များ) အပြင် function ၏ scope ကို access လုပ်ရန် အသုံးဝင်သည်။ ဥပမာအားဖြင့်:
```javascript
function displayCandy(){
@ -96,13 +96,13 @@ displayCandy();
console.log(candy)
```
ဒီဥပမာတွင် `displayCandy` function သည် candy အမျိုးအစားအသစ်ကို array ထဲသို့ push လုပ်သော function ကို ပတ်လည်ဖုံးအုပ်ထားသည်။ ဒီ code ကို run လုပ်ပါက `candy` array သည် undefined ဖြစ်မည် ၎င်းသည် closure ၏ local variable ဖြစ်သောကြောင့်ဖြစ်သည်။
ဒီဥပမာတွင် displayCandy function သည် array တစ်ခုရှိပြီး candy type အသစ်ကို push လုပ်သော function ကို enclosure လုပ်ထားသည်။ ဒီ code ကို run လုပ်ပါက `candy` array သည် undefined ဖြစ်မည် ၎င်းသည် closure ၏ local variable ဖြစ်သောကြောင့်ဖြစ်သည်။
`candy` array ကို accessible ဖြစ်စေရန် ဘာလုပ်ရမလဲ? ၎င်းကို closure အပြင်ဘက်သို့ ရွှေ့ပါ။ ဒီနည်းဖြင့် array သည် global ဖြစ်ပြီး closure ၏ local scope တွင်သာ ရှိနေမည်မဟုတ်တော့။
`candy` array ကို accessible ဖြစ်စေရန် ဘာလုပ်ရမလဲ? ၎င်းကို closure အပြင်သို့ ရွှေ့ပါ။ ဒီနည်းဖြင့် array သည် global ဖြစ်လာပြီး closure ၏ local scope တွင်သာ မကျန်ရှိတော့ပါ
### လုပ်ဆောင်ရန်
`script.js` တွင် element declarations အောက်တွင် function တစ်ခု ဖန်တီးပါ။
`script.js` တွင် element declarations အောက်တွင် function တစ်ခု ဖန်တီးပါ။
```javascript
function dragElement(terrariumElement) {
@ -115,19 +115,19 @@ function dragElement(terrariumElement) {
}
```
`dragElement` သည် ၎င်း၏ `terrariumElement` object ကို script အပေါ်ပိုင်းတွင်ရှိ declarations မှရရှိသည်။ ထို့နောက်၊ object ကို function ထဲသို့ pass လုပ်ပြီး local positions ကို `0` သတ်မှတ်သည်။ ၎င်းသည် drag နှင့် drop functionality ကို element တစ်ခုစီတွင် ထည့်သွင်းသောအခါ ပြောင်းလဲရန် local variables ဖြစ်သည်။ Terrarium သည် drag လုပ်ထားသော elements များဖြင့် ပြည့်စုံမည်ဖြစ်သောကြောင့် application သည် ၎င်းတို့ကိုထားရှိထားသောနေရာကို စောင့်ကြည့်ရန်လိုအပ်သည်။
`dragElement` သည် `terrariumElement` object ကို script ရဲ့ အပေါ်ပိုင်းရှိ declarations မှ ရယူသည်။ ထို့နောက် object ကို pass လုပ်ပြီး local positions ကို `0` သတ်မှတ်သည်။ ဒီ local variables များသည် drag နှင့် drop functionality ကို element တစ်ခုစီတွင် ထည့်သွင်းသည့်အခါ ပြောင်းလဲမည်ဖြစ်သည်။ Terrarium သည် drag လုပ်ထားသော elements များဖြင့် ပြည့်စုံလာမည်ဖြစ်ပြီး၊ application သည် ၎င်းတို့၏ placement ကို စောင့်ကြည့်ထားရန် လိုအပ်သည်။
ထို့အပြင်၊ function သို့ pass လုပ်ထားသော terrariumElement သည် `pointerdown` event ကို assign လုပ်ထားသည်။ ၎င်းသည် DOM management အတွက် [web APIs](https://developer.mozilla.org/docs/Web/API) ၏ အစိတ်အပိုင်းဖြစ်သည်။ `onpointerdown` သည် button ကို push လုပ်သောအခါ (သို့) draggable element ကို touch လုပ်သောအခါ fired ဖြစ်သည်။ ဒီ event handler သည် [web နှင့် mobile browsers](https://caniuse.com/?search=onpointerdown) နှစ်ခုလုံးတွင် အလုပ်လုပ်သည်။
ထို့အပြင် `terrariumElement` ကို `pointerdown` event သတ်မှတ်ထားသည်။ ၎င်းသည် [web APIs](https://developer.mozilla.org/docs/Web/API) ၏ အစိတ်အပိုင်းဖြစ်ပြီး DOM ကို စီမံခန့်ခွဲရန် အထောက်အကူပြုသည်။ `onpointerdown` သည် button ကို push လုပ်သောအခါ (သို့မဟုတ် drag လုပ်နိုင်သော element ကို touch လုပ်သောအခါ) ဖွင့်လှစ်သည်။ ဒီ event handler သည် [web နှင့် mobile browsers](https://caniuse.com/?search=onpointerdown) နှစ်ခုလုံးတွင် အလုပ်လုပ်သည်။
✅ [event handler `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) သည် browser များတွင် support ပိုများသည်။ ဒီနေရာတွင် မသုံးသင့်သောအကြောင်းရင်းကို စဉ်းစားပါ။
✅ [event handler `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) သည် browser support ပိုမိုများသည်။ ဒီနေရာတွင် မသုံးသင့်သော အကြောင်းရင်းကို စဉ်းစားပါ။
---
## Pointerdrag function
`terrariumElement` သည် drag လုပ်ရန် ပြင်ဆင်ပြီးဖြစ်သည်။ `onpointerdown` event fired ဖြစ်သောအခါ `pointerDrag` function ကို invoke လုပ်သည်။ ဒီလိုင်းအောက်တွင် function ကို ထည့်ပါ။ `terrariumElement.onpointerdown = pointerDrag;`:
`terrariumElement` သည် drag လုပ်ရန် ပြင်ဆင်ပြီးဖြစ်သည်။ `onpointerdown` event ကို fire လုပ်သောအခါ `pointerDrag` function ကို invoke လုပ်သည်။ ဒီလိုင်းအောက်တွင် function ကို ထည့်သွင်းပါ။ `terrariumElement.onpointerdown = pointerDrag;`:
### လုပ်ဆောင်ရန်
### လုပ်ဆောင်ရန်
```javascript
function pointerDrag(e) {
@ -138,32 +138,31 @@ function pointerDrag(e) {
}
```
အရာများစွာဖြစ်ပျက်သည်။ ပထမဦးစွာ၊ `e.preventDefault();` ကို အသုံးပြု၍ pointerdown တွင် ဖြစ်ပျက်သည့် default events များကို မဖြစ်အောင်တားဆီးသည်။ ဒီနည်းဖြင့် interface ၏ အပြုအမူကို ပိုမိုထိန်းချုပ်နိုင်သည်။
အရာများစွာဖြစ်ပျက်သည်။ ပထမဆုံး သင်သည် `e.preventDefault();` ကို အသုံးပြု၍ pointerdown တွင် ဖြစ်ပျက်သည့် default events များကို မဖြစ်ပျက်စေရန် ကာကွယ်သည်။ ဒီနည်းဖြင့် interface ၏ အပြုအမူကို ပိုမိုထိန်းချုပ်နိုင်သည်။
> script ဖိုင်ကို အပြည့်အစုံဖန်တီးပြီးနောက် `e.preventDefault()` မပါဘဲ run လုပ်ကြည့်ပါ။ ဘာဖြစ်သနည်း?
> script ဖိုင်အားလုံးကို ဖန်တီးပြီးဆုံးသောအခါ ဒီလိုင်းကို ပြန်လာကြည့်ပြီး `e.preventDefault()` မပါဘဲ စမ်းကြည့်ပါ။ ဘာဖြစ်သနည်း?
ဒုတိယအနေနှင့် `index.html` ကို browser window တွင်ဖွင့်ပြီး interface ကို inspect လုပ်ပါ။ အပင်ကို click လုပ်သောအခါ 'e' event ကို capture လုပ်ပုံကို မြင်နိုင်သည်။ event ကို အနက်ရှိုင်းစွာကြည့်ပြီး pointer down event တစ်ခုမှ အချက်အလက်များကို ဘယ်လောက်များစုဆောင်းထားသည်ကို ကြည့်ပါ။
ဒုတိယအနေနှင့် `index.html` ကို browser window တွင် ဖွင့်ပြီး interface ကို inspect လုပ်ပါ။ အပင်တစ်ခုကို click လုပ်သောအခါ 'e' event ကို capture လုပ်ပုံကို မြင်နိုင်သည်။ event ကို inspect လုပ်ပြီး pointer down event တစ်ခုမှ သိမ်းဆည်းထားသော အချက်အလက်များကို ကြည့်ပါ။
ထို့နောက် local variables `pos3` နှင့် `pos4` ကို e.clientX သို့ set လုပ်ထားပုံကို သတိပြုပါ။ inspection pane တွင် `e` values ကို တွေ့နိုင်သည်။ ဒီ values များသည် အပင်ကို click (သို့) touch လုပ်သောအချိန်တွင် ၎င်း၏ x နှင့် y coordinates ကို capture လုပ်သည်။ အပင်များကို click နှင့် drag လုပ်သောအခါ၎င်းတို့၏အပြုအမူကို စိတ်ကြိုက်ထိန်းချုပ်ရန် ၎င်းတို့၏ coordinates ကို စောင့်ကြည့်ထားသည်။
ထို့နောက် local variables `pos3` နှင့် `pos4` ကို e.clientX နှင့် e.clientY သတ်မှတ်ထားပုံကို သတိပြုပါ။ ဒီ values များသည် သင် click (သို့မဟုတ် touch) လုပ်သောအခါ အပင်၏ x နှင့် y coordinates ကို capture လုပ်သည်။ အပင်များကို click နှင့် drag လုပ်သောအခါ ၎င်းတို့၏ coordinates ကို စောင့်ကြည့်ရန် fine-grained control လိုအပ်သည်။
✅ ဒီ app ကို closure တစ်ခုဖြင့် ဖန်တီးထားရသည့်အကြောင်းရင်း ပိုမိုရှင်းလင်းလာပါသလား? မဟုတ်ပါက၊ draggable plants 14 ခုစီ၏ scope ကို ဘယ်လိုထိန်းသိမ်းမလဲ?
✅ ဒီ app အားလုံးကို closure တစ်ခုဖြင့် ဖန်တီးထားရသည့် အကြောင်းရင်း ပိုမိုရှင်းလင်းလာပါသလား? ၎င်းမဟုတ်ပါက 14 ခုသော draggable plants တစ်ခုစီ၏ scope ကို ဘယ်လိုထိန်းသိမ်းမလဲ?
`pos4 = e.clientY` အောက်တွင် pointer event manipulations နှစ်ခုကို ထည့်ပါ။
`pos4 = e.clientY` အောက်တွင် pointer event manipulations နှစ်ခုကို ထည့်သွင်းပြီး initial function ကို ပြီးစီးပါ။
```html
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
```
အခုတော့ pointer နှင့် plant ကို drag လုပ်သောအခါ၊ drag လုပ်မှု gesture ကို deselect လုပ်သောအခါ ရပ်တန့်ရန် သတ်မှတ်ထားသည်။ `onpointermove` နှင့် `onpointerup` သည် `onpointerdown` API ၏ အစိတ်အပိုင်းများဖြစ်သည်။ interface သည် error များကို throw လုပ်မည်။ ၎င်းသည် `elementDrag` နှင့် `stopElementDrag` functions များကို မသတ်မှတ်ရသေးသောကြောင့်ဖြစ်သည်။ function များကို နောက်တစ်ဆင့်တွင် ဖန်တီးပါ။
အခုတော့ သင်သည် pointer နှင့်အတူ အပင်ကို drag လုပ်လိုသည်ကို ဖော်ပြထားပြီး၊ အပင်ကို deselect လုပ်သောအခါ dragging gesture ကို ရပ်လိုသည်ကို ဖော်ပြထားသည်။ `onpointermove` နှင့် `onpointerup` သည် `onpointerdown` နှင့် တူသော API ၏ အစိတ်အပိုင်းများဖြစ်သည်။ interface သည် errors များကို throw လုပ်မည်၊ အကြောင်းမှာ `elementDrag` နှင့် `stopElementDrag` functions မဖန်တီးရသေးသောကြောင့်ဖြစ်သည်။ အခုတော့ ၎င်းတို့ကို ဖန်တီးပါ။
## elementDrag နှင့် stopElementDrag functions
သင်၏ closure ကို ပြီးစီးရန် အပင်ကို drag လုပ်သောအခါနှင့် drag လုပ်မှုကို ရပ်တန့်သောအခါ ဖြစ်ပျက်မည့်အရာများကို စီမံခန့်ခွဲမည့် internal functions နှစ်ခုကို ထည့်သွင်းမည်။ သင်လိုချင်သော behavior သည် အပင်တစ်ခုစီကို မည်သည့်အချိန်တွင်မဆို drag လုပ်နိုင်ပြီး screen ပေါ်တွင် မည်သည့်နေရာတွင်မဆိုထားနိုင်ရန်ဖြစ်သည်။ ဒီ interface သည် drop zone မပါသော un-opinionated ဖြစ်သည်။ သင်၏ terrarium ကို စိတ်ကြိုက်ဒီဇိုင်းဆွဲနိုင်ရန် အပင်များကို ထည့်သွင်း၊ ဖယ်ရှား၊ ပြန်လည်ထားရှိနိုင်သည်။
သင်၏ closure ကို ပြီးစီးရန် drag လုပ်သောအခါနှင့် drag ရပ်သောအခါ ဖြစ်ပျက်မည့်အရာများကို စီမံခန့်ခွဲမည့် internal functions နှစ်ခုကို ထည့်သွင်းပါ။ သင်လိုချင်သော behavior သည် အပင်တစ်ခုစီကို မည်သည့်အချိန်တွင်မဆို drag လုပ်နိုင်ပြီး screen ပေါ်တွင် မည်သည့်နေရာတွင်မဆိုထားနိုင်ရန် ဖြစ်သည်။ ဒီ interface သည် drop zone မပါသောကြောင့် သင့် terrarium ကို အပင်များထည့်၊ ဖယ်ရှား၊ ပြန်လည်တည်နေရာချထားခြင်းဖြင့် မိမိစိတ်ကြိုက် ဖန်တီးနိုင်သည်။
### လုပ်ဆောင်ရန်
`pointerDrag` ၏ closing curly bracket အောက်တွင် `elementDrag` function ကို ထည့်ပါ။
`pointerDrag` ၏ closing curly bracket အောက်တွင် `elementDrag` function ကို ထည့်သွင်းပါ။
```javascript
function elementDrag(e) {
@ -176,18 +175,17 @@ function elementDrag(e) {
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
}
```
ဒီ function အတွင်း သင်သည် initial positions 1-4 ကို ပြင်ဆင်ထားသည်။ ဒီမှာ ဘာဖြစ်နေလဲ?
ဒီ function တွင် သင်သည် အစပိုင်းတွင် local variables 1-4 ကို ပြင်ဆင်ထားသည်။ ဒီမှာ ဘာဖြစ်နေလဲ?
Drag လုပ်သောအခါ `pos1` ကို `pos3` (သင်အရင်က `e.clientX` အဖြစ် သတ်မှတ်ထားသည်) နှင့် လက်ရှိ `e.clientX` တန်ဖိုးကို လျော့ချခြင်းဖြင့် ပြန်လည် assign လုပ်သည်။ `pos2` ကိုလည်း အတူတူလုပ်ဆောင်သည်။ ထို့နောက် `pos3` နှင့် `pos4` ကို element ၏ X နှင့် Y coordinates အသစ်များသို့ ပြန်လည်သတ်မှတ်သည်။ ဒီပြောင်းလဲမှုများကို console တွင် drag လုပ်နေစဉ် ကြည့်နိုင်သည်။ ထို့နောက် `pos1` နှင့် `pos2` ၏ positions အသစ်များကို အပင်၏ css style ကို ပြောင်းလဲခြင်းဖြင့် top နှင့် left X နှင့် Y coordinates ကို သတ်မှတ်သည်။
Drag လုပ်သောအခါ၊ `pos1` ကို `pos3` (အရင်က `e.clientX` အဖြစ် set လုပ်ထားသည်) နှင့် လက်ရှိ `e.clientX` တန်ဖိုးကို လျှော့ချခြင်းဖြင့် ပြန်လည် assign လုပ်သည်။ `pos2` ကိုလည်း အတူတူလုပ်ဆောင်သည်။ ထို့နောက်၊ `pos3` နှင့် `pos4` ကို element ၏ X နှင့် Y coordinates အသစ်များသို့ ပြန်လည် reset လုပ်သည်။ drag လုပ်နေစဉ်၊ console တွင် ဒီပြောင်းလဲမှုများကို ကြည့်နိုင်သည်။ ထို့နောက်၊ plant ၏ css style ကို ပြောင်းလဲပြီး၊ `pos1` နှင့် `pos2` ၏ တန်ဖိုးအသစ်များအပေါ်မူတည်၍ top နှင့် left X နှင့် Y coordinates ကို သတ်မှတ်သည်။
> `offsetTop` နှင့် `offsetLeft` သည် element ၏ parent position ကို အခြေခံ၍ position ကို သတ်မှတ်သော CSS properties ဖြစ်သည်။
> `offsetTop` နှင့် `offsetLeft` သည် element ၏ parent ၏ position အပေါ်မူတည်၍ position ကို သတ်မှတ်သော CSS properties ဖြစ်သည်။ parent သည် `static` မဟုတ်သော position ဖြစ်နိုင်သည်။
ဒီ positioning ကို ပြန်လည်တွက်ချက်ခြင်းအားလုံးသည် terrarium နှင့် ၎င်း၏ အပင်များ၏ behavior ကို စနစ်တကျ ပြုလုပ်ရန် အထောက်အကူပြုသည်။
ဒီ position များကို ပြန်လည်တွက်ချက်ခြင်းသည် terrarium နှင့် ၎င်း၏ plants ၏ behavior ကို စိတ်ကြိုက်ပြုလုပ်ရန် ခွင့်ပြုသည်။
### လုပ်ဆောင်ရန်
### လုပ်ဆောင်ရန်
interface ကို ပြီးစီးရန် နောက်ဆုံးလုပ်ဆောင်ရန်မှာ `elementDrag` ၏ closing curly bracket အောက်တွင် `stopElementDrag` function ကို ထည့်သွင်းပါ။
interface ကို ပြီးစီးရန် `elementDrag` ၏ closing curly bracket အောက်တွင် `stopElementDrag` function ကို ထည့်သွင်းပါ။
```javascript
function stopElementDrag() {
@ -196,35 +194,37 @@ function stopElementDrag() {
}
```
ဒီ function သေးငယ်သည် `onpointerup` နှင့် `onpointermove` events များကို reset လုပ်သည်။ ၎င်းသည် သင်၏ plant ၏ progress ကို ပြန်လည်စတင်ရန် (သို့) အပင်အသစ်ကို drag လုပ်ရန် ခွင့်ပြုသည်။
ဒီ function သေးငယ်သည် `onpointerup` နှင့် `onpointermove` events များကို reset လုပ်ပြီး၊ သင်၏ အပင်၏ progress ကို ပြန်လည်စတင်ရန် သို့မဟုတ် အပင်အသစ်ကို drag လုပ်ရန် စတင်နိုင်သည်။
✅ ဒီ events များကို null သို့ set မလုပ်ပါက ဘာဖြစ်မည်?
✅ ဒီ events များကို null သတ်မှတ်မထားပါက ဘာဖြစ်မည်?
အခုတော့ သင်၏ project ကို ပြီးစီးပါပြီ!
အခုတော့ သင်၏ project ကို ပြီးစီးခဲ့ပါပြီ!
🥇ဂုဏ်ယူပါတယ်! သင်၏လှပသော terrarium ကို ပြီးစီးပါပြီ။ ![finished terrarium](../../../../translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.my.png)
🥇ဂုဏ်ယူပါတယ်! သင်၏လှပသော terrarium ကို ပြီးစီးခဲ့ပါပြီ။ ![finished terrarium](../../../../translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.my.png)
---
## 🚀စိန်ခေါ်မှု
သင်၏ closure တွင် event handler အသစ်ထည့်သွင်းပြီး အပင်များအပေါ် အခြားအရာများပြုလုပ်ပါ။ ဥပမာအားဖြင့် အပင်ကို double-click လုပ်ပြီး အပင်ကို အရှေ့ဘက်သို့ ရောက်စေပါ။ စိတ်ဖန်တီးမှုရှိပါစေ!
သင်၏ closure တွင် event handler အသစ်ထည့်သွင်းပြီး အပင်များအပေါ် အပိုလုပ်ဆောင်မှုများပြုလုပ်ပါ။ ဥပမာအားဖြင့် အပင်ကို double-click လုပ်ပြီး အပင်ကို အရှေ့ဘက်သို့ ရောက်စေပါ။ ဖန်တီးမှုအတွက် စိတ်ကြိုက်လုပ်ဆောင်ပါ!
## မိမိသင်ခန်းစာပြီးနောက် စမ်းမေးခွန်း
## မိမိကိုယကို စမ်းမေးခွန်း
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/20)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
Element များကို screen ပေါ်တွင် drag လုပ်ခြင်းသည် ရိုးရှင်းသည့်အရာဖြစ်သော်လည်း၊ ၎င်းကို ပြုလုပ်ရန် နည်းလမ်းများစွာရှိပြီး၊ သင်လိုချင်သော effect အပေါ်မူတည်၍ အခက်အခဲများစွာရှိနိုင်သည်။ အမှန်တကယ် [drag and drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) တစ်ခုလုံးရှိသည်။ ဒီ module တွင် ကျွန်ုပ်တို့မသုံးခဲ့သောကြောင့်၊ ကျွန်ုပ်တို့လိုချင်သော effect သည် ကွဲပြားနေသည်။ သို့သော် သင်၏ project တွင် ဒီ API ကို စမ်းသုံးပြီး ဘာတွေပြုလုပ်နိုင်သည်ကို ကြည့်ပါ။
Elements များကို screen ပေါ်တွင် drag လုပ်ခြင်းသည် ရိုးရှင်းသော်လည်း၊ ၎င်းကို ပြုလုပ်ရန် နည်းလမ်းများစွာရှိပြီး၊ သင်လိုချင်သော effect အပေါ်မူတည်၍ အခက်အခဲများရှိနိုင်သည်။ အမှန်တကယ် [drag and drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) တစ်ခုလုံးရှိသည်။ ဒီ module တွင် ၎င်းကို မသုံးခဲ့ရသည့်အကြောင်းမှာ ကျွန်ုပ်တို့လိုချင်သော effect သည် ကွဲပြားခြားားသာကြောင့်ဖြစ်သည်။ သို့သော် သင်၏ကိုယ်ပိုင် project တွင် API ကို စမ်းသုံးပြီး ဘာတွေ ပြုလုပ်နိုင်သည်ကို ကြည့်ပါ။
Pointer events အကြောင်းကို [W3C docs](https://www.w3.org/TR/pointerevents1/) နှင့် [MDN web docs](https://developer.mozilla.org/docs/Web/API/Pointer_events) တွင် ပိုမိုလေ့လာပါ။
Browser capabilities ကို [CanIUse.com](https://caniuse.com/) တွင် အမြဲစစ်ဆေးပါ။
## လုပ်ဆောင်ရန်
[DOM နှင့် ပိုမိုလုပ်ဆောင်ပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရ အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူလဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,65 +1,63 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e982871b8388c59c22a41b73b5fca70f",
"translation_date": "2025-08-27T22:45:02+00:00",
"original_hash": "1b0aeccb600f83c603cd70cb42df594d",
"translation_date": "2025-08-28T18:48:48+00:00",
"source_file": "4-typing-game/typing-game/README.md",
"language_code": "my"
}
-->
# အဖြစ်အပျက်များကို အသုံးပြု၍ ဂိမ်းတစ်ခု ဖန်တီးခြင်း
## မိန့်ခွန်းမပြောမီ စစ်ဆေးမေးခွန်
## မျှဝေမည့် မေးခွန်းမျာ
[ိန့်ခွန်းမပြောမီ စစ်ဆေးမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/21)
[ေးခွန်းများ](https://ff-quizzes.netlify.app/web/quiz/21)
## အဖြစ်အပျက်အခြေပြု ပရိုဂရမ်ရေးသားမှု
Browser အခြေပြု အက်ပလီကေးရှင်းတစ်ခု ဖန်တီးရာတွင် အသုံးပြုသူများအတွက် ဂရပ်ဖစ်အသုံးပြုသူအင်တာဖေ့စ် (GUI) တစ်ခုကို ပံ့ပိုးပေးရမည်ဖြစ်သည်။ Browser နှင့် အပြန်အလှန်ဆက်သွယ်ရာတွင် အများဆုံးအသုံးပြုသောနည်းလမ်းမှာ အမျိုးမျိုးသောအရာများကို နှိပ်ခြင်းနှင့် ရိုက်ထည့်ခြင်းဖြစ်သည်။ Developer အနေဖြင့် ကျွန်ုပ်တို့ကြုံရသော စိန်ခေါ်မှုမှာ သူတို့သည် အချိန်မရွေး အဲဒီလုပ်ဆောင်မှုများကို ပြုလုပ်မည်ကို မသိနိုင်ခြင်းဖြစ်သည်။
Browser အခြေပြု အက်ပလီကေးရှင်းတစ်ခု ဖန်တီးရာတွင် အသုံးပြုသူများအတွက် ဂရပ်ဖစ်အသုံးပြုသူအင်တာဖေ့စ် (GUI) တစ်ခုကို ပံ့ပိုးပေးရမည်ဖြစ်သည်။ Browser နှင့် အပြန်အလှန်ဆက်သွယ်ရာတွင် အများဆုံးအသုံးပြုသောနည်းလမ်းမှာ ခလုတ်နှိပ်ခြင်းနှင့် အမျိုးမျိုးသောအရာများတွင် ရိုက်ထည့်ခြင်းဖြစ်သည်။ Developer အနေနဲ့ ကြုံရတဲ့ စိန်ခေါ်မှုကတော့ သူတို့ ဘယ်အချိန်မှာ ဒီအရာတွေကို လုပ်မယ်ဆိုတာ မသိနိုင်တာပဲ ဖြစ်ပါတယ်။
[အဖြစ်အပျက်အခြေပြု ပရိုဂရမ်ရေးသားမှု](https://en.wikipedia.org/wiki/Event-driven_programming) သည် ကျွန်ုပ်တို့၏ GUI ကို ဖန်တီးရန် လိုအပ်သော ပရိုဂရမ်ရေးသားမှုအမျိုးအစားအတွက် အမည်ဖြစ်သည်။ ဒီစကားစုကို နည်းနည်းခွဲစိတ်ကြည့်ပါက အဓိကစကားလုံးမှာ **အဖြစ်အပျက်** ဖြစ်သည်ကို တွေ့ရမည်။ Merriam-Webster အဆိုအရ [အဖြစ်အပျက်](https://www.merriam-webster.com/dictionary/event) ကို "တစ်ခုခုဖြစ်ပျက်ခြင်း" ဟု အဓိပ္ပါယ်ဖွင့်ဆိုထားသည်။ ဒါက ကျွန်ုပ်တို့ရဲ့ အခြေအနေကို အတိအကျ ဖော်ပြထားတာဖြစ်ပါတယ်။ ကျွန်ုပ်တို့သည် တစ်ခုခုဖြစ်ပျက်မည်ကို သိပြီး၊ အဲဒီအတွက် ကုဒ်တစ်ခုကို တုံ့ပြန်အကောင်အထည်ဖော်လိုသော်လည်း၊ အဲဒါ ဘယ်အချိန်မှာ ဖြစ်မည်ကို မသိနိုင်ပါ
[အဖြစ်အပျက်အခြေပြု ပရိုဂရမ်ရေးသားမှု](https://en.wikipedia.org/wiki/Event-driven_programming) ဆိုတာကတော့ GUI ဖန်တီးဖို့ လိုအပ်တဲ့ ပရိုဂရမ်ရေးသားမှုအမျိုးအစားကို ဆိုလိုတာဖြစ်ပါတယ်။ ဒီစကားကို နည်းနည်းခွဲကြည့်မယ်ဆိုရင် အဓိကစကားလုံးက **အဖြစ်အပျက်** ဖြစ်ပါတယ်။ Merriam-Webster အဆိုအရ [အဖြစ်အပျက်](https://www.merriam-webster.com/dictionary/event) ဆိုတာ "တစ်ခုခုဖြစ်ပျက်ခြင်း" လို့ အဓိပ္ပါယ်ဖွင့်ဆိုထားပါတယ်။ ဒါကတော့ ကျွန်တော်တို့ရဲ့ အခြေအနေကို အတိအကျ ဖော်ပြထားတာပါပဲ။ ကျွန်တော်တို့ သိတာက တစ်ခုခုဖြစ်ပျက်မယ်၊ ဒါပေမယ့် ဘယ်အချိန်မှာ ဖြစ်မယ်ဆိုတာတော့ မသိပါဘူး
ကျွန်ုပ်တို့ အကောင်အထည်ဖော်လိုသည့် ကုဒ်ပိုင်းကို သတ်မှတ်ရန် နည်းလမ်းမှာ function တစ်ခု ဖန်တီးခြင်းဖြစ်သည်။ [Procedural programming](https://en.wikipedia.org/wiki/Procedural_programming) အတွင်း function များကို အတိအကျ အစဉ်လိုက် ခေါ်သုံးရသည်ဟု တွေးပါ။ အဖြစ်အပျက်အခြေပြု ပရိုဂရမ်ရေးသားမှုတွင်လည်း အဲဒီအရာတူညီပါသည်။ ကွာခြားချက်မှာ function များကို **ဘယ်လို** ခေါ်သုံးမည်ဆိုတာပဲ ဖြစ်သည်
ကျွန်တော်တို့ လုပ်ဆောင်လိုတဲ့ ကုဒ်အပိုင်းကို သတ်မှတ်ဖို့ နည်းလမ်းကတော့ function တစ်ခု ဖန်တီးခြင်းဖြစ်ပါတယ်။ [Procedural programming](https://en.wikipedia.org/wiki/Procedural_programming) ကို စဉ်းစားကြည့်မယ်ဆိုရင် function တွေကို အတိအကျ အစဉ်လိုက် ခေါ်သုံးရပါတယ်။ အဖြစ်အပျက်အခြေပြု ပရိုဂရမ်ရေးသားမှုမှာလည်း ဒီအရာတူတူပဲ ဖြစ်ပါတယ်။ ကွာခြားချက်ကတော့ function တွေကို **ဘယ်လို** ခေါ်သုံးမလဲ ဆိုတာပါ
အဖြစ်အပျက်များ (button နှိပ်ခြင်း၊ ရိုက်ထည့်ခြင်း စသည်) ကို ကိုင်တွယ်ရန် ကျွန်ုပ်တို့သည် **အဖြစ်အပျက်နားထောင်သူများ** (event listeners) ကို မှတ်ပုံတင်ရမည်။ အဖြစ်အပျက်နားထောင်သူသည် အဖြစ်အပျက်တစ်ခု ဖြစ်ပေါ်လာသည်ကို နားထောင်ပြီး၊ အဲဒီအတွက် တုံ့ပြန်မှုအနေဖြင့် လုပ်ဆောင်မှုတစ်ခုကို အကောင်အထည်ဖော်သည်။ အဖြစ်အပျက်နားထောင်သူများသည် UI ကို အပ်ဒိတ်လုပ်ခြင်း၊ server ကို ခေါ်ဆိုခြင်း သို့မဟုတ် အသုံးပြုသူ၏ လုပ်ဆောင်မှုအတွက် လိုအပ်သော အခြားအရာများကို ပြုလုပ်နိုင်သည်။ ကျွန်ုပ်တို့သည် [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) ကို အသုံးပြု၍ အဖြစ်အပျက်နားထောင်သူကို ထည့်သွင်းပြီး၊ လုပ်ဆောင်ရန် function ကို ပံ့ပိုးပေးသည်။
အဖြစ်အပျက်များ (ခလုတ်နှိပ်ခြင်း၊ ရိုက်ထည့်ခြင်း စသဖြင့်) ကို ကိုင်တွယ်ဖို့ ကျွန်တော်တို့ **အဖြစ်အပျက်နားထောင်သူများ** (event listeners) ကို မှတ်ပုံတင်ရမည်ဖြစ်သည်။ အဖြစ်အပျက်နားထောင်သူဆိုတာ အဖြစ်အပျက်တစ်ခု ဖြစ်ပေါ်လာမည့်အချိန်ကို နားထောင်ပြီး အဖြစ်အပျက်ဖြစ်ပေါ်လာသည်နှင့်အတူ လိုက်လုပ်ဆောင်မည့် function တစ်ခုဖြစ်သည်။ အဖြစ်အပျက်နားထောင်သူများသည် UI ကို အပ်ဒိတ်လုပ်ခြင်း၊ server ကို ခေါ်ဆိုခြင်း သို့မဟုတ် အသုံးပြုသူ၏ လုပ်ဆောင်မှုအပေါ် မည်သည့်အရာကိုမဆို လိုက်လုပ်ဆောင်နိုင်သည်။ ကျွန်တော်တို့ [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) ကို အသုံးပြု၍ အဖြစ်အပျက်နားထောင်သူတစ်ခု ထည့်သွင်းပြီး လိုက်လုပ်ဆောင်မည့် function ကို ပံ့ပိုးပေးနိုင်သည်။
> **NOTE:** အဖြစ်အပျက်နားထောင်သူများကို ဖန်တီးရန် နည်းလမ်းများစွာ ရှိသည်ကို သတိပြုပါ။ သင်သည် anonymous functions ကို အသုံးပြုနိုင်သလို၊ မည်ပေးထားသော function များကိုလည်း ဖန်တီးနိုင်သည်။ `click` property ကို သတ်မှတ်ခြင်း၊ သို့မဟုတ် `addEventListener` ကို အသုံးပြုခြင်းကဲ့သို့သော shortcut များကိုလည်း အသုံးပြုနိုင်သည်။ ကျွန်ုပ်တို့၏ လေ့ကျင့်ခန်းတွင် `addEventListener` နှင့် anonymous functions ကို အဓိကထားမည်ဖြစ်သည်၊ အကြောင်းမှာ ဒါဟာ web developers များအကြား အများဆုံးအသုံးပြုသော နည်းလမ်းဖြစ်ပြီး၊ အလွန်ပြောင်းလွယ်ပြင်လွယ်သော နည်းလမ်းဖြစ်သည်။ `addEventListener` သည် အဖြစ်အပျက်အားလုံးအတွက် အလုပ်လုပ်နိုင်ပြီး၊ အဖြစ်အပျက်အမည်ကို parameter အဖြစ် ပံ့ပိုးပေးနိုင်သည်။
> **NOTE:** အဖြစ်အပျက်နားထောင်သူများ ဖန်တီးရန် နည်းလမ်းများစွာ ရှိသည်ကို သတိပြုပါ။ သင်သည် anonymous functions ကို အသုံးပြုနိုင်သလို၊ နာမည်ပေးထားသော function များကိုလည်း ဖန်တီးနိုင်သည်။ `click` property ကို သတ်မှတ်ခြင်း၊ သို့မဟုတ် `addEventListener` ကို အသုံးပြုခြင်းကဲ့သို့ shortcut များကိုလည်း အသုံးပြုနိုင်သည်။ ကျွန်တော်တို့ရဲ့ လေ့ကျင့်ခန်းမှာ `addEventListener` နှင့် anonymous functions ကို အဓိကထားပြီး လေ့လာသွားမှာဖြစ်ပါတယ်။ ဒါကတော့ အများဆုံး အသုံးပြုတဲ့ နည်းလမ်းဖြစ်သလို၊ အလွန်ပြောင်းလွယ်ပြင်လွယ်လည်း ဖြစ်ပါတယ်။ `addEventListener` က အဖြစ်အပျက်အားလုံးအတွက် အလုပ်လုပ်နိုင်ပြီး၊ အဖြစ်အပျက်နာမည်ကို parameter အနေနဲ့ ပံ့ပိုးပေးနိုင်ပါတယ်။
### ရိုးရိုးတွေ့ရသော အဖြစ်အပျက်များ
### ရိုးရိုးတွေ့ရတဲ့ အဖြစ်အပျက်များ
[အဖြစ်အပျက်များ](https://developer.mozilla.org/docs/Web/Events) အများအပြားကို သင်၏ အက်ပ်လီကေးရှင်း ဖန်တီးရာတွင် နားထောင်နိုင်သည်။ စာမျက်နှာပေါ်တွင် အသုံးပြုသူတစ်ဦး ပြုလုပ်သည့် အရာတိုင်းသည် အဖြစ်အပျက်တစ်ခုကို ဖြစ်ပေါ်စေပြီး၊ သင်၏ အသုံးပြုသူများအတွက် လိုအပ်သော အတွေ့အကြုံကို ပံ့ပိုးပေးရန် အလွန်အာဏာရှိသည်။ ကံကောင်းစွာ၊ သင်သည် အဖြစ်အပျက်အနည်းငယ်သာ လိုအပ်လိမ့်မည်။ ဂိမ်းဖန်တီးရာတွင် အသုံးပြုမည့် အဖြစ်အပျက်များအနက် အချို့ကို အောက်တွင် ဖော်ပြထားသည်-
[အဖြစ်အပျက်များ](https://developer.mozilla.org/docs/Web/Events) အများအပြားကို သင့်အက်ပလီကေးရှင်း ဖန်တီးရာတွင် နားထောင်နိုင်ပါတယ်။ မူလအားဖြင့် အသုံးပြုသူတစ်ဦးက စာမျက်နှာပေါ်မှာ လုပ်ဆောင်သမျှဟာ အဖြစ်အပျက်တစ်ခုကို ဖြစ်ပေါ်စေပါတယ်။ ဒါကတော့ သင့်ရဲ့ အက်ပလီကေးရှင်းကို အသုံးပြုသူအတွက် လိုအပ်တဲ့ အတွေ့အကြုံကို ပေးနိုင်ဖို့ အလွန်အကျိုးရှိပါတယ်။ ကံကောင်းစွာ၊ သင့်အနေနဲ့ အဖြစ်အပျက်အများအပြားကို မလိုအပ်ပါဘူး။ အောက်တွင် ရိုးရိုးတွေ့ရတဲ့ အဖြစ်အပျက်အချို့ကို ဖော်ပြထားပါတယ် (ကျွန်တော်တို့ ဂိမ်းဖန်တီးရာမှာ အသုံးပြုမည့် နှစ်ခုလည်း ပါဝင်ပါတယ်)။
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): အသုံးပြုသူသည် button သို့မဟုတ် hyperlink တစ်ခုကို နှိပ်ခြင်း
- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): အသုံးပြုသူသည် ညာဘက်မောက်စ်ခလုတ်ကို နှိပ်ခြင်း
- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): အသုံးပြုသူသည် စာသားတစ်ခုကို highlight ပြုလုပ်ခြင်း
- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): အသုံးပြုသူသည် စာသားတစ်ခုကို ရိုက်ထည့်ခြင်း
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): အသုံးပြုသူက တစ်ခုခု (အထူးသဖြင့် ခလုတ် သို့မဟုတ် hyperlink) ကို နှိပ်လိုက်သည်
- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): အသုံးပြုသူက ညာဘက်မောက်စ်ခလုတ်ကို နှိပ်လိုက်သည်
- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): အသုံးပြုသူက စာသားတစ်ခုခုကို အထူးပြုရွေးချယ်လိုက်သည်
- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): အသုံးပြုသူက စာသားတစ်ခုခုကို ရိုက်ထည့်လိုက်သည်
## ဂိမ်းဖန်တီးခြင်း
ကျွန်ုပ်တို့သည် JavaScript တွင် အဖြစ်အပျက်များ အလုပ်လုပ်ပုံကို လေ့လာရန် ဂိမ်းတစ်ခု ဖန်တီးမည်။ ဂိမ်းသည် developer များအတွက် အရေးကြီးသော typing ကျွမ်းကျင်မှုကို စမ်းသပ်မည်ဖြစ်သည်။ Developer အားလုံးသည် typing ကျွမ်းကျင်မှုကို လေ့ကျင့်ထားသင့်သည်။ ဂိမ်း၏ အခြေခံစီးဆင်းမှုမှာ အောက်ပါအတိုင်းဖြစ်သည်-
ကျွန်တော်တို့ JavaScript မှာ အဖြစ်အပျက်တွေ ဘယ်လိုအလုပ်လုပ်တယ်ဆိုတာကို လေ့လာဖို့ ဂိမ်းတစ်ခု ဖန်တီးသွားမှာဖြစ်ပါတယ်။ ဂိမ်းရဲ့ အဓိကရည်ရွယ်ချက်ကတော့ Developer အားလုံးအတွက် အရေးကြီးတဲ့ typing ကျွမ်းကျင်မှုကို စမ်းသပ်ဖို့ ဖြစ်ပါတယ်။ Developer အားလုံးအနေနဲ့ typing ကို အမြဲလေ့ကျင့်နေဖို့ လိုပါတယ်! ဂိမ်းရဲ့ အထွေထွေစီးဆင်းမှုက အောက်ပါအတိုင်း ဖြစ်ပါမည်-
- Player သည် start button ကို နှိပ်ပြီး ရိုက်ရန် စာပိုဒ်တစ်ခုကို ကြည့်ရှုရမည်
- Player သည် စာပိုဒ်ကို အမြန်ဆုံး ရိုက်ရမည်
- Player က start ခလုတ်ကို နှိပ်ပြီး ရိုက်ထည့်ရန် စာပိုဒ်တစ်ခုကို ကြည့်နိုင်မည်
- Player က စာပိုဒ်ကို အမြန်ဆုံး ရိုက်ထည့်မည်
- စကားလုံးတစ်လုံးပြီးတိုင်း နောက်တစ်လုံးကို highlight ပြုလုပ်မည်
- Player တွင် စာလုံးပေါင်းအမှားရှိပါက textbox ကို အနီရောင်ပြောင်းမည်
- Player သည် စာပိုဒ်ကို ပြီးမြောက်ပါက အောင်မြင်မှုစာသားနှင့် ကြာချိန်ကို ပြသမည်
- Player မှာ typo ရှိရင် textbox ကို အနီရောင်ပြောင်းမည်
- Player က စာပိုဒ်ကို ပြီးမြောက်စွာ ရိုက်ပြီးပါက အောင်မြင်မှုစာသားနှင့် ကြာချိန်ကို ပြသမည်
အခု ကျွန်ုပ်တို့၏ ဂိမ်းကို ဖန်တီးပြီး အဖြစ်အပျက်များကို လေ့လာကြစို့!
- [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) ကို အသုံးပြုပြီး အမြင့်ဆုံးအမှတ်များကို သိမ်းဆည်းပါ။
အခု ကျွန်တော်တို့ရဲ့ ဂိမ်းကို ဖန်တီးပြီး အဖြစ်အပျက်များကို လေ့လာကြရအောင်!
## မျှဝေပြီးနောက် စမ်းမေးခွန်း
## မိန့်ခွန်းပြီးနောက် မေးခွန်းများ
[မျှဝေပြီးနောက် စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/22)
[မိန့်ခွန်းပြီးနောက် မေးခွန်းများ](https://ff-quizzes.netlify.app/web/quiz/22)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာမှု
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
[ဝဘ်ဘရောက်ဆာမှ အသုံးပြုနိုင်သော အဖြစ်အပျက်များအားလုံး](https://developer.mozilla.org/docs/Web/Events) ကိုဖတ်ရှုပါ၊ သင့်အနေဖြင့် တစ်ခုချင်းစီကို မည်သည့်အခြေအနေတွင် အသုံးပြုမည်ကို စဉ်းစားကြည့်ပါ။
[ဝဘ်ဘရောက်ဆာမှတဆင့်](https://developer.mozilla.org/docs/Web/Events) ဖွင့်နိုင်သော အဖြစ်အပျက်များအားလုံးကို ဖတ်ရှုပါ၊ သင့်အနေဖြင့် တစ်ခုချင်းစီကို မည်သည့်အခြေအနေတွင် အသုံးပြုမည်ကို စဉ်းစားပါ။
## လုပ်ငန်းတာဝန်
## အိမ်စာ
[ကီးဘုတ်ဂိမ်းအသစ်တစ်ခု ဖန်တီးပါ](assignment.md)
[အသစ်သော ကီးဘုတ်ဂိမ်းတစ်ခု ဖန်တီးပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူလဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေပါသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "0bb55e0b98600afab801eea115228873",
"translation_date": "2025-08-27T22:10:05+00:00",
"original_hash": "2326d04e194a10aa760b51f5e5a1f61d",
"translation_date": "2025-08-28T18:34:11+00:00",
"source_file": "5-browser-extension/1-about-browsers/README.md",
"language_code": "my"
}
@ -12,100 +12,100 @@ CO_OP_TRANSLATOR_METADATA:
![Browser sketchnote](../../../../translated_images/browser.60317c9be8b7f84adce43e30bff8d47a1ae15793beab762317b2bc6b74337c1a.my.jpg)
> Sketchnote by [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob)
## မိမိကိုယ်ကိုစစ်မေးရန်မေးခွန်းမျာ
## မိန့်ခွန်းမတင်မီ စမ်းမေးခွန်
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/23)
[မိန့်ခွန်းမတင်မီ စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/23)
### အကျဉ်းချုပ်
### နိဒါန်း
Browser Extension များသည် Browser တွင်အပိုလုပ်ဆောင်ချက်များထည့်သွင်းပေးနိုင်သည်။ Browser Extension တစ်ခုကိုတည်ဆောက်မည်ဆိုပါက Browser များအလုပ်လုပ်ပုံကိုအရင်လေ့လာသင့်သည်။
Browser Extension များသည် Browser တွင် အပိုလုပ်ဆောင်ချက်များကို ထည့်သွင်းပေးနိုင်သည်။ သို့သော် Browser Extension တစ်ခုကို တည်ဆောက်မီ Browser များ၏ လုပ်ဆောင်ပုံကို အနည်းငယ်လေ့လာသင့်သည်။
### Browser အကြောင်း
ဒီသင်ခန်းစာများတွင် Chrome, Firefox, Edge Browser များတွင်အလုပ်လုပ်နိုင်သော Browser Extension တစ်ခုကိုတည်ဆောက်ပုံကိုလေ့လာမည်ဖြစ်သည်။ ဒီအပိုင်းတွင် Browser များအလုပ်လုပ်ပုံနှင့် Browser Extension ၏အခြေခံဖွဲ့စည်းမှုများကိုလေ့လာမည်ဖြစ်သည်။
ဒီသင်ခန်းစာများတွဲတွင် Chrome, Firefox, Edge Browser များတွင် အလုပ်လုပ်နိုင်သော Browser Extension တစ်ခုကို ဘယ်လိုတည်ဆောက်ရမည်ကို သင်လေ့လာမည်ဖြစ်သည်။ ဒီအပိုင်းတွင် Browser များ၏ လုပ်ဆောင်ပုံနှင့် Browser Extension ၏ အခြေခံဖွဲ့စည်းမှုများကို ရှာဖွေမည်ဖြစ်သည်။
Browser ဆိုတာဘာလဲ? ဒါဟာ End User တစ်ဦးက Server မှအကြောင်းအရာများကိုရယူပြီး Web Page များပေါ်တွင်ပြသနိုင်စေသော Software Application တစ်ခုဖြစ်သည်။
Browser ဆိုတာ တကယ်တော့ ဘာလဲ? ၎င်းသည် အသုံးပြုသူများကို Server မှ အကြောင်းအရာများကို ရယူပြီး Web Page များပေါ်တွင် ပြသပေးနိုင်သော Software Application တစ်ခုဖြစ်သည်။
✅ သမိုင်းအနည်းငယ်: ပထမဆုံး Browser ကို 'WorldWideWeb' ဟုခေါ်ပြီး Sir Timothy Berners-Lee က 1990 ခုနှစ်တွင်ဖန်တီးခဲ့သည်။
✅ သမိုင်းအနည်းငယ်: ပထမဆုံး Browser ကို 'WorldWideWeb' ဟု ခေါ်ပြီး Sir Timothy Berners-Lee က 1990 ခုနှစ်တွင် ဖန်တီးခဲ့သည်။
![early browsers](../../../../translated_images/earlybrowsers.d984b711cdf3a42ddac919d46c4b5ca7232f68ccfbd81395e04e5a64c0015277.my.jpg)
> Some early browsers, via [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
> အစောပိုင်း Browser များ၊ [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing) မှ
User တစ်ဦးက URL (Uniform Resource Locator) လိပ်စာကိုအသုံးပြု၍ အင်တာနက်နှင့်ချိတ်ဆက်သောအခါ၊ `http` သို့မဟုတ် `https` လိပ်စာကိုအသုံးပြု၍ Hypertext Transfer Protocol ဖြင့် Web Server နှင့်ဆက်သွယ်ပြီး Web Page ကိုရယူသည်။
အသုံးပြုသူတစ်ဦးသည် URL (Uniform Resource Locator) လိပ်စာကို အသုံးပြု၍ အင်တာနက်နှင့် ချိတ်ဆက်သောအခါ၊ အများအားဖြင့် Hypertext Transfer Protocol (`http` သို့မဟုတ် `https`) ကို အသုံးပြု၍ Browser သည် Web Server နှင့် ဆက်သွယ်ပြီး Web Page ကို ရယူသည်။
ဒီအချိန်တွင် Browser ၏ Rendering Engine က User ၏ Device (မိုဘိုင်းဖုန်း, Desktop, Laptop စသည်တို့) ပေါ်တွင် Web Page ကိုပြသပေးသည်။
ဒီအချိန်တွင် Browser ၏ Rendering Engine သည် ၎င်းကို အသုံးပြုသူ၏ စက်ပေါ်တွင် ပြသပေးသည်။ ၎င်းသည် မိုဘိုင်းဖုန်း၊ Desktop သို့မဟုတ် Laptop တစ်ခုဖြစ်နိုင်သည်။
Browser များတွင် Content ကို Cache လုပ်ထားနိုင်သောစွမ်းရည်ရှိပြီး Server မှအကြောင်းအရာများကိုအကြိမ်တိုင်းရယူရန်မလိုအပ်စေပါ။ User ၏ Browsing Activity ကိုမှတ်တမ်းတင်ထားနိုင်ပြီး 'Cookies' ဟုခေါ်သော Data အနည်းငယ်ကိုသိမ်းဆည်းထားနိုင်သည်။ Cookies တွင် User ၏လုပ်ဆောင်မှုများနှင့်ပတ်သက်သောအချက်အလက်များပါဝင်သည်။
Browser များတွင် Content ကို Cache လုပ်ထားနိုင်သော စွမ်းရည်လည်းရှိသည်။ ထို့ကြောင့် Server မှ အကြောင်းအရာကို အမြဲတမ်း ပြန်လည်ရယူရန် မလိုအပ်တော့ပေ။ ၎င်းတို့သည် အသုံးပြုသူ၏ Browsing Activity ကို မှတ်တမ်းတင်ထားနိုင်ပြီး 'Cookies' ဟုခေါ်သော အသေးစား Data များကို သိမ်းဆည်းထားနိုင်သည်။ ၎င်းတို့သည် အသုံးပြုသူ၏ လှုပ်ရှားမှုများကို သိမ်းဆည်းထားရန် အသုံးပြုသည်။
Browser များသည်တစ်ခုနှင့်တစ်ခုမတူကြောင်းသတိထားပါ။ Browser တစ်ခုစီတွင်အားသာချက်နှင့်အားနည်းချက်များရှိပြီး Professional Web Developer တစ်ဦးအနေဖြင့် Web Page များကို Cross-Browser တွင်အကောင်းဆုံးအလုပ်လုပ်စေရန်နားလည်ထားရန်လိုအပ်သည်။ ဒါတွင် မိုဘိုင်းဖုန်းကဲ့သို့သော Viewport သေးငယ်များကို Handle လုပ်ခြင်းနှင့် Offline ဖြစ်နေသော User များကို Handle လုပ်ခြင်းတို့ပါဝင်သည်။
Browser များသည် အားလုံးတူညီကြောင်း မဟုတ်ကြောင်း သတိထားပါ။ Browser တစ်ခုစီတွင် အားသာချက်နှင့် အားနည်းချက်များရှိပြီး Professional Web Developer တစ်ဦးအနေဖြင့် Web Page များကို Cross-Browser တွင် ကောင်းစွာ အလုပ်လုပ်စေရန် နားလည်ထားရန် လိုအပ်သည်။ ၎င်းတွင် မိုဘိုင်းဖုန်း၏ သေးငယ်သော Viewport များနှင့် Offline အသုံးပြုသူများကို ကိုင်တွယ်ခြင်းတို့ ပါဝင်သည်။
သင့်အကြိုက် Browser ကိုအသုံးပြု၍ Bookmark လုပ်ထားသင့်သော Website တစ်ခုက [caniuse.com](https://www.caniuse.com) ဖြစ်သည်။ Web Page များကိုတည်ဆောက်နေစဉ်တွင် caniuse ၏ Supported Technologies စာရင်းများကိုအသုံးပြုခြင်းသည် User များကိုအကောင်းဆုံး Support ပေးနိုင်ရန်အထောက်အကူဖြစ်သည်။
သင့်အကြိုက် Browser ကို အသုံးပြု၍ Bookmark ထားသင့်သော အလွန်အသုံးဝင်သော Website တစ်ခုမှာ [caniuse.com](https://www.caniuse.com) ဖြစ်သည်။ Web Page များကို တည်ဆောက်နေစဉ် caniuse ၏ Supported Technologies စာရင်းများကို အသုံးပြုခြင်းဖြင့် သင့်အသုံးပြုသူများကို အကောင်းဆုံးထောက်ပံ့နိုင်သည်။
✅ သင့် Website ၏ User Base တွင်အများဆုံးအသုံးပြုသော Browser များကိုဘယ်လိုသိနိုင်မလဲ? Analytics ကိုစစ်ဆေးပါ - Web Development Process ၏အစိတ်အပိုင်းအဖြစ် Analytics Package များကိုတပ်ဆင်နိုင်ပြီး Popular Browser များအားလုံးတွင်အများဆုံးအသုံးပြုသော Browser များကိုပြသပေးပါမည်။
✅ သင့် Website ၏ အသုံးပြုသူများအကြား ဘယ် Browser များ အများဆုံးလူကြိုက်များကြောင်း ဘယ်လိုသိနိုင်မလဲ? သင့် Analytics ကို စစ်ဆေးပါ - Web Development လုပ်ငန်းစဉ်တွင် Analytics Package များကို ထည့်သွင်းနိုင်ပြီး ၎င်းတို့သည် လူကြိုက်များသော Browser များကို ပြသပေးမည်။
## Browser Extension များ
Browser Extension တစ်ခုကိုဘယ်လိုတည်ဆောက်ချင်ရတာလဲ? သင်မကြာခဏလုပ်ဆောင်ရသော Tasks များကိုလွယ်ကူစွာရယူရန် Browser တွင်တပ်ဆင်ထားသောအရာတစ်ခုဖြစ်သည်။ ဥပမာအားဖြင့် Web Page များတွင်အရောင်များကိုစစ်ဆေးရန်လိုအပ်လျှင် Color-picker Browser Extension တစ်ခုကိုတပ်ဆင်နိုင်သည်။ Password များကိုမှတ်မိရန်အခက်အခဲရှိလျှင် Password-management Browser Extension ကိုအသုံးပြုနိုင်သည်။
Browser Extension တစ်ခုကို ဘာကြောင့် တည်ဆောက်ချင်ရသလဲ? ၎င်းသည် သင့် Browser တွင် ထပ်ခါထပ်ခါ လုပ်ဆောင်ရသော အလုပ်များကို အလွယ်တကူ လုပ်ဆောင်နိုင်ရန် အသုံးဝင်သည်။ ဥပမာအားဖြင့် သင့်အနေဖြင့် Web Page များတွင် အရောင်များကို စစ်ဆေးရန် လိုအပ်လျှင် Color-picker Browser Extension တစ်ခုကို ထည့်သွင်းနိုင်သည်။ သင့်အနေဖြင့် Password များကို မှတ်မိရန် အခက်အခဲရှိလျှင် Password-management Browser Extension တစ်ခုကို အသုံးပြုနိုင်သည်။
Browser Extension များကိုတည်ဆောက်ခြင်းသည်ပျော်စရာကောင်းသည်။ အကန့်အသတ်ရှိသော Tasks များကိုအကောင်းဆုံးလုပ်ဆောင်ပေးနိုင်သည်။
Browser Extension များကို တည်ဆောက်ခြင်းသည် ပျော်စရာကောင်းသည်။ ၎င်းတို့သည် သတ်မှတ်ထားသော အလုပ်အချို့ကို ကောင်းစွာ လုပ်ဆောင်နိုင်သည်။
✅ သင့်အကြိုက် Browser Extension များကဘာလဲ? သူတို့ဘယ်လို Tasks များကိုလုပ်ဆောင်ပေးသလဲ?
✅ သင့်အကြိုက် Browser Extension များက ဘာတွေလုပ်ဆောင်ပေးသလဲ? ၎င်းတို့၏ လုပ်ဆောင်ချက်များက ဘာတွေလဲ?
### Extension များတပ်ဆင်ခြင်း
### Extension များကို ထည့်သွင်းခြင်း
Browser Extension တစ်ခုကိုတည်ဆောက်ပြီး Deploy လုပ်ပုံကိုကြည့်ရှုပါ။ Browser တစ်ခုစီတွင်ဒီလုပ်ငန်းစဉ်ကို Handle လုပ်ပုံကွဲပြားနိုင်သော်လည်း Chrome နှင့် Firefox တွင် Edge Browser တွင်လုပ်ဆောင်ပုံနှင့်ဆင်တူသည်။
တည်ဆောက်ခြင်းမစတင်မီ Browser Extension တစ်ခုကို တည်ဆောက်ခြင်းနှင့် တင်သွင်းခြင်း လုပ်ငန်းစဉ်ကို ကြည့်ပါ။ Browser တစ်ခုစီတွင် ၎င်းတို့၏ လုပ်ငန်းစဉ်မှာ အနည်းငယ်ကွဲပြားသော်လည်း Chrome နှင့် Firefox တို့တွင် Edge ၏ ဤဥပမာနှင့် ဆင်တူသည်။
![screenshot of the Edge browser showing the open edge://extensions page and open settings menu](../../../../translated_images/install-on-edge.d68781acaf0b3d3dada8b7507cde7a64bf74b7040d9818baaa9070668e819f90.my.png)
> Note: Developer Mode ကိုဖွင့်ထားပြီး Other Stores မှ Extension များကို Allow လုပ်ထားရန်သေချာပါ
> Note: Developer Mode ကို ဖွင့်ထားပြီး အခြား Store များမှ Extension များကို ခွင့်ပြုထားရန် သေချာပါစေ
ခြေခံအားဖြင့်လုပ်ငန်းစဉ်မှာ -
ဓိကအားဖြင့် လုပ်ငန်းစဉ်မှာ -
- `npm run build` ကိုအသုံးပြု၍ Extension ကို Build လုပ်ပါ
- Browser တွင် "Settings and more" Button (အပေါ်ယံညာဘက်ရှိ `...` icon) ကိုအသုံးပြု၍ Extension Pane သို့သွားပါ
- Installation အသစ်ဖြစ်လျှင် `load unpacked` ကိုရွေးချယ်ပြီး Build Folder (ဤကိစ္စတွင် `/dist`) မှ Fresh Extension ကို Upload လုပ်ပါ
- သို့မဟုတ်, ရှိပြီးသား Installed Extension ကို Reload လုပ်ပါ
- `npm run build` ကို အသုံးပြု၍ သင့် Extension ကို တည်ဆောက်ပါ
- Browser တွင် "Settings and more" ခလုတ် (`...` icon) ကို အသုံးပြု၍ Extension များ၏ စာမျက်နှာသို့ သွားပါ
- အသစ်တစ်ခုကို ထည့်သွင်းလိုပါက `load unpacked` ကို ရွေးချယ်ပြီး Build Folder (ဤအခါတွင် `/dist`) မှ အသစ်တစ်ခုကို Upload လုပ်ပါ
- သို့မဟုတ် ရှိပြီးသား Extension ကို ပြန်လည်တင်ရန် `reload` ကို နှိပ်ပါ
ဒီအညွှန်းများသည် သင်တိုင်တည်ဆောက်သော Extension များအတွက်ဖြစ်သည်။ Browser Extension Store တွင် Release လုပ်ထားသော Extension များကိုတပ်ဆင်ရန် Browser တစ်ခုစီနှင့်ဆက်စပ်သော [Stores](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) သို့သွားပြီး သင့်အကြိုက် Extension ကိုတပ်ဆင်ပါ။
ဤညွှန်ကြားချက်များသည် သင့်ကိုယ်တိုင် တည်ဆောက်သော Extension များအတွက်သာ သက်ဆိုင်သည်။ Browser Extension Store တွင် ထုတ်ဝေထားသော Extension များကို ထည့်သွင်းရန် [Store များ](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) သို့ သွားပြီး သင့်နှစ်သက်ရာ Extension ကို ထည့်သွင်းပါ။
### စတင်လုပ်ဆောင်ပါ
### စတင်လိုက်ပါ
သင့်ဒေသ၏ Carbon Footprint ကိုပြသသော Browser Extension တစ်ခုကိုတည်ဆောက်မည်ဖြစ်သည်။ ဒေသ၏ Energy Usage နှင့် Energy Source ကိုပြသမည်။ Extension တွင် API Key ကိုရယူရန် Form တစ်ခုပါဝင်မည်။
သင့်ဒေသ၏ Carbon Footprint ကို ပြသပေးမည့် Browser Extension တစ်ခုကို သင်တည်ဆောက်မည်ဖြစ်သည်။ ၎င်းသည် သင့်ဒေသ၏ စွမ်းအင်အသုံးပြုမှုနှင့် စွမ်းအင်ရင်းမြစ်ကို ပြသမည်ဖြစ်သည်။ Extension တွင် API Key ကို ရယူရန် Form တစ်ခုပါဝင်မည်။
**လိုအပ်သောအရာများ:**
**သင့်အတွက်လိုအပ်သည်များ:**
- [API key](https://www.co2signal.com/) - ဒီ Page တွင် Email ကိုထည့်ပြီး API Key ရယူပါ
- [Region Code](http://api.electricitymap.org/v3/zones) - [Electricity Map](https://www.electricitymap.org/map) တွင်သင့်ဒေသ၏ Code ကိုရယူပါ (ဥပမာ Boston တွင် 'US-NEISO' ကိုအသုံးပြုသည်)
- [Starter Code](../../../../5-browser-extension/start) - `start` Folder ကို Download လုပ်ပါ; ဒီ Folder တွင် Code ကိုပြီးစီးပါမည်။
- [NPM](https://www.npmjs.com) - NPM သည် Package Management Tool ဖြစ်သည်; သင့် Local Computer တွင် Install လုပ်ပြီး `package.json` File တွင်ဖော်ပြထားသော Packages များကို Install လုပ်ပါ
- [API Key တစ်ခု](https://www.co2signal.com/) - ဤစာမျက်နှာတွင် သင့် Email ကို ထည့်သွင်းပါ၊ API Key တစ်ခုကို ပေးပို့မည်
- [သင့်ဒေသ၏ Code](http://api.electricitymap.org/v3/zones) - [Electricity Map](https://www.electricitymap.org/map) နှင့် ကိုက်ညီသော Code (ဥပမာအားဖြင့် Boston တွင် 'US-NEISO' ကို အသုံးပြုသည်)
- [Starter Code](../../../../5-browser-extension/start) - `start` Folder ကို Download လုပ်ပါ၊ သင်သည် ဤ Folder တွင် Code ကို ပြည့်စုံစေမည်
- [NPM](https://www.npmjs.com) - NPM သည် Package Management Tool တစ်ခုဖြစ်သည်၊ ၎င်းကို Local တွင် Install လုပ်ပြီး သင့် `package.json` ဖိုင်တွင် ဖော်ပြထားသော Package များကို အသုံးပြုရန် Install လုပ်ပါ
✅ Package Management အကြောင်းကို [Learn module](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon) မှာပိုမိုလေ့လာပါ
✅ Package Management အကြောင်းပိုမိုလေ့လာရန် ဤ [Learn Module](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon) ကို ကြည့်ပါ
Codebase ကိုကြည့်ရှုရန်အချိန်ယူပါ:
Codebase ကို အချိန်ယူကြည့်ပါ:
dist
-|manifest.json (defaults set here)
-|index.html (front-end HTML markup here)
-|background.js (background JS here)
-|main.js (built JS)
src
-|index.js (your JS code goes here)
dist
-|manifest.json (defaults set here)
-|index.html (front-end HTML markup here)
-|background.js (background JS here)
-|main.js (built JS)
src
-|index.js (your JS code goes here)
API Key နှင့် Region Code ကိုရယူပြီးနောက် Note တစ်ခုတွင်သိမ်းဆည်းထားပါ။
သင့် API Key နှင့် Region Code ကို အသုံးပြုရန် Note တစ်ခုတွင် သိမ်းထားပါ။
### Extension ၏ HTML ကိုတည်ဆောက်ပါ
### Extension ၏ HTML ကို တည်ဆောက်ခြင်း
ဒီ Extension တွင် Views နှစ်ခုပါဝင်သည်။ API Key နှင့် Region Code ကိုရယူရန် View တစ်ခု:
ဤ Extension တွင် View နှစ်ခုပါဝင်သည်။ API Key နှင့် Region Code ကို ရယူရန် View တစ်ခု:
![screenshot of the completed extension open in a browser, displaying a form with inputs for region name and API key.](../../../../translated_images/1.b6da8c1394b07491afeb6b2a8e5aca73ebd3cf478e27bcc9aeabb187e722648e.my.png)
နှင့် Region ၏ Carbon Usage ကိုပြသရန် View တစ်ခု:
နှင့် ဒုတိယ View သည် Region ၏ Carbon Usage ကို ပြသရန်:
![screenshot of the completed extension displaying values for carbon usage and fossil fuel percentage for the US-NEISO region.](../../../../translated_images/2.1dae52ff0804224692cd648afbf2342955d7afe3b0101b617268130dfb427f55.my.png)
Form ကိုတည်ဆောက်ပြီး CSS ဖြင့် Style လုပ်ခြင်းမှစတင်ပါ။
Form နှင့် CSS ဖြင့် ၎င်းကို အလှဆင်ရန် `/dist` Folder တွင် HTML ကို တည်ဆောက်ပါ။
`/dist` Folder တွင် Form နှင့် Result Area တစ်ခုကိုတည်ဆောက်ပါ။ `index.html` File တွင် Form Area ကို Populate လုပ်ပါ:
`index.html` ဖိုင်တွင် Form အပိုင်းကို ဖြည့်ပါ:
```HTML
<form class="form-data" autocomplete="on">
@ -122,10 +122,10 @@ Form ကိုတည်ဆောက်ပြီး CSS ဖြင့် Style လ
</div>
<button class="search-btn">Submit</button>
</form>
```
ဒီ Form သည်သင့် Save လုပ်ထားသောအချက်အလက်များကို Input လုပ်ပြီး Local Storage တွင်သိမ်းဆည်းရန်ဖြစ်သည်။
```
ဤ Form သည် သင့် Save လုပ်ထားသော အချက်အလက်များကို Input လုပ်ပြီး Local Storage တွင် သိမ်းဆည်းမည်။
နောက်တစ်ဆင့် Result Area ကိုတည်ဆောက်ပါ; Form Tag ၏အောက်တွင် Div များကိုထည့်ပါ:
ထို့နောက် Results Area ကို ဖန်တီးပါ။ Form Tag ၏ အောက်တွင် Div များကို ထည့်ပါ:
```HTML
<div class="result">
@ -139,44 +139,44 @@ Form ကိုတည်ဆောက်ပြီး CSS ဖြင့် Style လ
</div>
<button class="clear-btn">Change region</button>
</div>
```
ဒီအချိန်တွင် Build လုပ်နိုင်ပါပြီ။ Extension ၏ Package Dependencies များကို Install လုပ်ရန်သေချာပါ:
```
ဤအချိန်တွင် Build တစ်ခုကို စမ်းကြည့်နိုင်သည်။ Extension ၏ Package Dependencies များကို Install လုပ်ရန် သေချာပါစေ:
```
npm install
```
```
ဒီ Command သည် npm, Node Package Manager ကိုအသုံးပြု၍ Extension ၏ Build Process အတွက် webpack ကို Install လုပ်ပါမည်။ ဒီ Process ၏ Output ကို `/dist/main.js` တွင်ကြည့်နိုင်သည် - Code ကို Bundled လုပ်ထားသည်ကိုတွေ့ရမည်။
ဤ Command သည် NPM (Node Package Manager) ကို အသုံးပြု၍ Extension ၏ Build Process အတွက် Webpack ကို Install လုပ်မည်။ ဤ Process ၏ Output ကို `/dist/main.js` တွင် ကြည့်နိုင်သည် - Code ကို Bundled လုပ်ထားသည်ကို တွေ့ရမည်။
ခုအချိန်တွင် Extension ကို Build လုပ်ပြီး Edge Browser တွင် Extension အဖြစ် Deploy လုပ်ပါက Form တစ်ခုကိုတိကျစွာပြသထားသည်ကိုတွေ့ရမည်။
ခုအချိန်တွင် Extension ကို Build လုပ်ပြီး Edge တွင် Extension အဖြစ် Deploy လုပ်ပါက Form တစ်ခုကို သေသပ်စွာ ပြသမည်။
အောင်မြင်ပါပြီ၊ Browser Extension တစ်ခုကိုတည်ဆောက်ရန်ပထမဆုံးအဆင့်များကိုအောင်မြင်စွာလုပ်ဆောင်ပြီးပါပြီ။ နောက်ထပ်သင်ခန်းစာများတွင် Functionality ပိုမိုကောင်းမွန်ပြီးအသုံးဝင်သော Extension တစ်ခုကိုတည်ဆောက်မည်ဖြစ်သည်။
ဂုဏ်ယူပါတယ်၊ Browser Extension တစ်ခုကို တည်ဆောက်ရန် ပထမဆုံးအဆင့်ကို သင်ပြီးစီးခဲ့ပါပြီ။ နောက်ထပ် သင်ခန်းစာများတွင် ၎င်းကို ပိုမိုအသုံးဝင်စေရန် လုပ်ဆောင်မည်။
---
## 🚀 စိန်ခေါ်မှု
Browser Extension Store တစ်ခုကိုကြည့်ရှုပြီး Browser တွင် Extension တစ်ခုကိုတပ်ဆင်ပါ။ Files များကိုစူးစမ်းကြည့်ပါ။ ဘာတွေတွေ့ရလဲ?
Browser Extension Store တစ်ခုကို ကြည့်ပြီး သင့် Browser တွင် Extension တစ်ခုကို ထည့်သွင်းပါ။ ၎င်း၏ ဖိုင်များကို စူးစမ်းကြည့်ပါ။ သင်ဘာတွေ ရှာဖွေတွေ့ရှိသလဲ?
## မိမိကိုယ်ကိုစစ်မေးရန်မေးခွန်းမျာ
## မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/24)
[မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/24)
## ပြန်လည်သုံးသပ်ခြင်းနှင့်ကိုယ်တိုင်လေ့လာခြင်း
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
ဒီသင်ခန်းစာတွင် Web Browser ၏သမိုင်းအနည်းငယ်ကိုလေ့လာခဲ့သည်။ World Wide Web ၏တီထွင်သူများက Web ကိုဘယ်လိုအသုံးပြုရန်ရည်ရွယ်ခဲ့သည်ကိုပိုမိုလေ့လာရန်အခွင့်အရေးယူပါ။ အသုံးဝင်သော Website များမှာ -
သင်ခန်းစာတွင် Web Browser ၏ သမိုင်းအကြောင်း အနည်းငယ်ကို သင်လေ့လာခဲ့သည်။ World Wide Web ၏ ဖန်တီးသူများက ၎င်းကို ဘယ်လိုအသုံးပြုရန် ရည်ရွယ်ခဲ့ကြောင်းကို ပိုမိုလေ့လာရန် အခွင့်အရေးယူပါ။ အသုံးဝင်သော Website များမှာ -
[The History of Web Browsers](https://www.mozilla.org/firefox/browsers/browser-history/)
[The History of Web Browsers](https://www.mozilla.org/firefox/browsers/browser-history/)
[History of the Web](https://webfoundation.org/about/vision/history-of-the-web/)
[History of the Web](https://webfoundation.org/about/vision/history-of-the-web/)
[An interview with Tim Berners-Lee](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want)
[An interview with Tim Berners-Lee](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want)
## လုပ်ငန်းတာဝန်
[Restyle your extension](assignment.md)
[သင့် Extension ကို ပြန်လည်ဒီဇိုင်းဆွဲပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွဲအချော်များ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,29 +1,29 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e10f168beac4e7b05e30e0eb5c92bf11",
"translation_date": "2025-08-27T22:18:08+00:00",
"original_hash": "a7587943d38d095de8613e1b508609f5",
"translation_date": "2025-08-28T18:37:12+00:00",
"source_file": "5-browser-extension/2-forms-browsers-local-storage/README.md",
"language_code": "my"
}
-->
# Browser Extension Project Part 2: API ကိုခေါ်ရန်၊ Local Storage ကိုအသုံးပြုရန်
# Browser Extension Project Part 2: API ကိုခေါ်ယူခြင်း၊ Local Storage ကိုအသုံးပြုခြင်း
## မိန့်ခွန်းမတင်မီ စစ်ဆေးမှု
## မိန့်ခွန်းမတင်မီမေးခွန်းများ
[မိန့်ခွန်းမတင်မီ စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/25)
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/25)
### နိဒါန်း
### အကျဉ်းချုပ်
ဒီသင်ခန်းစာမှာ သင့ browser extension ရဲ့ form ကို submit လုပ်ပြီး API ကိုခေါ်သုံးကာ ရလဒ်တွေကို browser extension မှာ ပြသပေးမှာဖြစ်ပါတယ်။ ထို့အပြင်၊ browser ရဲ့ local storage မှာ ဒေတာတွေကို သိမ်းဆည်းပြီး နောက်ပိုင်းအတွက် အသုံးပြုနိုင်မယ့်နည်းလမ်းကိုလည်း သင်ယူပါမယ်။
ဒီသင်ခန်းစာမှာတော့ သင့ browser extension ရဲ့ form ကို submit လုပ်ပြီး API ကိုခေါ်ယူကာ ရလဒ်များကို browser extension မှာ ပြသပေးမှာဖြစ်ပါတယ်။ ထို့အပြင်၊ သင် browser ရဲ့ local storage မှာ data ကို သိမ်းဆည်းပြီး နောက်တစ်ခါအသုံးပြုနိုင်ဖို့နည်းလမ်းများကိုလည်း လေ့လာရမှာဖြစ်ပါတယ်။
✅ သင့်ရဲ့ code ကိုဘယ်နေရာမှာထည့်ရမယ်ဆိုတာ သိရန် အမှတ်အသားနံပါတ်များကို သင့်ဖိုင်များတွင်လိုက်နာပါ။
✅ သင့် code ကို ထည့်သွင်းရမယ့်နေရာကို သိရှိရန် သင့်ဖိုင်များအတွင်းရှိ အမှတ်အသားများကိုလိုက်နာပါ။
### Extension ထဲမှာ ပြောင်းလဲနိုင်မယ့် elements တွေကို set up လုပ်ပါ:
### Extension အတွက် Manipulate လုပ်ရန် Element များကို Set Up လုပ်ပါ:
ဒီအချိန်မှာ သင့် browser extension အတွက် form နဲ့ results `<div>` ရဲ့ HTML ကို တည်ဆောက်ပြီးဖြစ်ပါပြီ။ အခုကစပြီး `/src/index.js` ဖိုင်မှာ အလုပ်လုပ်ရမှာဖြစ်ပြီး extension ကို အပိုင်းလိုက် တည်ဆောက်ရမှာဖြစ်ပါတယ်။ သင့်ရဲ့ project ကို set up လုပ်နည်းနဲ့ build လုပ်နည်းကို သိရန် [ယခင်သင်ခန်းစာ](../1-about-browsers/README.md) ကို ပြန်လည်ကြည့်ပါ။
ဒီအချိန်မှာတော့ သင် browser extension အတွက် form နှင့် results `<div>` ရဲ့ HTML ကို တည်ဆောက်ပြီးဖြစ်ပါပြီ။ အခုမှစပြီးတော့ `/src/index.js` ဖိုင်မှာ အလုပ်လုပ်ရမှာဖြစ်ပြီး extension ကို အပိုင်းလိုက် တည်ဆောက်ရမှာဖြစ်ပါတယ်။ သင့် project ကို set up လုပ်နည်းနှင့် build လုပ်နည်းကို [ယခင်သင်ခန်းစာ](../1-about-browsers/README.md) မှာ ပြန်လည်ကြည့်ရှုပါ။
`index.js` ဖိုင်မှာ အလုပ်လုပ်ပြီးနောက်၊ အမျိုးမျိုးသော fields တွေနဲ့ ဆက်စပ်နေတဲ့ တန်ဖိုးတွေကို သိမ်းဆည်းဖို့ `const` variables တစ်ချို့ကို စတင်ဖန်တီးပါ:
`index.js` ဖိုင်မှာ အလုပ်လုပ်ပြီးနောက်၊ `const` variable များကို ဖန်တီးကာ HTML ရဲ့ field များနှင့် ဆက်စပ်ထားသော value များကို သိမ်းဆည်းပါ:
```JavaScript
// form fields
@ -41,11 +41,11 @@ const myregion = document.querySelector('.my-region');
const clearBtn = document.querySelector('.clear-btn');
```
ဒီ fields တွေကို HTML မှာ သင်တည်ဆောက်ထားတဲ့ css class နဲ့ ရည်ညွှန်းထားပါတယ်။
ဒီ field များအားလုံးကို ယခင်သင် HTML မှာ set up လုပ်ထားသော CSS class အတိုင်း reference လုပ်ထားပါတယ်။
### Listeners ထည့်ပါ
### Listener များထည့်ပါ
နောက်တစ်ဆင့်မှာတော့ form နဲ့ reset button အတွက် event listeners တွေထည့်ပါ။ ဒါကြောင့် user က form ကို submit လုပ်တဲ့အခါ သို့မဟုတ် reset button ကိုနှိပ်တဲ့အခါ တစ်ခုခုဖြစ်ပေါ်မှာဖြစ်ပါတယ်။ ဖိုင်ရဲ့ အောက်ဆုံးမှာ app ကို initialize လုပ်ဖို့ call ထည့်ပါ:
နောက်တစ်ဆင့်မှာတော့ form နှင့် reset button အတွက် event listener များကို ထည့်သွင်းပါ။ သုံးစွဲသူက form ကို submit လုပ်သော်လည်းကောင်း၊ reset button ကို click လုပ်သော်လည်းကောင်း၊ တစ်ခုခုဖြစ်ပေါ်စေပြီး ဖိုင်ရဲ့ အောက်ဆုံးမှာ app ကို initialize လုပ်ရန် call လုပ်ပါ:
```JavaScript
form.addEventListener('submit', (e) => handleSubmit(e));
@ -53,11 +53,11 @@ clearBtn.addEventListener('click', (e) => reset(e));
init();
```
✅ submit event သို့မဟုတ် click event ကို နားထောင်ဖို့ shorthand ကို သတိပြုပါ၊ event ကို handleSubmit သို့မဟုတ် reset functions ကို ပေးပို့ပုံကိုလည်း သတိပြုပါ။ ဒီ shorthand ကို ပိုရှည်တဲ့ format နဲ့ရေးနိုင်မလား? သင်ဘယ်ဖော်မတ်ကို ပိုကြိုက်ပါသလဲ?
✅ submit event သို့မဟုတ် click event ကို listen လုပ်ရန် shorthand ကို သတိပြုပါ။ ဒီ shorthand ကို အရှည် version အဖြစ်ရေးနိုင်မလား? သင်အကြိုက်ဆုံး version က ဘယ်ဟာလဲ?
### init() function နဲ့ reset() function ကို တည်ဆောက်ပါ:
### init() function နှင့် reset() function ကို တည်ဆောက်ပါ:
အခုတော့ extension ကို initialize လုပ်မယ့် function ကို တည်ဆောက်ပါ၊ ဒါက init() လို့ခေါ်ပါတယ်:
အခုတော့ extension ကို initialize လုပ်မယ့် function ဖြစ်တဲ့ init() ကို တည်ဆောက်ရမှာဖြစ်ပါတယ်:
```JavaScript
function init() {
@ -93,34 +93,34 @@ function reset(e) {
```
ဒီ function ထဲမှာ စိတ်ဝင်စားစရာ logic တစ်ချို့ရှိပါတယ်။ ဖတ်ကြည့်ပြီး ဘာဖြစ်နေလဲဆိုတာ မြင်နိုင်ပါသလား?
ဒီ function မှာ စိတ်ဝင်စားဖွယ် logic ရှိပါတယ်။ သင်ဖတ်ရှုရင်း ဘာတွေဖြစ်ပျက်နေလဲဆိုတာမြင်နိုင်ပါသလား?
- `const` နှစ်ခုကို local storage ထဲမှာ user ရဲ့ APIKey နဲ့ region code ရှိမရှိ စစ်ဆေးဖို့ သတ်မှတ်ထားပါတယ်။
- အဲဒီနှစ်ခုထဲက တစ်ခုခု null ဖြစ်ရင် form ကို 'block' အဖြစ်ပြောင်းပြီး ပြသပါ။
- results, loading, နဲ့ clearBtn ကို ဖျောက်ပြီး error text ကို အလွတ် string အဖြစ် သတ်မှတ်ပါ။
- key နဲ့ region ရှိနေခဲ့ရင်တော့ အောက်ပါအတိုင်းလုပ်ဆောင်ပါ:
- API ကိုခေါ်ပြီး carbon usage data ကိုရယူပါ။
- results area ကို ဖျောက်ပါ။
- form ကို ဖျောက်ပါ။
- `const` နှစ်ခုကို local storage မှာ APIKey နှင့် region code ရှိ/မရှိ စစ်ဆေးရန် set up လုပ်ထားပါတယ်။
- အဲဒီ value များ null ဖြစ်နေပါက form ကို display style 'block' အဖြစ်ပြောင်းပြီး ပြသပါ။
- results, loading, နှင့် clearBtn ကို hide လုပ်ပြီး error text ကို အလွတ်ထားပါ။
- key နှင့် region ရှိနေပါက အောက်ပါ routine ကို စတင်ပါ:
- API ကို call လုပ်ကာ carbon usage data ကိုရယူပါ။
- results area ကို hide လုပ်ပါ။
- form ကို hide လုပ်ပါ။
- reset button ကို ပြပါ။
ရှေ့ဆက်မလုပ်မီ browser တွေမှာ ရရှိနိုင်တဲ့ အရေးကြီးသော concept တစ်ခုကို သင်ယူရမှာဖြစ်ပါတယ် - [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)။ LocalStorage က browser ထဲမှာ string တွေကို `key-value` pair အနေနဲ့ သိမ်းဆည်းဖို့ အသုံးဝင်ပါတယ်။ ဒီလို web storage ကို JavaScript နဲ့ manipulate လုပ်ပြီး browser ထဲမှာ ဒေတာကို စီမံနိုင်ပါတယ်။ LocalStorage က မသက်တမ်းကုန်သလို SessionStorage က browser ပိတ်လိုက်တာနဲ့ ဖျက်သိမ်းသွားပါတယ်။ storage အမျိုးအစားတွေမှာ အသုံးပြုမှုအပေါ် မတူညီတဲ့ အားသာချက်နဲ့ အားနည်းချက်တွေရှိပါတယ်။
ရှေ့ဆက်မလုပ်ခင်မှာ browser တွေမှာ ရရှိနိုင်တဲ့ အရေးကြီးသော concept တစ်ခုဖြစ်တဲ့ [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) ကိုလေ့လာပါ။ LocalStorage သည် browser မှာ string များကို `key-value` pair အနေနဲ့ သိမ်းဆည်းရန် အသုံးဝင်သော နည်းလမ်းတစ်ခုဖြစ်ပါတယ်။ ဒီ storage ကို JavaScript ဖြင့် manipulate လုပ်ကာ browser မှာ data ကို စီမံနိုင်ပါတယ်။ LocalStorage သည် မသက်တမ်းကုန်သည့် storage ဖြစ်ပြီး SessionStorage သည် browser ကို ပိတ်လိုက်သည်နှင့် ဖျက်သိမ်းသွားပါသည်။ storage အမျိုးအစားများမှာ အသုံးပြုမှုအပေါ်တွင် အားသာချက်နှင့် အားနည်းချက်များရှိပါတယ်။
> မှတ်ချက် - သင့် browser extension ရဲ့ local storage က main browser window ရဲ့ instance နဲ့ မတူပါဘူး၊ သီးခြားစွာ လုပ်ဆောင်ပါတယ်။
> Note - သင့် browser extension မှာ သီးသန့် local storage ရှိပါတယ်။ main browser window သည် အခြား instance ဖြစ်ပြီး သီးသန့်အနေဖြင့် လုပ်ဆောင်ပါသည်။
APIKey ကို string တန်ဖိုးတစ်ခုအဖြစ် သတ်မှတ်ပြီး၊ Edge မှာ "inspect" လုပ်ပြီး storage ကို Applications tab မှာကြည့်နိုင်ပါတယ်။
APIKey ကို string value အနေနဲ့ set လုပ်ပြီး Edge မှာ "inspect" လုပ်ကာ storage ကို Applications tab မှာကြည့်ရှုနိုင်ပါတယ်။
![Local storage pane](../../../../translated_images/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.my.png)
✅ LocalStorage မှာ ဒေတာတစ်ချို့ကို မသိမ်းသင့်တဲ့ အခြေအနေတွေကို စဉ်းစားကြည့်ပါ။ အထွေထွေအားဖြင့် API Keys ကို LocalStorage မှာ သိမ်းတာက အဆင်မပြေတဲ့အကြောင်းကို မြင်နိုင်ပါသလား? ကျွန်တော်တို့ရဲ့ app က သင်ယူရေးအတွက်သာဖြစ်ပြီး app store မှာ မတင်မီအတွက် ဒီနည်းကို အသုံးပြုမှာဖြစ်ပါတယ်။
✅ LocalStorage မှာ data ကို မသိမ်းဆည်းသင့်တဲ့ အခြေအနေများကို စဉ်းစားပါ။ အထူးသဖြင့် API Keys ကို LocalStorage မှာ သိမ်းဆည်းတာက အဆင်မပြေတဲ့အကြောင်းကို သတိထားပါ။ သင့် app သည် သင်ကြားရေးအတွက်သာဖြစ်ပြီး app store မှာ deploy မလုပ်မည်ဖြစ်သောကြောင့် ဒီနည်းလမ်းကို အသုံးပြုပါမည်။
Web API ကို အသုံးပြုပြီး LocalStorage ကို manipulate လုပ်နိုင်ပါတယ်၊ `getItem()`, `setItem()`, သို့မဟုတ် `removeItem()` ကို အသုံးပြုနိုင်ပါတယ်။ ဒါဟာ browser အားလုံးမှာ ကျယ်ကျယ်ပြန့်ပြန့် support လုပ်ထားပါတယ်။
LocalStorage ကို manipulate လုပ်ရန် Web API ကို အသုံးပြုပါ။ `getItem()`, `setItem()`, `removeItem()` ကို အသုံးပြုနိုင်ပြီး browser များတွင် ကျယ်ကျယ်ပြန့်ပြန့် support လုပ်ထားပါတယ်။
`displayCarbonUsage()` function ကို တည်ဆောက်မတိုင်မီ၊ initial form submission ကို handle လုပ်မယ့် functionality ကို တည်ဆောက်ပါ။
`displayCarbonUsage()` function ကို build လုပ်မတိုင်မီ၊ initial form submission ကို handle လုပ်ရန် functionality ကို build လုပ်ပါ။
### Form submission ကို handle လုပ်ပါ
### Form Submission ကို Handle လုပ်ပါ
`handleSubmit` လို့ခေါ်တဲ့ function တစ်ခုကို ဖန်တီးပြီး event argument `(e)` ကို လက်ခံပါ။ event ကို propagate မဖြစ်အောင် (ဒီအခါမှာ browser ကို refresh မလုပ်စေချင်တာ) ရပ်တန့်ပြီး၊ `setUpUser` လို့ခေါ်တဲ့ function ကို `apiKey.value` နဲ့ `region.value` arguments တွေကို ပေးပို့ပါ။ ဒီနည်းနဲ့ initial form ကနေ appropriate fields တွေကို populate လုပ်ပြီးရတဲ့ values နှစ်ခုကို အသုံးပြုနိုင်ပါတယ်။
`handleSubmit` ဟုခေါ်သော function တစ်ခုကို ဖန်တီးပြီး event argument `(e)` ကို လက်ခံပါ။ event ကို propagate မဖြစ်စေရန် (ဒီအခါမှာ browser refresh မဖြစ်စေရန်လိုသည်) ရပ်တန့်ပြီး `setUpUser` function ကို call လုပ်ပါ။ အဲဒီ function ကို `apiKey.value` နှင့် `region.value` arguments ဖြင့် pass လုပ်ပါ။ ဒီနည်းလမ်းဖြင့် initial form မှာ populate လုပ်ထားသော field value နှစ်ခုကို အသုံးပြုနိုင်ပါသည်။
```JavaScript
function handleSubmit(e) {
@ -129,11 +129,11 @@ function handleSubmit(e) {
}
```
✅ သင့်ရဲ့မှတ်ဉာဏ်ကို ပြန်လည်တက်ကြွစေပါ - ယခင်သင်ခန်းစာမှာ သင်တည်ဆောက်ထားတဲ့ HTML မှာ `values` တွေကို capture လုပ်မယ့် input fields နှစ်ခုရှိပြီး၊ အဲဒီ fields နှစ်ခုလုံးကို `required` လို့ သတ်မှတ်ထားပါတယ်။ ဒါကြောင့် browser က user တွေကို null values ထည့်မရအောင် တားဆီးပါတယ်။
✅ သင့်ရဲ့ HTML မှာ input field နှစ်ခုရှိပြီး value များကို `const` variable ဖြင့် capture လုပ်ထားသည်ကို သတိပြုပါ။ အဲဒီ field များသည် `required` ဖြစ်သောကြောင့် browser က null value များကို input လုပ်ခြင်းကို တားဆီးပါသည်။
### User ကို set up လုပ်ပါ
### User ကို Set Up လုပ်ပါ
`setUpUser` function ကို ဆက်လုပ်ပါ၊ ဒီမှာတော့ apiKey နဲ့ regionName အတွက် local storage values တွေကို set လုပ်ပါမယ်။ function အသစ်တစ်ခုထည့်ပါ:
`setUpUser` function ကို ဆက်လက်တည်ဆောက်ပါ။ ဒီနေရာမှာ local storage value များကို apiKey နှင့် regionName အတွက် set လုပ်ပါ။ function အသစ်တစ်ခုကို ထည့်ပါ:
```JavaScript
function setUpUser(apiKey, regionName) {
@ -147,25 +147,25 @@ function setUpUser(apiKey, regionName) {
}
```
ဒီ function က API ကိုခေါ်မယ့်အချိန် loading message ကို ပြသဖို့ သတ်မှတ်ထားပါတယ်။ ဒီအချိန်မှာ သင့် browser extension ရဲ့ အရေးကြီးဆုံး function ကို တည်ဆောက်ဖို့ ရောက်ရှိလာပါပြီ!
ဒီ function မှာ API ကို call လုပ်နေစဉ် loading message ကို ပြသပါမည်။ အခုတော့ browser extension ရဲ့ အရေးကြီးဆုံး function ကို ဖန်တီးရန် ရောက်ရှိပါပြီ!
### Carbon Usage ကို ပြသပါ
### Carbon Usage ကို Display လုပ်ပါ
အခုတော့ API ကို query လုပ်ဖို့ အချိန်ရောက်ပါပြီ!
အခုတော့ API ကို query လုပ်ရန် အချိန်ရောက်ပါပြီ!
ရှေ့ဆက်မလုပ်မီ API တွေကို ဆွေးနွေးရမယ်။ API တွေဟာ [Application Programming Interfaces](https://www.webopedia.com/TERM/A/API.html) လို့ခေါ်ပြီး web developer တွေရဲ့ toolbox မှာ အရေးကြီးတဲ့ အစိတ်အပိုင်းတစ်ခုဖြစ်ပါတယ်။ API တွေက programs တွေကို အချင်းချင်း ဆက်သွယ်ဖို့ standard နည်းလမ်းတွေ ပေးပါတယ်။ ဥပမာအားဖြင့် သင် database ကို query လုပ်ဖို့လိုတဲ့ web site တစ်ခု တည်ဆောက်နေရင်၊ တစ်ယောက်ယောက်က API တစ်ခုကို သင့်အတွက် ဖန်တီးထားနိုင်ပါတယ်။ API အမျိုးအစားတွေ များစွာရှိပေမယ့် [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/) က အများဆုံး အသုံးပြုတဲ့ API အမျိုးအစားတစ်ခုဖြစ်ပါတယ်။
API များကို ဆွေးနွေးရန်အချိန်ရောက်ပါပြီ။ API များသည် [Application Programming Interfaces](https://www.webopedia.com/TERM/A/API.html) ဟုခေါ်ပြီး web developer များအတွက် အရေးကြီးသော tool တစ်ခုဖြစ်သည်။ API များသည် program များအကြား interface လုပ်ရန် standard နည်းလမ်းများကို ပေးသည်။ ဥပမာအားဖြင့် database ကို query လုပ်ရန် website တစ်ခုတည်ဆောက်နေပါက API တစ်ခုကို အသုံးပြုရန် တစ်စုံတစ်ဦးက ဖန်တီးထားနိုင်သည်။ API အမျိုးအစားများစွာရှိသော်လည်း [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/) သည် အလွန်လူကြိုက်များသည်။
✅ 'REST' ဆိုတာ 'Representational State Transfer' ကို ရည်ညွှန်းပြီး၊ data ကို ရယူဖို့ အမျိုးမျိုးဖွဲ့စည်းထားတဲ့ URLs တွေကို အသုံးပြုပါတယ်။ Developer တွေအတွက် ရရှိနိုင်တဲ့ API အမျိုးအစားတွေကို သုတေသနလုပ်ပါ။ ဘယ် format က သင့်ကို ဆွဲဆောင်ပါသလဲ?
✅ 'REST' ဆိုသည်မှာ 'Representational State Transfer' ကိုဆိုလိုပြီး URL များကို configure လုပ်ကာ data ကို fetch လုပ်ရန် အသုံးပြုသည်။ Developer များအတွက် ရရှိနိုင်သော API အမျိုးအစားများကို သုတေသနလုပ်ပါ။ သင့်အကြိုက်ဆုံး format က ဘာလဲ?
ဒီ function အကြောင်း အရေးကြီးတဲ့ အချက်တွေကို သတိပြုပါ။ ပထမဦးစွာ [`async` keyword](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) ကို သတိပြုပါ။ သင့် function တွေကို asynchronous ဖြစ်အောင်ရေးခြင်းက data ပြန်လာတဲ့အချိန်အထိ စောင့်နေပြီးမှ ဆက်လုပ်ဆောင်စေပါတယ်။
ဒီ function ရဲ့ အရေးကြီးသောအချက်များကို သတိပြုပါ။ ပထမဦးဆုံး [`async` keyword](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) ကို သတိပြုပါ။ function များကို asynchronous အဖြစ်ရေးခြင်းသည် data ရရှိရန် စောင့်ဆိုင်းပြီးမှ ဆက်လက်လုပ်ဆောင်ရန် အရေးကြီးသည်။
ဒီမှာ `async` အကြောင်း video တစ်ခုရှိပါတယ်:
`async` နှင့် `await` ကို အသုံးပြု၍ promise များကို စီမံရန် ဗီဒီယိုတစ်ခုကို ကြည့်ပါ:
[![Async and Await for managing promises](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "Async and Await for managing promises")
> 🎥 အထက်ပါပုံကိုနှိပ်ပြီး async/await အကြောင်း video ကိုကြည့်ပါ။
> 🎥 အထက်ပါပုံကို click လုပ်ကာ async/await အကြောင်း ဗီဒီယိုကို ကြည့်ပါ။
C02Signal API ကို query လုပ်ဖို့ function အသစ်တစ်ခု ဖန်တီးပါ:
C02Signal API ကို query လုပ်ရန် function အသစ်တစ်ခုကို ဖန်တီးပါ:
```JavaScript
import axios from '../node_modules/axios';
@ -205,36 +205,36 @@ async function displayCarbonUsage(apiKey, region) {
}
```
ဒီ function က ကြီးမားပါတယ်။ ဘာဖြစ်နေလဲဆိုတာ ကြည့်ပါ:
ဒီ function သည် အကြီးမားဆုံးဖြစ်သည်။ ဒီမှာ ဘာတွေဖြစ်နေလဲ?
- best practices အတိုင်း `async` keyword ကို အသုံးပြုပြီး function ကို asynchronous ဖြစ်အောင်လုပ်ထားပါတယ်။ function ထဲမှာ `try/catch` block ပါဝင်ပြီး API က data ပြန်လာတဲ့အခါ promise တစ်ခု return လုပ်ပါမယ်။ API က data ပြန်လာမယ့်အမြန်နှုန်းကို သင်ထိန်းချုပ်လို့မရတဲ့အတွက် (တစ်ခါတစ်လေတော့ response မရနိုင်ပါဘူး) asynchronous ဖြစ်အောင်ရေးထားတာပါ
- co2signal API ကို သင့် region ရဲ့ data ကိုရယူဖို့ query လုပ်ပါတယ်၊ သင့် API Key ကို အသုံးပြုဖို့ header parameters ထဲမှာ authentication အမျိုးအစားတစ်ခုလိုအပ်ပါတယ်။
- API က response ပြန်လာတဲ့အခါ၊ response data ရဲ့ အစိတ်အပိုင်းတွေကို သင့် screen ရဲ့ data ပြသဖို့ သတ်မှတ်ထားတဲ့နေရာတွေမှာ assign လုပ်ပါတယ်
- error ဖြစ်ခဲ့ရင် သို့မဟုတ် ရလဒ်မရှိခဲ့ရင် error message ကို ပြသပါတယ်
- best practices ကိုလိုက်နာပြီး `async` keyword ကို အသုံးပြုကာ function ကို asynchronous အဖြစ်လုပ်ဆောင်သည်။ function မှာ `try/catch` block ပါရှိပြီး API response ရလာသောအခါ promise ကို return ပြန်ပါမည်။ API response ရရှိမည့်အမြန်နှုန်းကို သင့်အနေနဲ့ control လုပ်လို့မရသောကြောင့် asynchronous အနေနဲ့ handle လုပ်ရန်လိုအပ်သည်
- co2signal API ကို query လုပ်ကာ region data ကိုရယူပြီး API Key ကို အသုံးပြုသည်။ အဲဒီ key ကို အသုံးပြုရန် header parameters မှာ authentication type ကို အသုံးပြုရပါမည်။
- API response ရလာသောအခါ response data ရဲ့ အစိတ်အပိုင်းများကို သင့် screen ရဲ့ သတ်မှတ်ထားသောနေရာများတွင် assign လုပ်ပါ
- error ဖြစ်ပေါ်ပါက သို့မဟုတ် result မရှိပါက error message ကို ပြသပါ
✅ asynchronous programming patterns ကို သင့် toolbox ထဲမှာ ထည့်သွင်းထားဖို့ အရေးကြီးပါတယ်။ ဒီလို code ကို configure လုပ်နိုင်တဲ့ နည်းလမ်းမျိုးစုံကို [ဖတ်ရှုပါ](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)။
✅ asynchronous programming pattern များကို သင့် toolbox မှာ ထည့်သွင်းရန် အရေးကြီးသည်။ [ဒီ code အမျိုးအစား](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) ကို configure လုပ်နိုင်သော နည်းလမ်းများကို ဖတ်ရှုပါ
ဂုဏ်ယူပါတယ်! သင့် extension ကို build (`npm run build`) လုပ်ပြီး၊ extensions pane မှာ refresh လုပ်ပါက သင့် extension အလုပ်လုပ်နေပါပြီ! icon ကတော့ အလုပ်မလုပ်သေးပါဘူး၊ နောက်သင်ခန်းစာမှာ ပြင်ဆင်ပါမယ်။
ဂုဏ်ယူပါတယ်! သင့် extension ကို build (`npm run build`) လုပ်ပြီး extension pane မှာ refresh လုပ်ပါက အလုပ်လုပ်နေသော extension ရရှိပါမည်! အလုပ်မလုပ်သေးသောအရာတစ်ခုက icon ဖြစ်ပြီး နောက်သင်ခန်းစာမှာ ပြင်ဆင်ပါမည်။
---
## 🚀 စိန်ခေါ်မှု
ဒီသင်ခန်းစာတွေမှာ API အမျိုးအစားအတော်များများကို ဆွေးနွေးခဲ့ပါတယ်။ web API တစ်ခုကို ရွေးပြီး အနက်ရှိုင်းဆုံး သုတေသနလုပ်ပါ။ ဥပမာအားဖြင့် browser တွေထဲမှာ ရရှိနိုင်တဲ့ [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) ကိုကြည့်ပါ။ သင်အမြင်မှာ API တစ်ခုက ဘယ်လိုဖြစ်ရင် အကောင်းဆုံးဖြစ်မလဲ?
ဒီသင်ခန်းစာများမှာ API အမျိုးအစားများစွာကို ဆွေးနွေးခဲ့ပါသည်။ web API တစ်ခုကို ရွေးပြီး အဲဒီ API ရဲ့ အကျိုးကျေးဇူးများကို သုတေသနလုပ်ပါ။ ဥပမာအားဖြင့် browser တွေမှာ ရရှိနိုင်သော [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) ကို ကြည့်ပါ။ သင်အမြင်မှာ API တစ်ခုက ဘယ်လိုကောင်းမြတ်သင့်သလဲ?
## မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု
## မိန့်ခွန်းပြီးနောက်မေးခွန်းများ
[မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/26)
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/26)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
ဒီသင်ခန်းစာမှာ LocalStorage နဲ့ APIs အကြောင်း သင်ယူခဲ့ပါတယ်၊ professional web developer အတွက် အလွန်အသုံးဝင်ပါတယ်။ ဒီနှစ်ခုက ဘယ်လိုပေါင်းစပ်လုပ်ဆောင်နိုင်မလဲဆိုတာ စဉ်းစားကြည့်ပါ။ API ကို အသုံးပြုဖို့အတွက် items တွေကို သိမ်းဆည်းမယ့် web site တစ်ခုကို ဘယ်လို architect လုပ်မလဲဆိုတာ စဉ်းစားပါ။
ဒီသင်ခန်းစာမှာ LocalStorage နှင့် API များကို လေ့လာခဲ့ပြီး professional web developer အတွက် အလွန်အသုံးဝင်သည်။ ဒီနှစ်ခုက ဘယ်လိုပေါင်းစပ်လုပ်ဆောင်သလဲဆိုတာ စဉ်းစားပါ။ API ကို အသုံးပြုရန် item များကို သိမ်းဆည်းမည့် website ကို ဘယ်လို architect လုပ်မလဲဆိုတာ စဉ်းစားပါ။
## လုပ်ငန်း
## အိမ်စာ
[Adopt an API](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရ အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှု ဝန်ဆောင်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,73 +1,73 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f198c6b817b4b2a99749f4662e7cae98",
"translation_date": "2025-08-27T22:12:33+00:00",
"original_hash": "49b58721a71cfda824e2f3e1f46908c6",
"translation_date": "2025-08-28T18:35:41+00:00",
"source_file": "5-browser-extension/3-background-tasks-and-performance/README.md",
"language_code": "my"
}
-->
# Browser Extension Project Part 3: Background Tasks နှင့် Performance ကိုလေ့လာပါ
## မိန့်ခွန်းမတိုင်မီ Quiz
## မိန့်ခွန်းမတင်မီ စစ်ဆေးမှု
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/27)
[မိန့်ခွန်းမတင်မီ စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/27)
### အကျဉ်းချုပ်
### နိဒါန်း
ဒီ module ရဲ့ နောက်ဆုံးသင်ခန်းစာနှစ်ခုမှာ API ကနေ fetch လုပ်ထားတဲ့ data ကို ဖော်ပြဖို့ form တစ်ခုနဲ့ display area တစ်ခုကို ဘယ်လိုတည်ဆောက်ရမယ်ဆိုတာကို သင်လေ့လာခဲ့ပါတယ်။ ဒါဟာ web presence တစ်ခုကို ဖန်တီးတဲ့အခါမှာ အလွန်ပုံမှန်တဲ့နည်းလမ်းတစ်ခုဖြစ်ပါတယ်။ သင် asynchronous data fetching ကို handle လုပ်ပုံကိုပါ သင်ယူခဲ့ပါတယ်။ Browser extension ကို အခုဆိုရင် အလွန်နီးကပ်ပြီး ပြီးမြောက်သွားပါပြီ
ဒီ module ရဲ့ နောက်ဆုံးအတန်းနှစ်ခုမှာ API ကနေ data ကို ရယူပြီး ဖောင်နှင့် ပြသမှုဧရိယာကို ဘယ်လိုတည်ဆောက်ရမယ်ဆိုတာကို သင်လေ့လာခဲ့ပါတယ်။ ဒါဟာ web ပေါ်မှာ web presence တစ်ခုကို ဖန်တီးတဲ့ အခြေခံနည်းလမ်းတစ်ခုဖြစ်ပါတယ်။ သင် asynchronous data fetching ကို handle ဘယ်လိုလုပ်ရမယ်ဆိုတာတောင်လေ့လာခဲ့ပါတယ်။ သင့် browser extension ဟာ အနည်းငယ်ပဲ ကျန်တော့ပြီး ပြီးစီးတော့မယ်ဖြစ်ပါတယ်
အခုတော့ background tasks တချို့ကို စီမံခန့်ခွဲဖို့လိုအပ်ပါတယ်၊ အထူးသဖြင့် extension ရဲ့ icon ရဲ့ အရောင်ကို refresh လုပ်ပုံကိုပါ။ ဒါကြောင့် browser က ဒီလို tasks တွေကို ဘယ်လို handle လုပ်သလဲဆိုတာကို ဆွေးနွေးဖို့ အချိန်ကောင်းတစ်ခုဖြစ်ပါတယ်။ သင်တည်ဆောက်နေတဲ့ web assets တွေ performance ရဲ့ context မှာ browser tasks တွေကို စဉ်းစားကြည့်ရအောင်။
အခုတော့ background tasks တချို့ကို စီမံခန့်ခွဲဖို့လိုအပ်ပါတယ်၊ အထူးသဖြင့် extension ရဲ့ icon အရောင်ကို refresh လုပ်တာပါ။ ဒါကြောင့် browser က ဒီလို tasks တွေကို ဘယ်လိုစီမံတယ်ဆိုတာကို ပြောဖို့ အချိန်ကောင်းတစ်ခုဖြစ်ပါတယ်။ သင့်ရဲ့ web assets တွေကို တည်ဆောက်နေစဉ်မှာ ဒီ browser tasks တွေကို performance ရဲ့ အရပ်ကနေ စဉ်းစားကြည့်ရအောင်။
## Web Performance အခြေခံ
> "Website performance ဆိုတာ နှစ်ခုအကြောင်းပါပဲ - စာမျက်နှာ load လုပ်တာ ဘယ်လောက်မြန်တယ်၊ code run လုပ်တာ ဘယ်လောက်မြန်တယ်။" -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
> "Website performance ဆိုတာ နှစ်ခုပါပဲ - စာမျက်နှာဘယ်လောက်မြန်မြန် load တယ်၊ နဲ့ အဲ့ဒီမှာရှိတဲ့ code ဘယ်လောက်မြန်မြန် run တယ်။" -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
Website တွေကို အမျိုးမျိုးသော devices, users, နဲ့ situations တွေမှာ အလွန်မြန်ဆန်အောင် ဖန်တီးပုံကို လေ့လာတဲ့အခါမှာ အလွန်ကျယ်ပြန့်တဲ့အကြောင်းအရာတစ်ခုဖြစ်ပါတယ်။ သင် browser extension တစ်ခုတည်ဆောက်နေစဉ်မှာ သတိထားရမယ့်အချက်အချို့ကို အောက်မှာဖော်ပြထားပါတယ်။
Website တွေကို အမျိုးမျိုးသော device တွေ၊ user တွေ၊ နဲ့ အခြေအနေတွေမှာ အလွန်မြန်ဆန်အောင်လုပ်ပေးဖို့နည်းလမ်းတွေဟာ အလွန်ကျယ်ပြန့်ပါတယ်။ သင် browser extension တစ်ခုဖြစ်စေ၊ standard web project တစ်ခုဖြစ်စေ တည်ဆောက်နေစဉ်မှာ သတိထားရမယ့်အချက်တချို့ကို ဒီမှာဖော်ပြထားပါတယ်။
သင့် site ကို ထိရောက်စွာ run လုပ်နေကြောင်း သေချာစေဖို့ ပထမဆုံး လိုအပ်တာက performance data ကို စုဆောင်းရပါမယ်။ ဒီအချက်ကို သင့် web browser ရဲ့ developer tools မှာ စတင်လေ့လာနိုင်ပါတယ်။ Edge browser မှာ "Settings and more" button (browser ရဲ့ အပေါ်ယံညာဘက်မှာရှိတဲ့ သုံးခုတိုင် icon) ကိုရွေးပြီး More Tools > Developer Tools ကိုသွားပါ၊ ပြီးရင် Performance tab ကိုဖွင့်ပါ။ Windows မှာ `Ctrl` + `Shift` + `I` သို့မဟုတ် Mac မှာ `Option` + `Command` + `I` ကို အသုံးပြုပြီး developer tools ကိုဖွင့်နိုင်ပါတယ်။
သင့် site ကို ထိရောက်စွာ run နိုင်အောင်လုပ်ဖို့ ပထမဆုံး လိုအပ်တာက performance data ကို စုဆောင်းဖို့ပါ။ ဒီအချက်ကို သင့် web browser ရဲ့ developer tools မှာ စတင်စစ်ဆေးနိုင်ပါတယ်။ Edge browser မှာ "Settings and more" button (browser ရဲ့ အပေါ်ယံညာဘက်ထောင့်မှာရှိတဲ့ သုံးစင်း icon) ကိုရွေးပြီး More Tools > Developer Tools ကိုသွားပြီး Performance tab ကိုဖွင့်ပါ။ Windows မှာ `Ctrl` + `Shift` + `I` သို့မဟုတ် Mac မှာ `Option` + `Command` + `I` ကို အသုံးပြုပြီး developer tools ကိုဖွင့်နိုင်ပါတယ်။
Performance tab မှာ Profiling tool ပါဝင်ပါတယ်။ Website တစ်ခုကိုဖွင့်ပါ (ဥပမာ [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon))၊ 'Record' button ကို click လုပ်ပြီး site ကို refresh လုပ်ပါ။ Record ကို မည်သည့်အချိန်မှာမဆို ရပ်နိုင်ပြီး site ကို 'script', 'render', နဲ့ 'paint' လုပ်တဲ့ routines တွေကို ကြည့်နိုင်ပါမယ်။
Performance tab မှာ Profiling tool တစ်ခုပါဝင်ပါတယ်။ Website တစ်ခုကိုဖွင့်ပါ (ဥပမာ [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon))၊ 'Record' button ကိုနှိပ်ပြီး site ကို refresh လုပ်ပါ။ အချိန်မရွေး recording ကိုရပ်လိုက်ပါ၊ သင် 'script', 'render', နဲ့ 'paint' လုပ်တဲ့ routines တွေကိုကြည့်နိုင်ပါလိမ့်မယ်။
![Edge profiler](../../../../translated_images/profiler.5a4a62479c5df01cfec9aab74173dba13f91d2c968e1a1ae434c26165792df15.my.png)
✅ [Microsoft Documentation](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) မှာ Edge ရဲ့ Performance panel ကိုလေ့လာပါ။
> အကြံပြုချက်: သင့် website ရဲ့ startup time ကို တိကျစွာသိဖို့ browser ရဲ့ cache ကို ရှင်းလင်းပါ။
> အကြံပြုချက် - သင့် website ရဲ့ startup time ကို တိကျစွာဖော်ပြဖို့ browser ရဲ့ cache ကို ရှင်းလင်းပါ။
Profile timeline ရဲ့ elements တွေကိုရွေးပြီး page load လုပ်နေစဉ်ဖြစ်ပျက်တဲ့ events တွေကို zoom လုပ်ကြည့်ပါ။
Profile timeline ရဲ့ အစိတ်အပိုင်းတွေကိုရွေးပြီး သင့်စာမျက်နှာ load လုပ်နေစဉ်ဖြစ်ပျက်တဲ့ အဖြစ်အပျက်တွေကို zoom in လုပ်ကြည့်ပါ။
Profile timeline ရဲ့ အပိုင်းတစ်ခုကိုရွေးပြီး summary pane မှာ page performance ရဲ့ snapshot ကိုကြည့်ပါ:
Profile timeline ရဲ့ အစိတ်အပိုင်းတစ်ခုကိုရွေးပြီး summary pane မှာ သင့်စာမျက်နှာ performance ရဲ့ snapshot ကိုကြည့်ပါ။
![Edge profiler snapshot](../../../../translated_images/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.my.png)
Event Log pane ကိုစစ်ဆေးပြီး event တစ်ခုခု 15 ms ထက်ပိုကြာနေမလားကြည့်ပါ:
Event Log pane ကိုစစ်ဆေးပြီး 15 ms ထက်ပိုကြာတဲ့ event တစ်ခုခုရှိမရှိကြည့်ပါ။
![Edge event log](../../../../translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.my.png)
Profiler ကိုနားလည်ပါ! ဒီ site ရဲ့ developer tools ကိုဖွင့်ပြီး bottlenecks ရှိမရှိစစ်ဆေးပါ။ ဘာ asset က အလွန်နှေးနေသလဲ? ဘာ asset က အမြန်ဆုံး load လုပ်သွားသလဲ?
သင့် profiler ကိုနားလည်ပါ! ဒီ site ရဲ့ developer tools ကိုဖွင့်ပြီး bottlenecks ရှိမရှိကြည့်ပါ။ ဘယ် asset က အမြန်ဆုံး load လုပ်သလဲ? ဘယ် asset က အနှေးဆုံးလဲ?
## Profiling checks
## Profiling စစ်ဆေးမှုများ
အထွေထွေအားဖြင့် production မှာ deploy လုပ်တဲ့အခါမှာ အဆင်မပြေတဲ့အရာတွေမဖြစ်စေရန် web developer တစ်ဦးအနေနဲ့ သတိထားရမယ့် "ပြဿနာရှိနိုင်တဲ့နေရာ" အချို့ရှိပါတယ်။
ယေဘူယျအားဖြင့် site တစ်ခုကို production မှာ deploy လုပ်ဖို့အချိန်ရောက်တဲ့အခါ အဆိုးရွားဆုံးအံ့ဩစရာတွေကိုရှောင်ရှားဖို့အတွက် web developer တစ်ဦးအနေနဲ့ သတိထားရမယ့် "ပြဿနာဧရိယာ" တချို့ရှိပါတယ်။
**Asset sizes**: အခုနှစ်တွေမှာ web ဟာ "ပိုလေး"လာပြီး "ပိုနှေး"လာပါတယ်။ ဒီအလေးချိန်တစ်ချို့ဟာ images တွေကို အသုံးပြုမှုနဲ့ဆက်စပ်ပါတယ်။
**Asset sizes**: Web ဟာ မကြာသေးခင်ကတည်းက 'ပိုလေး'လာပြီး အနှေးလာပါတယ်။ ဒီအလေးတစ်ခုမှာ images တွေကို အသုံးပြုမှုနဲ့ဆက်စပ်ပါတယ်။
✅ [Internet Archive](https://httparchive.org/reports/page-weight) ကိုကြည့်ပြီး page weight ရဲ့ သမိုင်းကြောင်းနဲ့ အခြားအချက်အလက်တွေကိုလေ့လာပါ။
✅ [Internet Archive](https://httparchive.org/reports/page-weight) ကိုကြည့်ပြီး page weight ရဲ့ သမိုင်းကြောင်းနဲ့ပိုမိုသိရှိပါ။
သင့် images တွေကို optimize လုပ်ပြီး သုံးစွဲသူတွေအတွက် size နဲ့ resolution ကိုသင့်တော်အောင်ပေးသင့်ပါတယ်။
သင့် images တွေကို optimize လုပ်ပြီး သင့် user တွေအတွက် size နဲ့ resolution မှန်ကန်တဲ့အတိုင်းပေးပို့တာက လုပ်ဆောင်သင့်တဲ့အရာတစ်ခုဖြစ်ပါတယ်။
**DOM traversals**: Browser ဟာ သင့်ရေးထားတဲ့ code အပေါ်မူတည်ပြီး Document Object Model ကို build လုပ်ရပါတယ်၊ ဒါကြောင့် page performance ကိုကောင်းမွန်စေဖို့ tags တွေကို လိုအပ်သလောက်သာအသုံးပြုပါ။ အဓိက style sheet မှာ မလိုအပ်တဲ့ CSS တွေကို optimize လုပ်ပါ
**DOM traversals**: Browser ဟာ သင့်ရေးထားတဲ့ code အပေါ်မူတည်ပြီး Document Object Model ကို တည်ဆောက်ရပါတယ်။ ဒါကြောင့် သင့်စာမျက်နှာ performance ကိုကောင်းမွန်အောင်လုပ်ဖို့ tags တွေကို အနည်းဆုံးထားပြီး စာမျက်နှာအတွက်လိုအပ်တာပဲ အသုံးပြုနဲ့ style လုပ်ပါ။ ဥပမာအားဖြင့် တစ်ခုတည်းသောစာမျက်နှာမှာသာအသုံးပြုမယ့် styles တွေကို main style sheet မှာထည့်စရာမလိုပါဘူး
**JavaScript**: JavaScript developer တစ်ဦးအနေနဲ့ 'render-blocking' scripts တွေကို သတိထားရပါမယ်၊ အဲဒီ scripts တွေကို DOM ကို traverse နဲ့ paint လုပ်မတိုင်မီ load လုပ်ဖို့လိုအပ်ပါတယ်။ `defer` ကို inline scripts တွေမှာ အသုံးပြုပါ။
**JavaScript**: JavaScript developer တစ်ဦးအနေနဲ့ 'render-blocking' scripts တွေကို သတိထားရပါမယ်။ အဲ့ဒီ scripts တွေဟာ DOM ကို traverse နဲ့ paint လုပ်ဖို့မတိုင်ခင် load လုပ်ဖို့လိုအပ်ပါတယ်။ `defer` ကို inline scripts တွေမှာအသုံးပြုဖို့စဉ်းစားပါ (Terrarium module မှာလုပ်သလို)
✅ [Site Speed Test website](https://www.webpagetest.org/) မှာ sites တွေကိုစမ်းကြည့်ပြီး site performance ကိုသတ်မှတ်တဲ့ common checks တွေကိုလေ့လာပါ။
✅ [Site Speed Test website](https://www.webpagetest.org/) မှာ site performance ကိုစစ်ဆေးတဲ့အခါ သာမန်စစ်ဆေးမှုတွေကိုလေ့လာပါ။
Browser က သင့် assets တွေကို render လုပ်ပုံကို နားလည်ပြီးရင် extension ကိုပြီးမြောက်အောင်လုပ်ဖို့ လိုအပ်တဲ့အရာတွေကိုကြည့်ရအောင်:
Browser က သင့်ပေးပို့တဲ့ assets တွေကို ဘယ်လို render လုပ်တယ်ဆိုတာကို နားလည်ပြီးပြီဆိုရင် သင့် extension ကိုပြီးစီးဖို့လိုအပ်တဲ့ အနောက်ဆုံးအချက်အချို့ကိုကြည့်ရအောင်:
### အရောင်ကိုတွက်ချက်ဖို့ function တစ်ခုဖန်တီးပါ
### အရောင်တွက်ချက်ဖို့ function တစ်ခုဖန်တီးပါ
`/src/index.js` မှာ `calculateColor()` ဆိုတဲ့ function ကို DOM ကို access လုပ်ဖို့ const variables တွေကို set လုပ်ပြီးနောက်ထည့်ပါ:
`/src/index.js` မှာ `calculateColor()` လို့ခေါ်တဲ့ function တစ်ခုကို DOM ကို access လုပ်ဖို့ သတ်မှတ်ထားတဲ့ `const` variables တွေရဲ့နောက်မှာထည့်ပါ။
```JavaScript
function calculateColor(value) {
@ -88,19 +88,19 @@ function calculateColor(value) {
}
```
ဒီမှာ ဘာဖြစ်နေလဲ? API call ကနေ carbon intensity value ကို pass လုပ်ပြီး colors array မှာရှိတဲ့ index နဲ့ value ရဲ့နီးကပ်မှုကိုတွက်ချက်ပါတယ်။ ပြီးရင် chrome runtime ကို အနီးဆုံး color value ကိုပို့ပါတယ်။
ဒီမှာဘာဖြစ်နေလဲ? သင် API call ကနေရရှိတဲ့ carbon intensity value ကို pass လုပ်ပြီး colors array မှာရှိတဲ့ index နဲ့ ဘယ်လောက်နီးလဲဆိုတာတွက်ချက်ပါတယ်။ ပြီးရင် အဲ့ဒီနီးဆုံး color value ကို chrome runtime ကိုပို့ပါတယ်။
chrome.runtime မှာ [API](https://developer.chrome.com/extensions/runtime) တစ်ခုရှိပြီး background tasks အမျိုးမျိုးကို handle လုပ်ပါတယ်၊ သင့် extension က ဒီ tools တွေကိုအသုံးပြုနေပါတယ်:
Chrome.runtime မှာ background tasks အမျိုးမျိုးကို handle လုပ်တဲ့ [API](https://developer.chrome.com/extensions/runtime) ရှိပါတယ်၊ သင့် extension က အဲ့ဒီ API ကိုအသုံးပြုနေပါတယ်။
> "chrome.runtime API ကို အသုံးပြုပြီး background page ကို retrieve လုပ်ပါ၊ manifest ရဲ့ details တွေကို return လုပ်ပါ၊ app သို့မဟုတ် extension lifecycle မှာဖြစ်ပျက်တဲ့ events တွေကို နားထောင်ပြီး တုံ့ပြန်ပါ။ URL တွေကို fully-qualified URLs အဖြစ်ပြောင်းဖို့လည်း API ကိုအသုံးပြုနိုင်ပါတယ်။"
> "Chrome.runtime API ကို background page ကို retrieve လုပ်ဖို့၊ manifest အကြောင်းအရာတွေကိုပြန်ပေးဖို့၊ နဲ့ app သို့မဟုတ် extension lifecycle မှာဖြစ်ပျက်တဲ့ events တွေကိုနားထောင်ပြီး တုံ့ပြန်ဖို့အသုံးပြုပါ။ ဒီ API ကို relative path URLs တွေကို fully-qualified URLs တွေပြောင်းဖို့လည်းအသုံးပြုနိုင်ပါတယ်။"
Edge browser အတွက် extension ကို develop လုပ်နေတဲ့အခါ chrome API ကိုအသုံးပြုနေတာ အံ့ဩစရာဖြစ်နိုင်ပါတယ်။ Edge ရဲ့ နောက်ဆုံး browser versions တွေဟာ Chromium browser engine ပေါ်မှာ run လုပ်နေတဲ့အတွက် ဒီ tools တွေကိုအသုံးပြုနိုင်ပါတယ်။
သင် Edge အတွက် browser extension တစ်ခုကို develop လုပ်နေတယ်ဆိုရင် chrome API ကိုအသုံးပြုနေတာအံ့ဩစရာဖြစ်နိုင်ပါတယ်။ Edge ရဲ့ နောက်ဆုံး browser versions တွေဟာ Chromium browser engine ပေါ်မှာ run လုပ်တာကြောင့် ဒီ tools တွေကိုအသုံးပြုနိုင်ပါတယ်။
> သတိပြုပါ၊ browser extension ကို profile လုပ်ချင်ရင် extension ကိုယ်တိုင်ရဲ့ dev tools ကိုဖွင့်ပါ၊ အဲဒါဟာ browser instance သီးသန့်တစ်ခုဖြစ်ပါတယ်။
> မှတ်ချက် - browser extension တစ်ခုကို profile လုပ်ချင်တယ်ဆိုရင် extension ကိုယ်တိုင်ရဲ့ dev tools မှာဖွင့်ပြီးစစ်ဆေးပါ၊ အဲ့ဒါဟာ သီးခြား browser instance တစ်ခုဖြစ်ပါတယ်။
### Default icon color ကို set လုပ်ပါ
### Default icon color ကိုသတ်မှတ်ပါ
အခုတော့ `init()` function မှာ chrome ရဲ့ `updateIcon` action ကိုအသုံးပြုပြီး generic green color ကို default အဖြစ် set လုပ်ပါ:
အခုတော့ `init()` function မှာ chrome ရဲ့ `updateIcon` action ကိုခေါ်ပြီး generic green အဖြစ် icon ကိုစတင်သတ်မှတ်ပါ။
```JavaScript
chrome.runtime.sendMessage({
@ -113,14 +113,14 @@ chrome.runtime.sendMessage({
### Function ကိုခေါ်ပြီး call ကို execute လုပ်ပါ
နောက်ဆုံးမှာ သင်ဖန်တီးထားတဲ့ function ကို C02Signal API က promise မှာထည့်ပြီးခေါ်ပါ:
နောက်ဆုံးမှာ သင်ဖန်တီးထားတဲ့ function ကို C02Signal API က promise ပြန်ပေးတဲ့နေရာမှာထည့်ပါ။
```JavaScript
//let CO2...
calculateColor(CO2);
```
နောက်ဆုံးမှာ `/dist/background.js` မှာ background action calls တွေကိုနားထောင်ဖို့ listener ကိုထည့်ပါ:
နောက်ဆုံးမှာ `/dist/background.js` မှာ background action calls တွေကိုနားထောင်ဖို့ listener တစ်ခုထည့်ပါ။
```JavaScript
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
@ -142,35 +142,35 @@ function drawIcon(value) {
}
```
ဒီ code မှာ backend task manager ကို message တစ်ခုခုရောက်လာတဲ့အခါ listener ကိုထည့်ထားပါတယ်။ Message က 'updateIcon' ဆိုရင်တော့ Canvas API ကိုအသုံးပြုပြီး အရောင်မှန်တဲ့ icon ကို draw လုပ်ဖို့နောက် code ကို run လုပ်ပါတယ်။
ဒီ code မှာ backend task manager ကိုလာတဲ့ messages တွေအားလုံးအတွက် listener တစ်ခုထည့်ထားပါတယ်။ 'updateIcon' လို့ခေါ်ရင်တော့ Canvas API ကိုအသုံးပြုပြီး သင့်ရဲ့ icon ကိုမှန်ကန်တဲ့အရောင်နဲ့ဆွဲဆောင်ဖို့ code ကို run လုပ်ပါတယ်။
✅ [Space Game lessons](../../6-space-game/2-drawing-to-canvas/README.md) မှာ Canvas API ကိုပိုမိုလေ့လာပါ
✅ [Space Game lessons](../../6-space-game/2-drawing-to-canvas/README.md) မှာ Canvas API အကြောင်းပိုမိုလေ့လာနိုင်ပါမယ်
အခုတော့ extension ကိုပြန် build (`npm run build`) လုပ်ပြီး refresh နဲ့ launch လုပ်ပါ၊ အရောင်ပြောင်းတာကိုကြည့်ပါ။ အခုတော့ errands သွားလုပ်ဖို့ သို့မဟုတ် ပန်းကန်ဆေးဖို့အချိန်ကောင်းလား? အခုတော့သိပါပြီ!
အခုတော့ သင့် extension ကိုပြန်တည်ဆောက်ပါ (`npm run build`), refresh လုပ်ပြီး extension ကိုဖွင့်ပါ၊ အရောင်ပြောင်းတာကိုကြည့်ပါ။ အခုတော့ errands သွားလုပ်ဖို့ သို့မဟုတ် ပန်းကန်ဆေးဖို့အချိန်ကောင်းလား? အခုတော့သိပြီနော်!
အောင်မြင်ပါတယ်၊ သင်အသုံးဝင်တဲ့ browser extension တစ်ခုကိုတည်ဆောက်ပြီး browser ရဲ့လုပ်ပုံနဲ့ performance ကို profile လုပ်ပုံကိုလေ့လာပြီးပါပြီ။
သင်အသုံးဝင်တဲ့ browser extension တစ်ခုကိုတည်ဆောက်ပြီး browser ဘယ်လိုအလုပ်လုပ်တယ်ဆိုတာနဲ့ performance ကိုဘယ်လို profile လုပ်ရမယ်ဆိုတာကိုလေ့လာပြီးပါပြီ။
---
## 🚀 စိန်ခေါ်မှု
အရင်ကတည်ဆောက်ထားတဲ့ open source websites တွေကိုစစ်ဆေးပြီး၊ GitHub history အပေါ်မူတည်ပြီး performance အတွက် optimization လုပ်ပုံကိုသတ်မှတ်နိုင်ပါသလား? အများဆုံး pain point ဘာဖြစ်ပါသလဲ?
အရင်ကတည်ရှိခဲ့တဲ့ open source websites တချို့ကိုစူးစမ်းပြီး၊ GitHub history အပေါ်မူတည်ပြီး performance အတွက် ဘယ်လို optimize လုပ်ခဲ့တယ်ဆိုတာရှာဖွေကြည့်ပါ။ အများဆုံး pain point ကဘာလဲ?
## မိန့်ခွန်းပြီးနောက် Quiz
## မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/28)
[မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/28)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
[performance newsletter](https://perf.email/) မှာ sign up လုပ်ဖို့စဉ်းစားပါ။
[performance newsletter](https://perf.email/) တစ်ခုအတွက် စာရင်းသွင်းစဉ်းစားပါ။
Browser တွေက web performance ကိုဘယ်လိုသတ်မှတ်တယ်ဆိုတာကို web tools ရဲ့ performance tabs တွေကိုကြည့်ပြီးလေ့လာပါ။ အဓိကကွာခြားချက်တွေရှိပါသလား?
Browser တွေက web performance ကိုဘယ်လိုတိုင်းတာတယ်ဆိုတာကို သူတို့ရဲ့ web tools ရဲ့ performance tabs တွေကိုကြည့်ပြီးစူးစမ်းပါ။ အဓိကကွာခြားချက်တစ်ခုခုတွေတွေ့ရလား?
## လုပ်ငန်း
## အိမ်စာ
[Analyze a site for performance](assignment.md)
[Site performance ကိုခွဲခြမ်းစိတ်ဖြာပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှားမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူလဘာသာစကားဖြင့် အာဏာတရားရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှု ဝန်ဆောင်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,46 +1,46 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "d9da6dc61fb712b29f65e108c79b8a5d",
"translation_date": "2025-08-27T22:27:07+00:00",
"original_hash": "979cfcce2413a87d9e4c67eb79234bc3",
"translation_date": "2025-08-28T18:40:54+00:00",
"source_file": "6-space-game/1-introduction/README.md",
"language_code": "my"
}
-->
# အာကာသဂိမ်းတစ်ခု တည်ဆောက်ခြင်း အပိုင်း ၁: နိဒါန်း
# အာကာသဂိမ်းတည်ဆောက်ခြင်း အပိုင်း ၁: အနိမ့်ဆုံးအကျဉ်းချုပ်
![video](../../../../6-space-game/images/pewpew.gif)
![ဗီဒီယို](../../../../6-space-game/images/pewpew.gif)
## မိန့်ခွန်းမတိုင်မီ စမ်းမေးခွန်း
## မိန့်ခွန်းမပြုမီ စစ်တမ်း
[မိန့်ခွန်းမတိုင်မီ စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/29)
[မိန့်ခွန်းမပြုမီ စစ်တမ်း](https://ff-quizzes.netlify.app/web/quiz/29)
### ဂိမ်းဖွံ့ဖြိုးရေးအတွက် Inheritance နှင့် Composition
### ဂိမ်းတိုးတက်မှုတွင် အမွေဆက်ခြင်းနှင့် ဖွဲ့စည်းမှု
ယခင်သင်ခန်းစာများတွင် သင်တည်ဆောက်ခဲ့သော app များသည် အတိုချုပ်သော ပရောဂျက်များဖြစ်သောကြောင့် ဒီဇိုင်းအဆောက်အအုံကို မသိပ်စဉ်းစားရန်လိုအပ်ခဲ့ပါ။ သို့သော် သင့် application များသည် အရွယ်အစားနှင့် အကျယ်အဝန်းကြီးလာသည်နှင့်အမျှ ဒီဇိုင်းဆိုင်ရာ ဆုံးဖြတ်ချက်များသည် ပိုမိုအရေးကြီးလာပါသည်။ JavaScript တွင် application များကို ကြီးမားစွာ ဖန်တီးရန်အတွက် နည်းလမ်းနှစ်ခုရှိပါသည် - *composition* သို့မဟုတ် *inheritance* ဖြစ်ပါသည်။ နှစ်ခုစလုံးတွင် အားသာချက်နှင့် အားနည်းချက်များရှိသော်လည်း ဂိမ်း၏အခြေခံအနေအထားမှ ရှင်းပြကြပါစို့
ယခင်သင်ခန်းစာများတွင် သင်တည်ဆောက်ခဲ့သော app များသည် အတိုင်းအတာသေးငယ်သောကြောင့် ဒီဇိုင်းအဆောက်အအုံကို စိုးရိမ်ရန်မလိုအပ်ခဲ့ပါ။ သို့သော် သင့် application များသည် အရွယ်အစားနှင့် အတိုင်းအတာကြီးလာသည်နှင့်အမျှ ဒီဇိုင်းဆိုင်ရာ ဆုံးဖြတ်ချက်များသည် ပိုမိုအရေးပါလာသည်။ JavaScript တွင် application ကြီးများကို ဖန်တီးရန် နည်းလမ်းကြီးနှစ်ခုရှိသည် - *ဖွဲ့စည်းမှု* သို့မဟုတ် *အမွေဆက်ခြင်း*။ နှစ်ခုစလုံးတွင် အားသာချက်နှင့် အားနည်းချက်များရှိသော်လည်း ဂိမ်း၏အခြေခံအနေအထားမှ ရှင်းလင်းဖော်ပြပါမည်
✅ အတော်လေးကျော်ကြားသော programming စာအုပ်တစ်အုပ်မှာ [design patterns](https://en.wikipedia.org/wiki/Design_Patterns) အကြောင်းကို ရေးသားထားခြင်းဖြစ်ပါသည်။
✅ အတော်လေးကျော်ကြားသော programming စာအုပ်တစ်အုပ်မှာ [design patterns](https://en.wikipedia.org/wiki/Design_Patterns) နှင့်ဆိုင်သည်။
ဂိမ်းတစ်ခုတွင် `game objects` ဆိုသည်မှာ မျက်နှာပြင်ပေါ်တွင် ရှိနေသော objects များဖြစ်ပါသည်။ ၎င်းတို့သည် cartesian coordinate system ပေါ်တွင် တည်ရှိနေသော `x` နှင့် `y` coordinate တို့ဖြင့် သတ်မှတ်ထားသော တည်နေရာရှိသည်။ ဂိမ်းတစ်ခု ဖန်တီးနေစဉ် သင်တွေ့ရှိမည်မှာ သင့် game objects များအားလုံးတွင် သင်ဖန်တီးသည့် ဂိမ်းတိုင်းအတွက် အခြေခံ property တစ်ခုရှိသည်။ ၎င်းတို့မှာ -
ဂိမ်းတွင် `game objects` ဆိုသည်မှာ screen ပေါ်တွင် ရှိနေသော objects ဖြစ်သည်။ ဒါဟာ Cartesian coordinate system ပေါ်မှာ `x` နှင့် `y` coordinate ရှိခြင်းဖြင့် သတ်မှတ်ထားသည်။ ဂိမ်းတိုးတက်လာသည်နှင့်အမျှ သင်၏ game objects များသည် သင်ဖန်တီးသော ဂိမ်းတိုင်းအတွက် အခြေခံ property တစ်ခုရှိသည်ကို သတိပြုမိပါမည်။ အဓိကအားဖြင့် အောက်ပါအရာများဖြစ်သည် -
- **တည်နေရာအခြေခံ** - ဂိမ်းအရာဝတ္ထုများအများစုသည် တည်နေရာအခြေခံဖြစ်သည်။ ၎င်းတို့တွင် `x` နှင့် `y` တည်နေရာရှိသည်။
- **ရွေ့လျားနိုင်သော** - ဤအရာဝတ္ထုများသည် တည်နေရာအသစ်သို့ ရွေ့လျားနိုင်သည်။ ဤအရာဝတ္ထုများသည် များသောအားဖြင့် သူရဲကောင်း၊ အလွှာသတ္တဝါ သို့မဟုတ် NPC (ကစားသမားမဟုတ်သော ဇာတ်ကောင်) ဖြစ်သည်။ သို့သော် သစ်ပင်ကဲ့သို့ static object များမဟုတ်ပါ။
- **ကိုယ်တိုင်ဖျက်ဆီးနိုင်သော** - ဤအရာဝတ္ထုများသည် သတ်မှတ်ထားသော အချိန်ကာလအတွင်းသာ ရှိနေပြီး ၎င်းတို့ကို ဖျက်သိမ်းရန် ပြင်ဆင်ထားသည်။ ယေဘူယျအားဖြင့် ဤအရာဝတ္ထုများကို `dead` သို့မဟုတ် `destroyed` boolean ဖြင့် ဖော်ပြပြီး ဂိမ်း engine သို့ ၎င်းကို render မလုပ်ရန် အချက်ပြသည်။
- **cool-down** - 'Cool-down' သည် အချိန်တိုအတွင်းသာ ရှိနေသော အရာဝတ္ထုများအတွက် အထူး property တစ်ခုဖြစ်သည်။ ဥပမာအားဖြင့် မိနစ်ပိုင်းသာ မြင်ရမည့် စာသားတစ်ခု သို့မဟုတ် ပေါက်ကွဲမှုကဲ့သို့သော ဂရပ်ဖစ်အကျိုးသက်ရောက်မှုတစ်ခု
- **တည်နေရာအခြေခံ** ဂိမ်း element များအားလုံး (သို့မဟုတ် အများစု) သည် တည်နေရာအခြေခံဖြစ်သည်။ ဒါဟာ `x` နှင့် `y` တည်နေရာရှိသည်ကို ဆိုလိုသည်။
- **ရွေ့လျားနိုင်သော** ဤ object များသည် တည်နေရာအသစ်သို့ ရွေ့လျားနိုင်သည်။ ဤသည်မှာ typically hero, monster သို့မဟုတ် NPC (non-player character) ဖြစ်သည်။ သို့သော် ဥပမာအားဖြင့် သစ်ပင်ကဲ့သို့ static object မဟုတ်ပါ။
- **ကိုယ်တိုင်ဖျက်ဆီးခြင်း** ဤ object များသည် သတ်မှတ်ထားသော အချိန်ကာလအတွင်းသာ ရှိနေပြီး ထိုအချိန်ကုန်ဆုံးသည်နှင့် ဖျက်ပစ်ရန် ပြင်ဆင်ထားသည်။ ယေဘူယျအားဖြင့် ဤသည်ကို `dead` သို့မဟုတ် `destroyed` boolean ဖြင့် ဖော်ပြပြီး ဂိမ်း engine သို့ ဤ object ကို render မလုပ်ရန် signal ပေးသည်။
- **cool-down** 'Cool-down' သည် အချိန်တိုအတွင်းသာ ရှိနေသော object များအတွက် အခြေခံ property ဖြစ်သည်။ ဥပမာအားဖြင့် milliseconds အနည်းငယ်သာ မြင်ရမည့် text သို့မဟုတ် graphical effect (ဥပမာ - ပေါက်ကွဲမှု) တစ်ခုဖြစ်သည်
✅ Pac-Man ကဲ့သို့သော ဂိမ်းတစ်ခုကို စဉ်းစားကြည့်ပါ။ ဤအရာဝတ္ထုအမျိုးအစားလေးမျိုးကို ဂိမ်းတွင် ရှာဖွေနိုင်ပါသလား?
✅ Pac-Man ကဲ့သို့သော ဂိမ်းတစ်ခုကို စဉ်းစားပါ။ ဤ object အမျိုးအစားလေးခုကို ဂိမ်းတွင် ရှာဖွေနိုင်ပါသလား?
### အပြုအမူကို ဖော်ပြခြင်း
ထက်တွင် ဖော်ပြထားသည့်အတိုင်း ဂိမ်းအရာဝတ္ထုများတွင် ရှိနိုင်သည့် အပြုအမူများကို ဖော်ပြထားပါသည်။ ဒါကို ဘယ်လို encode လုပ်မလဲ? ဤအပြုအမူများကို class များ သို့မဟုတ် object များနှင့် ဆက်စပ်ထားသော method များအဖြစ် ဖော်ပြနိုင်ပါသည်။
ပေါ်တွင် ဖော်ပြထားသောအရာများသည် game objects တွင် ရှိနိုင်သော အပြုအမူများဖြစ်သည်။ ဒါကို ဘယ်လို encode လုပ်မလဲ? ဤအပြုအမူကို class သို့မဟုတ် object များနှင့် ဆက်စပ်ထားသော method များအဖြစ် ဖော်ပြနိုင်သည်။
**Classes**
`Classes` ကို `inheritance` နှင့် တွဲဖက်ပြီး class တစ်ခုတွင် အပြုအမူတစ်ခုကို ထည့်သွင်းရန် အသုံးပြုနိုင်ပါသည်။
`classes` ကို `inheritance` နှင့် တွဲဖက်အသုံးပြု၍ class တစ်ခုတွင် အပြုအမူတစ်ခု ထည့်သွင်းရန် ရည်ရွယ်ချက်ရှိသည်။
Inheritance သည် နားလည်ရန် အရေးကြီးသော အယူအဆတစ်ခုဖြစ်သည်။ [MDN ၏ inheritance ဆောင်းပါး](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) ကို ဖတ်ရှုပါ။
အမွေဆက်ခြင်းသည် နားလည်ရန် အရေးပါသော အယူအဆတစ်ခုဖြစ်သည်။ [MDN ရဲ့ အမွေဆက်ခြင်းဆောင်းပါး](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) ကို ဖတ်ရှုပါ။
Code ဖြင့် ဖော်ပြပါက ဂိမ်းအရာဝတ္ထုသည် အောက်ပါအတိုင်း ဖြစ်နိုင်ပါသည် -
Code ဖြင့် ဖော်ပြပါက game object သည် အောက်ပါအတိုင်း ဖြစ်နိုင်သည် -
```javascript
@ -88,11 +88,11 @@ hero.moveTo(5,5);
const tree = new Tree();
```
✅ Pac-Man ၏ သူရဲကောင်း (ဥပမာ - Inky, Pinky, Blinky) ကို JavaScript ဖြင့် ဘယ်လိုရေးမလဲဆိုတာ စဉ်းစားကြည့်ပါ။
✅ Pac-Man hero (ဥပမာ - Inky, Pinky, Blinky) ကို JavaScript ဖြင့် ဘယ်လိုရေးမလဲဆိုတာ စဉ်းစားရန် အချိန်အနည်းငယ်ယူပါ။
**Composition**
Object inheritance ကို ကိုင်တွယ်ရန် နည်းလမ်းကွဲတစ်ခုမှာ *Composition* ကို အသုံးပြုခြင်းဖြစ်သည်။ ထို့နောက် object များသည် ၎င်းတို့၏ အပြုအမူကို အောက်ပါအတိုင်း ဖော်ပြပါသည် -
Object inheritance ကို ကိုင်တွယ်ရန် နည်းလမ်းကွဲတစ်ခုမှာ *Composition* ကို အသုံးပြုခြင်းဖြစ်သည်။ ထို့နောက် object များသည် အပြုအမူကို အောက်ပါအတိုင်း ဖော်ပြသည် -
```javascript
//create a constant gameObject
@ -137,25 +137,25 @@ hero.moveTo(5,5);
const tree = createStatic(0,0, 'Tree');
```
**ဘယ် pattern ကို သုံးလဲ?**
**ဘယ် pattern ကို သုံးသင့်သလဲ?**
ဘယ် pattern ကို သုံးမည်ဆိုတာ သင့်အပေါ်မူတည်ပါသည်။ JavaScript သည် ဤ paradigm နှစ်ခုစလုံးကို ပံ့ပိုးပေးပါသည်။
ဘယ် pattern ကို သုံးမည်ဆိုတာ သင့်ရဲ့ ရွေးချယ်မှုအပေါ် မူတည်သည်။ JavaScript သည် ဤ paradigm နှစ်ခုစလုံးကို ပံ့ပိုးပေးသည်။
--
ဂိမ်းဖွံ့ဖြိုးရေးတွင် ကျယ်ကျယ်ပြန့်ပြန့် အသုံးပြုသော pattern တစ်ခုမှာ ဂိမ်း၏ အသုံးပြုသူအတွေ့အကြုံနှင့် စွမ်းဆောင်ရည်ကို ကိုင်တွယ်ရန်ဖြစ်သည်။
ဂိမ်းတိုးတက်မှုတွင် အသုံးများသော pattern တစ်ခုသည် ဂိမ်း၏ user experience နှင့် performance ကို ကိုင်တွယ်ရန် ပြဿနာကို ဖြေရှင်းပေးသည်။
## Pub/sub pattern
✅ Pub/Sub ဆိုသည်မှာ 'publish-subscribe' ကို ရည်ညွှန်းပါသည်။
✅ Pub/Sub သည် 'publish-subscribe' ကို ဆိုလိုသည်။
ဤ pattern သည် သင့် application ၏ အစိတ်အပိုင်းများသည် တစ်ခုနှင့်တစ်ခု မသိစေခြင်း၏ အယူအဆကို ကိုင်တွယ်ပါသည်။ အဘယ်ကြောင့်လဲဆိုတော့ အစိတ်အပိုင်းများကို ခွဲခြားထားခြင်းဖြင့် အခြေအနေကို ပိုမိုလွယ်ကူစွာ နားလည်နိုင်စေပါသည်။ ထို့အပြင် လိုအပ်ပါက အပြုအမူကို ရုတ်တရက် ပြောင်းလဲနိုင်စေပါသည်။ ဤအရာကို ဘယ်လိုလုပ်ဆောင်မလဲ? ၎င်းကို အောက်ပါအယူအဆများကို တည်ဆောက်ခြင်းဖြင့် ပြုလုပ်ပါသည် -
ဤ pattern သည် application ၏ အစိတ်အပိုင်းများသည် တစ်ခုနှင့်တစ်ခု မသိအောင်ထားသင့်သည်ဆိုသော အယူအဆကို ကိုင်တွယ်သည်။ အဘယ်ကြောင့်လဲ? အစိတ်အပိုင်းများကို ခွဲခြားထားပါက အထွေထွေမှာ ဘာဖြစ်နေလဲဆိုတာ ပိုမိုလွယ်ကူစွာ မြင်နိုင်သည်။ ထို့အပြင် သင်လိုအပ်ပါက အပြုအမူကို ရုတ်တရက် ပြောင်းလဲရန်လည်း ပိုမိုလွယ်ကူစေသည်။ ဤအရာကို ဘယ်လိုအောင်မြင်စေမလဲ? ဤအရာကို အောက်ပါအယူအဆများကို တည်ဆောက်ခြင်းဖြင့် ပြုလုပ်သည် -
- **message**: message သည် ယေဘူယျအားဖြင့် စာသား string တစ်ခုဖြစ်ပြီး အချို့သော payload (message ၏ အဓိပ္ပါယ်ကို ရှင်းလင်းပေးသော data တစ်ခု) ပါဝင်နိုင်ပါသည်။ ဂိမ်းတစ်ခုတွင် message တစ်ခုမှာ `KEY_PRESSED_ENTER` ဖြစ်နိုင်ပါသည်။
- **publisher**: ဤ element သည် message တစ်ခုကို *publish* လုပ်ပြီး subscriber များအားလုံးသို့ ပေးပို့ပါသည်။
- **subscriber**: ဤ element သည် သတ်မှတ်ထားသော message များကို *listen* လုပ်ပြီး message ရရှိသည်နှင့်တပြိုင်နက် တစ်စုံတစ်ရာလုပ်ဆောင်ပါသည်။ ဥပမာအားဖြင့် လေဆာပစ်ခြင်း
- **message**: message သည် text string တစ်ခုဖြစ်ပြီး optional payload (message အကြောင်းကို ရှင်းလင်းပေးသော data အပိုင်း) တစ်ခုနှင့် တွဲဖက်ထားသည်။ ဂိမ်းတွင် သာမန် message တစ်ခုမှာ `KEY_PRESSED_ENTER` ဖြစ်နိုင်သည်။
- **publisher**: ဤ element သည် message တစ်ခုကို *publish* လုပ်ပြီး subscriber အားလုံးထံ ပေးပို့သည်။
- **subscriber**: ဤ element သည် သတ်မှတ်ထားသော message များကို *listen* လုပ်ပြီး message ကို ရရှိသောအခါ laser ပစ်ခြင်းကဲ့သို့သော task တစ်ခုကို ဆောင်ရွက်သည်
ဤ pattern ၏ အကောင်အထည်ဖော်မှုသည် အရွယ်အစားသေးငယ်သော်လည်း အလွန်အစွမ်းထက်ပါသည်။ ၎င်းကို အောက်ပါအတိုင်း အကောင်အထည်ဖော်နိုင်ပါသည် -
Implementation သည် အရွယ်အစားသေးငယ်သော်လည်း အလွန်အစွမ်းထက်သော pattern ဖြစ်သည်။ ဤအရာကို အောက်ပါအတိုင်း implement လုပ်နိုင်သည် -
```javascript
//set up an EventEmitter class that contains listeners
@ -180,7 +180,7 @@ class EventEmitter {
```
အထက်ပါ code ကို အသုံးပြုရန်အတွက် အလွန်သေးငယ်သော အကောင်အထည်ဖော်မှုတစ်ခုကို ဖန်တီးနိုင်ပါသည် -
အထက်ပါ code ကို အသုံးပြုရန် အလွန်သေးငယ်သော implementation တစ်ခုကို ဖန်တီးနိုင်သည် -
```javascript
//set up a message structure
@ -204,7 +204,7 @@ window.addEventListener('keyup', (evt) => {
});
```
အထက်တွင် keyboard event `ArrowLeft` ကို ချိတ်ဆက်ပြီး `HERO_MOVE_LEFT` message ကို ပေးပို့ပါသည်။ ဤ message ကို နားထောင်ပြီး `hero` ကို ရွေ့လျားစေပါသည်။ ဤ pattern ၏ အားသာချက်မှာ event listener နှင့် hero တို့သည် တစ်ခုနှင့်တစ်ခု မသိစေခြင်းဖြစ်သည်။ `ArrowLeft` ကို `A` key သို့ ပြောင်းလဲနိုင်ပါသည်။ ထို့အပြင် `ArrowLeft` တွင် အခြားအရာတစ်ခုကို ပြုလုပ်စေလိုပါက eventEmitter ၏ `on` function တွင် အနည်းငယ် ပြင်ဆင်ခြင်းဖြင့် ပြုလုပ်နိုင်ပါသည် -
အထက်တွင် keyboard event `ArrowLeft` ကို ချိတ်ဆက်ပြီး `HERO_MOVE_LEFT` message ကို ပေးပို့သည်။ ဤ message ကို listen လုပ်ပြီး hero ကို ရလဒ်အနေနှင့် ရွေ့လျားသည်။ ဤ pattern ၏ အားသာချက်မှာ event listener နှင့် hero တစ်ခုနှင့်တစ်ခု မသိအောင်ထားသည်။ `ArrowLeft` ကို `A` key သို့ remap ပြုလုပ်နိုင်သည်။ ထို့အပြင် `ArrowLeft` တွင် အခြားအရာတစ်ခုကို ပြုလုပ်ရန်လည်း eventEmitter ရဲ့ `on` function ကို အနည်းငယ် edit လုပ်ခြင်းဖြင့် အလွယ်တကူ ပြုလုပ်နိုင်သည် -
```javascript
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
@ -212,17 +212,17 @@ eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
});
```
သင့်ဂိမ်းကြီးလာသည်နှင့်အမျှ အရာများ ပိုမိုရှုပ်ထွေးလာသော်လည်း ဤ pattern သည် အလွန်ရိုးရှင်းနေပြီး သင့် code သန့်ရှင်းစွာ ရှိနေပါသည်။ ဤ pattern ကို အသုံးပြုရန် အလွန်အကြံပြုပါသည်။
သင့်ဂိမ်းကြီးလာသည်နှင့်အမျှ အရာများ ပိုမိုရှုပ်ထွေးလာသော်လည်း ဤ pattern သည် ရှုပ်ထွေးမှုအတူတူရှိနေပြီး သင့် code သည် သန့်ရှင်းနေသည်။ ဤ pattern ကို လက်ခံအသုံးပြုရန် အလွန်အကြံပြုပါသည်။
---
## 🚀 စိန်ခေါ်မှု
Pub-sub pattern သည် ဂိမ်းတစ်ခုကို ဘယ်လိုတိုးတက်စေမည်ကို စဉ်းစားကြည့်ပါ။ ဘယ်အစိတ်အပိုင်းများက event များကို ထုတ်လွှင့်သင့်ပြီး ဂိမ်းသည် ၎င်းတို့ကို ဘယ်လိုတုံ့ပြန်သင့်သလဲ? ဂိမ်းအသစ်တစ်ခုကို စဉ်းစားပြီး ၎င်း၏ အစိတ်အပိုင်းများ ဘယ်လိုအပြုအမူရှိမည်ကို ဖန်တီးစဉ်းစားပါ
Pub-sub pattern သည် ဂိမ်းတစ်ခုကို ဘယ်လိုတိုးတက်စေမည်ကို စဉ်းစားပါ။ ဘယ်အစိတ်အပိုင်းများသည် events ကို emit လုပ်သင့်ပြီး ဂိမ်းသည် အဲဒီ events များကို ဘယ်လိုတုံ့ပြန်သင့်သလဲ? ဂိမ်းအသစ်တစ်ခုကို စဉ်းစားပြီး အဲဒီအစိတ်အပိုင်းများသည် ဘယ်လိုအပြုအမူရှိမည်ကို ဖန်တီးရန် အခွင့်အရေးရှိပါသည်
## မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း
## မိန့်ခွန်းပြီးနောက် စစ်တမ်း
[မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/30)
[မိန့်ခွန်းပြီးနောက် စစ်တမ်း](https://ff-quizzes.netlify.app/web/quiz/30)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
@ -235,4 +235,4 @@ Pub/Sub အကြောင်းကို [ဖတ်ရှုခြင်း](ht
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှု ဝန်ဆောင်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,50 +1,50 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "41be8d35e7f30aa9dad10773c35e89c4",
"translation_date": "2025-08-27T22:24:34+00:00",
"original_hash": "056641280211e52fd0adb81b6058ec55",
"translation_date": "2025-08-28T18:39:45+00:00",
"source_file": "6-space-game/2-drawing-to-canvas/README.md",
"language_code": "my"
}
-->
# အာကာသဂိမ်းတည်ဆောက်ခြင်း အပိုင်း ၂: ဟီးရိုနှင့် မုဆိုးများကို Canvas တွင် ရေးဆွဲခြင်း
# အာကာသဂိမ်းတစ်ခုတည်ဆောက်ခြင်း အပိုင်း ၂: ဟီးရိုနှင့် မုဆိုးများကို Canvas ပေါ်တွင် ရေးဆွဲခြင်း
## မိန့်ခွန်းမတိုင်မီ မေးခွန်း
## မိန့်ခွန်းမတိုင်မီ စစ်တမ်း
[မိန့်ခွန်းမတိုင်မီ ေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/31)
[မိန့်ခွန်းမတိုင်မီ စစ်တမ်း](https://ff-quizzes.netlify.app/web/quiz/31)
## Canvas
Canvas သည် HTML element တစ်ခုဖြစ်ပြီး မူရင်းအားဖြင့် အကြောင်းအရာမပါရှိပါ။ ၎င်းသည် အလွတ်ဖြစ်ပြီး သင်ရေးဆွဲရန်လိုအပ်သည်။
Canvas သည် HTML element တစ်ခုဖြစ်ပြီး ပုံမှန်အားဖြင့် အကြောင်းအရာမပါရှိပါဘူး။ ဒါဟာ အလွတ်ဖြစ်ပြီး သင်ရေးဆွဲရမယ်။
✅ [Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) ကို MDN တွင် ဖတ်ရှုပါ။
✅ [Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) ကို MDN မှာ ပိုမိုလေ့လာပါ။
ဤသည်ကို မူလအားဖြင့် စာမျက်နှာ၏ body အစိတ်အပိုင်းအဖြစ် ကြေညာထားသည်။
ဒါကို ပုံမှန်အားဖြင့် စာမျက်နှာရဲ့ body အပိုင်းမှာ ဒီလို သတ်မှတ်ပါတယ်။
```html
<canvas id="myCanvas" width="200" height="100"></canvas>
```
အထက်တွင် `id`, `width` နှင့် `height` ကို သတ်မှတ်ထားသည်။
အထက်မှာ `id`, `width` နဲ့ `height` ကို သတ်မှတ်ထားပါတယ်။
- `id`: ၎င်းကို သတ်မှတ်ထားသည့်အခါ interaction လုပ်ရန် reference ရယူနိုင်ရန်
- `width`: element ၏ အကျယ်
- `height`: element ၏ အမြင့်
- `id`: သင်ရဲ့ interaction အတွက် reference ရယူနိုင်ဖို့ သတ်မှတ်ပါ
- `width`: element ရဲ့ အကျယ်ကို သတ်မှတ်ပါ
- `height`: element ရဲ့ အမြင့်ကို သတ်မှတ်ပါ
## ရိုးရှင်းသော ဂျီဩမေတြီရေးဆွဲခြင်း
## ရိုးရှင်းတဲ့ ဂျီဩမေတြီပုံစံများ ရေးဆွဲခြင်း
Canvas သည် cartesian coordinate system ကို အသုံးပြု၍ အရာများကို ရေးဆွဲသည်။ ထို့ကြောင့် x-axis နှင့် y-axis ကို အသုံးပြု၍ တည်နေရာကို ဖော်ပြသည်။ `0,0` တည်နေရာသည် အပေါ်ဘက် ဘယ်ဖက်ဖြစ်ပြီး အောက်ဘက် ညာဖက်သည် သင်သတ်မှတ်ထားသော Canvas ၏ WIDTH နှင့် HEIGHT ဖြစ်သည်။
Canvas သည် Cartesian coordinate system ကို အသုံးပြုပြီး ပုံများကို ရေးဆွဲပါတယ်။ ဒါကြောင့် x-axis နဲ့ y-axis ကို အသုံးပြုပြီး တစ်ခုခုရဲ့ တည်နေရာကို ဖော်ပြပါတယ်။ `0,0` တည်နေရာသည် အပေါ်ဘက် ဘယ်ဖက်နေရာဖြစ်ပြီး အောက်ဘက်ညာဖက်သည် သင်သတ်မှတ်ထားသော Canvas ရဲ့ WIDTH နဲ့ HEIGHT ဖြစ်ပါတယ်။
![Canvas grid](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.my.png)
> [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) မှရရှိသော ပုံ
![Canvas ရဲ့ grid](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.my.png)
> ပုံကို [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) မှာ ရယူထားပါတယ်။
Canvas element တွင် ရေးဆွဲရန် အောက်ပါအဆင့်များကို လိုက်နာရမည်။
Canvas element ပေါ်မှာ ရေးဆွဲဖို့ အောက်ပါအဆင့်များကို လိုအပ်ပါတယ်-
1. **Reference ရယူပါ** Canvas element ကို ရယူပါ
2. **Reference ရယူပါ** Canvas element အတွင်းရှိ Context element ကို ရယူပါ
3. **ရေးဆွဲမှုလုပ်ဆောင်ပါ** Context element ကို အသုံးပြုပါ
1. **Reference ရယူပါ** Canvas element အတွက်
2. **Reference ရယူပါ** Canvas element ပေါ်မှာရှိတဲ့ Context element အတွက်
3. **Drawing operation လုပ်ဆောင်ပါ** Context element ကို အသုံးပြုပြီး
အထက်ပါအဆင့်များအတွက် ကုဒ်သည် အောက်ပါအတိုင်းဖြစ်သည်။
အထက်ပါအဆင့်များအတွက် Code သည် ပုံမှန်အားဖြင့် ဒီလိုပုံစံရှိပါတယ်-
```javascript
// draws a red rectangle
@ -61,19 +61,19 @@ ctx.fillStyle = 'red';
ctx.fillRect(0,0, 200, 200) // x,y,width, height
```
✅ Canvas API သည် အဓိကအားဖြင့် 2D shapes ကို အခြေခံထားပြီး 3D element များကိုလည်း ရေးဆွဲနိုင်သည်။ ၎င်းအတွက် [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) ကို အသုံးပြုနိုင်သည်။
✅ Canvas API သည် အဓိကအားဖြင့် 2D ပုံစံများကို အာရုံစိုက်ထားပြီး သင် 3D element များကိုလည်း ဝဘ်ဆိုဒ်ပေါ်မှာ ရေးဆွဲနိုင်ပါတယ်။ ဒီအတွက် [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) ကို အသုံးပြုနိုင်ပါတယ်။
Canvas API ဖြင့် ရေးဆွဲနိုင်သော အရာများမှာ -
Canvas API ကို အသုံးပြုပြီး အမျိုးမျိုးသောအရာများကို ရေးဆွဲနိုင်ပါတယ်-
- **ဂျီဩမေတြီပုံသဏ္ဍာန်များ** - Rectangle ရေးဆွဲပုံကို ပြထားပြီး အခြားပုံသဏ္ဍာန်များကိုလည်း ရေးဆွဲနိုင်သည်။
- **စာသား** - မည်သည့် font နှင့် အရောင်ဖြင့်မဆို စာသားကို ရေးဆွဲနိုင်သည်။
- **ပုံများ** - .jpg သို့မဟုတ် .png ကဲ့သို့သော ပုံ asset ကို အသုံးပြု၍ ပုံကို ရေးဆွဲနိုင်သည်။
- **ဂျီဩမေတြီပုံစံများ**၊ rectangle ရေးဆွဲပုံကို ပြထားပြီး အခြားသောအရာများကိုလည်း ရေးဆွဲနိုင်ပါတယ်။
- **စာသား**၊ သင်လိုချင်တဲ့ font နဲ့ အရောင်ကို အသုံးပြုပြီး စာသားကို ရေးဆွဲနိုင်ပါတယ်။
- **ပုံများ** .jpg သို့မဟုတ် .png ကဲ့သို့သော ပုံ asset ကို အသုံးပြုပြီး ပုံကို ရေးဆွဲနိုင်ပါတယ်။
✅ စမ်းကြည့်ပါ! Rectangle ရေးဆွဲပုံကို သိပြီး Circle ကို စမ်းရေးဆွဲနိုင်ပါသလား။ CodePen တွင် Canvas ရေးဆွဲမှုများကို စိတ်ဝင်စားစွာ ကြည့်ပါ။ [အလွန်အံ့ဩဖွယ်ကောင်းသော ဥပမာ](https://codepen.io/dissimulate/pen/KrAwx) တစ်ခုကို ကြည့်ပါ။
✅ စမ်းကြည့်ပါ! Rectangle ရေးဆွဲပုံကို သိပြီးသားဖြစ်လို့ Circle ကို စာမျက်နှာပေါ်မှာ ရေးဆွဲနိုင်ပါသလား? CodePen မှ Canvas ရေးဆွဲမှုများကို စိတ်ဝင်စားဖို့ ကြည့်ပါ။ [အလွန်အံ့ဩဖွယ်ကောင်းတဲ့ ဥပမာ](https://codepen.io/dissimulate/pen/KrAwx) တစ်ခုကို ဒီမှာ ကြည့်နိုင်ပါတယ်
## ပုံ asset တစ်ခုကို Load လုပ်ပြီး ရေးဆွဲခြင်း
ပုံ asset ကို `Image` object တစ်ခုဖန်တီးပြီး ၎င်း၏ `src` property ကို သတ်မှတ်ခြင်းဖြင့် Load လုပ်သည်။ ထို့နောက် `load` event ကို နားထောင်ပြီး အသုံးပြုရန် အဆင်သင့်ဖြစ်သောအခါ သိရှိနိုင်သည်။ ကုဒ်သည် အောက်ပါအတိုင်းဖြစ်သည်။
ပုံ asset ကို Load လုပ်ဖို့ `Image` object တစ်ခုကို ဖန်တီးပြီး `src` property ကို သတ်မှတ်ရပါမယ်။ ပြီးရင် `load` event ကို နားထောင်ပြီး အသုံးပြုနိုင်ဖို့ အဆင်သင့်ဖြစ်တဲ့အခါ သိရပါမယ်။ Code သည် ဒီလိုပုံစံရှိပါတယ်-
### Asset Load လုပ်ခြင်း
@ -87,7 +87,7 @@ img.onload = () => {
### Asset Load လုပ်ပုံစံ
အထက်ပါကို အောက်ပါပုံစံအတိုင်း wrap လုပ်ရန် အကြံပြုသည်။ ၎င်းသည် အသုံးပြုရန် လွယ်ကူပြီး အဆင်သင့်ဖြစ်သောအခါမှသာ Manipulate လုပ်ရန် ဖြစ်သည်။
အထက်ပါကို ဒီလိုပုံစံတစ်ခုအတွင်းမှာ ထည့်သွင်းဖို့ အကြံပြုပါတယ်၊ ဒါကြောင့် အသုံးပြုရလွယ်ကူပြီး အဆင်သင့်ဖြစ်တဲ့အခါမှ Manipulate လုပ်နိုင်ပါတယ်-
```javascript
function loadAsset(path) {
@ -110,7 +110,7 @@ async function run() {
```
Game asset များကို Screen တွင် ရေးဆွဲရန် သင့်ကုဒ်သည် အောက်ပါအတိုင်းဖြစ်သည်။
Game asset များကို Screen ပေါ်မှာ ရေးဆွဲဖို့ သင့်ရဲ့ Code သည် ဒီလိုပုံစံရှိပါတယ်-
```javascript
async function run() {
@ -124,23 +124,23 @@ async function run() {
}
```
## အခုတော့ သင့်ဂိမ်းကို တည်ဆောက်ရန် အချိန်ရောက်ပြီ
## အခု သင့်ဂိမ်းကို တည်ဆောက်ဖို့ အချိန်ရောက်ပါပြီ
### ဘာကို တည်ဆောက်မလဲ
Canvas element ပါရှိသော Web page တစ်ခုကို တည်ဆောက်ပါ။ ၎င်းသည် `1024*768` အနက်ရောင် Screen ကို Render လုပ်သင့်သည်။ သင့်အား ပေးထားသော ပုံနှစ်ခုမှာ -
Canvas element ပါတဲ့ ဝဘ်စာမျက်နှာတစ်ခုကို တည်ဆောက်ပါ။ ဒါဟာ `1024*768` အနက်ရောင် Screen ကို Render လုပ်သင့်ပါတယ်။ သင့်ကို ပုံနှစ်ခုပေးထားပါတယ်-
- ဟီးရိုသင်္ဘော
- ဟီးရို ရေယာဉ်
![ဟီးရိုသင်္ဘော](../../../../translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.my.png)
![ဟီးရို ရေယာဉ်](../../../../translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.my.png)
- 5*5 မုဆိုး
![မုဆိုးသင်္ဘော](../../../../translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.my.png)
![မုဆိုး ရေယာဉ်](../../../../translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.my.png)
### တည်ဆောက်မှုကို စတင်ရန် အကြံပြုသော အဆင့်များ
### တည်ဆောက်မှုကို စတင်ဖို့ အကြံပြုထားသော အဆင့်များ
`your-work` sub folder တွင် ဖန်တီးထားသော ဖိုင်များကို ရှာပါ။ ၎င်းတွင် အောက်ပါအရာများ ပါဝင်သင့်သည် -
`your-work` sub folder တွင် ဖန်တီးထားသော ဖိုင်များကို ရှာပါ။ ဒါဟာ အောက်ပါအတိုင်း ပါဝင်သင့်ပါတယ်-
```bash
-| assets
@ -151,33 +151,33 @@ Canvas element ပါရှိသော Web page တစ်ခုကို တည
-| package.json
```
ဤ folder ၏ copy ကို Visual Studio Code တွင် ဖွင့်ပါ။ သင့်တွင် Visual Studio Code, NPM နှင့် Node တပ်ဆင်ထားသော Local Development Environment ရှိသင့်သည်။ သင့်ကွန်ပျူတာတွင် `npm` မရှိပါက [ဤနေရာတွင်](https://www.npmjs.com/get-npm) တပ်ဆင်ရန် လမ်းညွှန်ချက်ကို ကြည့်ပါ။
ဒီ folder ကို Visual Studio Code မှာ ဖွင့်ပါ။ သင့်မှာ Visual Studio Code, NPM နဲ့ Node တို့ပါဝင်တဲ့ Local Development Environment တစ်ခုရှိဖို့ လိုအပ်ပါတယ်။ သင့်ကွန်ပျူတာမှာ `npm` မရှိသေးရင် [ဒီမှာ](https://www.npmjs.com/get-npm) သင့်ရဲ့ setup ကို ပြုလုပ်ပါ။
သင့် Project ကို `your_work` folder တွင် စတင်ပါ -
သင့် project ကို `your_work` folder မှာ စတင်ပါ-
```bash
cd your-work
npm start
```
အထက်ပါသည် `http://localhost:5000` တွင် HTTP Server တစ်ခုကို စတင်မည်။ Browser တစ်ခုဖွင့်ပြီး အဆိုပါလိပ်စာကို ထည့်ပါ။ ယခုအချိန်တွင် Blank Page ဖြစ်နေသော်လည်း အနည်းငယ်ကြာပြီး ပြောင်းလဲလာမည်။
အထက်ပါသည် `http://localhost:5000` လိပ်စာမှာ HTTP Server တစ်ခုကို စတင်ပါမယ်။ Browser ကို ဖွင့်ပြီး အဲ့ဒီလိပ်စာကို ထည့်ပါ။ အခုတော့ Blank Page ဖြစ်နေပါတယ်၊ ဒါပေမယ့် အဲ့ဒါ ပြောင်းလဲလာပါမယ်။
> မှတ်ချက် - Screen ပေါ်တွင် ပြောင်းလဲမှုများကို ကြည့်ရန် Browser ကို Refresh လုပ်ပါ။
> မှတ်ချက်- Screen ပေါ်မှာ ပြောင်းလဲမှုများကို ကြည့်ဖို့ Browser ကို Refresh လုပ်ပါ။
### ကုဒ်ထည့်ပါ
### Code ထည့်ပါ
`your-work/app.js` တွင် အောက်ပါအရာများကို ဖြေရှင်းရန် လိုအပ်သော ကုဒ်ကို ထည့်ပါ။
`your-work/app.js` မှာ လိုအပ်သော Code ကို ထည့်ပြီး အောက်ပါအရာများကို ဖြေရှင်းပါ-
1. **Canvas** ကို အနက်ရောင်နောက်ခံဖြင့် ရေးဆွဲပါ
> အကြံပြုချက် - `/app.js` တွင် သင့် `ctx` element ကို အနက်ရောင်သတ်မှတ်ပြီး Top/Left coordinates ကို 0,0 သတ်မှတ်ပါ။ Canvas ၏ အမြင့်နှင့် အကျယ်ကို သတ်မှတ်ပါ။
1. **Canvas** ကို အနက်ရောင်နောက်ခံနဲ့ ရေးဆွဲပါ
> အကြံပြုချက်- `/app.js` မှာ သင့်တော်တဲ့ TODO အောက်မှာ `ctx` element ကို အနက်ရောင် သတ်မှတ်ပြီး Top/Left Coordinates ကို 0,0 နဲ့ Canvas ရဲ့ Height နဲ့ Width ကို သတ်မှတ်ပါ။
2. **Textures** ကို Load လုပ်ပါ
> အကြံပြုချက် - Player နှင့် Enemy ပုံများကို `await loadTexture` ဖြင့် Load လုပ်ပါ။ ပုံများကို Screen ပေါ်တွင် မမြင်ရသေးပါ။
3. **ဟီးရို** ကို Screen ၏ အောက်ခြေ အလယ်တွင် ရေးဆွဲပါ
> အကြံပြုချက် - `drawImage` API ကို အသုံးပြု`heroImg` ကို Screen ပေါ်တွင် ရေးဆွဲပါ။ `canvas.width / 2 - 45` နှင့် `canvas.height - canvas.height / 4)` ကို သတ်မှတ်ပါ။
> အကြံပြုချက်- Player နဲ့ Enemy ပုံများကို `await loadTexture` ကို အသုံးပြုပြီး ပုံလမ်းကြောင်းကို Passing လုပ်ပါ။ အခုတော့ Screen ပေါ်မှာ မမြင်ရသေးပါဘူး!
3. **ဟီးရို** ကို Screen ရဲ့ အောက်ခြေတစ်ဝက်မှာ အလယ်မှာ ရေးဆွဲပါ
> အကြံပြုချက်- `drawImage` API ကို အသုံးပြုပြီး heroImg ကို Screen ပေါ်မှာ ရေးဆွဲပါ၊ `canvas.width / 2 - 45` နဲ့ `canvas.height - canvas.height / 4)` ကို သတ်မှတ်ပါ။
4. **5*5 မုဆိုးများ** ကို ရေးဆွဲပါ
> အကြံပြုချက် - Enemy များကို Screen ပေါ်တွင် ရေးဆွဲရန် Code ကို Uncomment လုပ်ပါ။ ထို့နောက် `createEnemies` function သို့သွားပြီး ၎င်းကို တည်ဆောက်ပါ။
> အကြံပြုချက်- အခုတော့ မုဆိုးများကို Screen ပေါ်မှာ ရေးဆွဲဖို့ Code ကို Uncomment လုပ်နိုင်ပါပြီ။ နောက်တစ်ဆင့်မှာ `createEnemies` function ကို သွားပြီး အဲ့ဒါကို တည်ဆောက်ပါ။
အရင်ဆုံး Constants များကို သတ်မှတ်ပါ -
အရင်ဆုံး Constants များကို သတ်မှတ်ပါ-
```javascript
const MONSTER_TOTAL = 5;
@ -186,7 +186,7 @@ npm start
const STOP_X = START_X + MONSTER_WIDTH;
```
ထို့နောက် မုဆိုး array ကို Screen ပေါ်တွင် ရေးဆွဲရန် Loop တစ်ခုကို ဖန်တီးပါ -
ပြီးရင် မုဆိုးများ array ကို Screen ပေါ်မှာ ရေးဆွဲဖို့ Loop တစ်ခုကို ဖန်တီးပါ-
```javascript
for (let x = START_X; x < STOP_X; x += 98) {
@ -198,33 +198,33 @@ npm start
## ရလဒ်
ပြီးစီးသော ရလဒ်သည် အောက်ပါအတိုင်းဖြစ်သင့်သည် -
ပြီးဆုံးသော ရလဒ်သည် ဒီလိုပုံစံရှိသင့်ပါတယ်-
![အနက်ရောင် Screen, ဟီးရိုနှင့် 5*5 မုဆိုးများ](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.my.png)
![အနက်ရောင် Screen ဟီးရိုနဲ့ 5*5 မုဆိုးများ](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.my.png)
## ဖြေရှင်းချက်
အရင်ဆုံး သင်ကိုယ်တိုင် ဖြေရှင်းရန် ကြိုးစားပါ။ သို့သော် အကူအညီလိုအပ်ပါက [ဖြေရှင်းချက်](../../../../6-space-game/2-drawing-to-canvas/solution/app.js) ကို ကြည့်ပါ။
အရင်ဆုံး သင်ကိုယ်တိုင် ဖြေရှင်းဖို့ ကြိုးစားပါ၊ ဒါပေမယ့် အကူအညီလိုအပ်ရင် [ဖြေရှင်းချက်](../../../../6-space-game/2-drawing-to-canvas/solution/app.js) ကို ကြည့်ပါ။
---
## 🚀 စိန်ခေါ်မှု
သင်သည် 2D Canvas API ဖြင့် ရေးဆွဲခြင်းကို သင်ယူပြီးပါပြီ။ [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) ကို ကြည့်ပြီး 3D object တစ်ခုကို ရေးဆွဲကြည့်ပါ။
သင် Canvas API ကို အသုံးပြုပြီး 2D ပုံစံများကို ရေးဆွဲဖို့ သင်ယူပြီးသားဖြစ်ပါတယ်။ [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) ကို ကြည့်ပြီး 3D object တစ်ခုကို ရေးဆွဲကြည့်ပါ။
## မိန့်ခွန်းပြီးနောက် မေးခွန်း
## မိန့်ခွန်းပြီးနောက် စစ်တမ်း
[မိန့်ခွန်းပြီးနောက် ေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/32)
[မိန့်ခွန်းပြီးနောက် စစ်တမ်း](https://ff-quizzes.netlify.app/web/quiz/32)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
Canvas API အကြောင်း [ဖတ်ရှုခြင်း](https://developer.mozilla.org/docs/Web/API/Canvas_API) ဖြင့် ပိုမိုလေ့လာပါ
Canvas API အကြောင်းပိုမိုလေ့လာဖို့ [ဒီမှာဖတ်ပါ](https://developer.mozilla.org/docs/Web/API/Canvas_API)။
## လုပ်ငန်းတာဝန်
## အလုပ်ပေးစာ
[Canvas API ဖြင့် စမ်းသပ်ပါ](assignment.md)
[Canvas API ကို စမ်းသပ်ပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရားရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှု ဝန်ဆောင်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,32 +1,32 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "23f088add24f0f1fa51014a9e27ea280",
"translation_date": "2025-08-27T22:19:58+00:00",
"original_hash": "a9a161871de7706cb0e23b1bd0c74559",
"translation_date": "2025-08-28T18:37:46+00:00",
"source_file": "6-space-game/3-moving-elements-around/README.md",
"language_code": "my"
}
-->
# အာကာသဂိမ်း တည်ဆောက်ခြင်း အပိုင်း ၃: လှုပ်ရှားမှု ထည့်သွင်းခြင်း
## မိန့်ခွန်းမတိုင်မီ မေးခွန်း
## မိန့်ခွန်းမတိုင်မီ စစ်ဆေးမှု
[မိန့်ခွန်းမတိုင်မီ မေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/33)
[မိန့်ခွန်းမတိုင်မီ စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/33)
ဂိမ်းတွေဟာ အာလီယန်တွေ မျက်နှာပြင်ပေါ်မှာ လှုပ်ရှားနေမှ ပိုမိုပျော်ရွှင်စရာဖြစ်ပါတယ်! ဒီဂိမ်းမှာတော့ လှုပ်ရှားမှုအမျိုးအစားနှစ်မျိုးကို အသုံးပြုပါမယ်။
ဂိမ်းတွေဟာ အကောင်တွေ မျက်နှာပြင်ပေါ်မှာ လှုပ်ရှားနေမှ ပိုမိုစိတ်ဝင်စားဖွယ် ဖြစ်လာပါတယ်။ ဒီဂိမ်းမှာတော့ လှုပ်ရှားမှုနှစ်မျိုးကို အသုံးပြုသွားမှာဖြစ်ပါတယ်-
- **ကီးဘုတ်/မောက်စ် လှုပ်ရှားမှု**: အသုံးပြုသူက ကီးဘုတ် သို့မဟုတ် မောက်စ်ကို အသုံးပြုပြီး မျက်နှာပြင်ပေါ်မှာ အရာဝတ္ထုကို ရွှေ့လို့ရတဲ့အခါ
- **ဂိမ်းကနေ ဖြစ်ပေါ်လာတဲ့ လှုပ်ရှားမှု**: ဂိမ်းက အချိန်အကွာအဝေးတစ်ခုအတွင်းမှာ အရာဝတ္ထုကို ရွှေ့လှုပ်ပေးတဲ့အခါ
- **ကီးဘုတ်/မောက်စ် လှုပ်ရှားမှု**: အသုံးပြုသူက ကီးဘုတ် သို့မဟုတ် မောက်စ်ကို အသုံးပြုပြီး မျက်နှာပြင်ပေါ်မှာ အရာဝတ္ထုတစ်ခုကို လှုပ်ရှားစေခြင်း
- **ဂိမ်းမှ ဖြစ်ပေါ်သော လှုပ်ရှားမှု**: ဂိမ်းက အချိန်အကွာအဝေးတစ်ခုအတွင်း အရာဝတ္ထုတစ်ခုကို လှုပ်ရှားစေခြင်း
မျက်နှာပြင်ပေါ်မှာ အရာဝတ္ထုတွေကို ဘယ်လို ရွှေ့လှုပ်မလဲ? ဒါဟာ ကာတီရှီယန် ကိုဩဒိနိတ် (cartesian coordinates) ပေါ်မှာ အခြေခံထားပါတယ်။ အရာဝတ္ထုရဲ့ တည်နေရာ (x, y) ကို ပြောင်းပြီး မျက်နှာပြင်ကို ပြန်လည်ရေးဆွဲရပါတယ်
ဒါဆိုရင် မျက်နှာပြင်ပေါ်မှာ အရာဝတ္ထုတွေကို ဘယ်လို လှုပ်ရှားစေမလဲ? ဒါဟာ ကာတီရှန် ကိုဩဒိနိတ် (cartesian coordinates) ပေါ်မှာ အခြေခံထားတာပါ။ အရာဝတ္ထုရဲ့ တည်နေရာ (x, y) ကို ပြောင်းပြီး မျက်နှာပြင်ကို ပြန်ဆွဲရုံပါပဲ
မျက်နှာပြင်ပေါ်မှာ *လှုပ်ရှားမှု* ကို အောင်မြင်စေဖို့ 通常 အောက်ပါအဆင့်တွေ လိုအပ်ပါတယ်။
အများအားဖြင့် မျက်နှာပြင်ပေါ်မှာ *လှုပ်ရှားမှု* ကို အောင်မြင်စေဖို့ အောက်ပါအဆင့်တွေလိုအပ်ပါတယ်-
1. **တည်နေရာအသစ် သတ်မှတ်ပါ**: အရာဝတ္ထုကို ရွှေ့လို့ရတယ်လို့ ခံစားနိုင်ဖို့ လိုအပ်ပါတယ်။
2. **မျက်နှာပြင်ကို ရှင်းလင်းပါ**: မျက်နှာပြင်ကို ပြန်လည်ရေးဆွဲမည့်အခါ ရှင်းလင်းထားဖို့ လိုအပ်ပါတယ်။ ဒါကို နောက်ခံအရောင်ဖြင့် rectangle တစ်ခုကို ရေးဆွဲခြင်းဖြင့် ရှင်းလင်းနိုင်ပါတယ်။
3. **အရာဝတ္ထုကို တည်နေရာအသစ်မှာ ပြန်လည်ရေးဆွဲပါ**: ဒါကို လုပ်ဆောင်ခြင်းဖြင့် အရာဝတ္ထုကို တစ်နေရာမှ တစ်နေရာသို့ ရွှေ့လှုပ်ခြင်းကို အောင်မြင်စေပါတယ်။
1. **အရာဝတ္ထုတစ်ခုအတွက် တည်နေရာအသစ် သတ်မှတ်ခြင်း**: အရာဝတ္ထုဟာ လှုပ်ရှားနေတယ်လို့ မြင်ရဖို့အတွက် လိုအပ်ပါတယ်။
2. **မျက်နှာပြင်ကို ရှင်းလင်းခြင်း**: မျက်နှာပြင်ကို ဆွဲခြင်းတိုင်းအကြားမှာ ရှင်းလင်းဖို့ လိုအပ်ပါတယ်။ ဒါကို နောက်ခံအရောင်နဲ့ ပြည့်စွက်ထားတဲ့ စတုရန်းကို ဆွဲခြင်းဖြင့် ရှင်းလင်းနိုင်ပါတယ်။
3. **အရာဝတ္ထုကို တည်နေရာအသစ်မှာ ပြန်ဆွဲခြင်း**: ဒါကို လုပ်ပြီးမှ အရာဝတ္ထုကို တစ်နေရာကနေ တစ်နေရာကို လှုပ်ရှားစေခြင်းကို အောင်မြင်စေပါတယ်။
ဒီလိုပုံစံနဲ့ ကုဒ်ထဲမှာ ရေးဆွဲနိုင်ပါတယ်။
ဒီဟာကို ကုဒ်အနေနဲ့ အောက်ပါအတိုင်း ဖြစ်နိုင်ပါတယ်-
```javascript
//set the hero's location
@ -39,15 +39,15 @@ ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
```
သင်ရဲ့ ဟီးရိုကို frame တစ်ခုစီမှာ ပြန်လည်ရေးဆွဲရင် performance cost တက်လာနိုင်တဲ့ အကြောင်းရင်းကို တွေးမြင်နိုင်ပါသလား? [ဒီ pattern ရဲ့ အခြားရွေးချယ်စရာ](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas) အကြောင်းကို ဖတ်ရှုပါ။
မိန့်ခွန်းကို တစ်စက္ကန့်လျှင် အများကြိမ် ပြန်ဆွဲရတာကြောင့် စွမ်းဆောင်ရည်အပေါ် သက်ရောက်မှုရှိနိုင်တဲ့ အကြောင်းရင်းတစ်ခုကို တွေးနိုင်ပါသလား? [ဒီပုံစံအတွက် အခြားရွေးချယ်စရာများ](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas) အကြောင်း ဖတ်ရှုပါ။
## ကီးဘုတ် event ကို ကိုင်တွယ်ခြင်း
## ကီးဘုတ်ဖြင့် အဖြစ်အပျက်များကို ကိုင်တွယ်ခြင်း
Event တွေကို ကိုင်တွယ်ဖို့အတွက် အထူးသတ်မှတ်ထားတဲ့ event တွေကို ကုဒ်နဲ့ ချိတ်ဆက်ရပါတယ်။ ကီးဘုတ် event တွေဟာ တစ်ခုလုံး window ပေါ်မှာ ဖြစ်ပေါ်ပြီး မောက်စ် event တွေက `click` ကဲ့သို့ element တစ်ခုကို click လုပ်ခြင်းနဲ့ ချိတ်ဆက်နိုင်ပါတယ်။ ဒီ project တစ်ခုလုံးမှာ ကီးဘုတ် event တွေကို အသုံးပြုပါမယ်
အဖြစ်အပျက်တွေကို ကိုင်တွယ်ဖို့အတွက် သတ်မှတ်ထားတဲ့ အဖြစ်အပျက်တွေကို ကုဒ်နဲ့ ဆက်စပ်ရပါတယ်။ ကီးဘုတ်အဖြစ်အပျက်တွေဟာ တစ်ခုလုံးကို သက်ရောက်စေပြီး မောက်စ်အဖြစ်အပျက်တွေ (ဥပမာ `click`) ကတော့ သတ်မှတ်ထားတဲ့ အရာဝတ္ထုတစ်ခုကိုသာ သက်ရောက်စေပါတယ်။ ဒီပရောဂျက်တစ်ခုလုံးမှာတော့ ကီးဘုတ်အဖြစ်အပျက်တွေကို အသုံးပြုသွားမှာပါ
Event ကို ကိုင်တွယ်ဖို့အတွက် window ရဲ့ `addEventListener()` method ကို အသုံးပြုပြီး input parameter နှစ်ခုကို ပေးရပါမယ်။ ပထမ parameter က event ရဲ့ နာမည်ဖြစ်ပြီး ဥပမာ `keyup` ဖြစ်ပါတယ်။ ဒုတိယ parameter က event ဖြစ်ပေါ်တဲ့အခါ အလုပ်လုပ်သင့်တဲ့ function ဖြစ်ပါတယ်။
အဖြစ်အပျက်တစ်ခုကို ကိုင်တွယ်ဖို့အတွက် `addEventListener()` ဆိုတဲ့ window method ကို အသုံးပြုပြီး input parameter နှစ်ခုကို ထည့်သွင်းရပါတယ်။ ပထမ parameter က အဖြစ်အပျက်ရဲ့ အမည်ဖြစ်ပြီး (ဥပမာ `keyup`) ဒုတိယ parameter ကတော့ အဖြစ်အပျက်ဖြစ်ပေါ်တဲ့အခါ ခေါ်သုံးသင့်တဲ့ function ဖြစ်ပါတယ်။
ဥပမာအနေနဲ့:
ဥပမာအနေနဲ့-
```javascript
window.addEventListener('keyup', (evt) => {
@ -58,16 +58,16 @@ window.addEventListener('keyup', (evt) => {
})
```
Key event တွေအတွက် event ရဲ့ property နှစ်ခုကို အသုံးပြုပြီး ဘယ် key ကို နှိပ်ထားတယ်ဆိုတာ သိနိုင်ပါတယ်။
Key event တွေအတွက် အဖြစ်အပျက်မှာ အသုံးပြုနိုင်တဲ့ property နှစ်ခုရှိပါတယ်-
- `key`: နှိပ်ထားတဲ့ key ရဲ့ string ကိုယ်စားပြုမှုဖြစ်ပြီး ဥပမာ `ArrowUp`
- `keyCode`: number ကိုယ်စားပြုမှုဖြစ်ပြီး ဥပမာ `37`, `ArrowLeft` ကို ကိုယ်စားပြုပါတယ်။
- `key`: ဒါဟာ ဖိထားတဲ့ key ရဲ့ string ကိုယ်စားပြုချက်ဖြစ်ပြီး (ဥပမာ `ArrowUp`)
- `keyCode`: ဒါဟာ နံပါတ်ကိုယ်စားပြုချက်ဖြစ်ပြီး (ဥပမာ `37`), `ArrowLeft` ကို ကိုယ်စားပြုပါတယ်။
✅ Key event manipulation ဟာ ဂိမ်းတိုးတက်မှုအပြင် အခြားအရာတွေမှာလည်း အသုံးဝင်ပါတယ်။ ဒီနည်းလမ်းကို ဘယ်လိုအသုံးချနိုင်မလဲဆိုတာ တွေးကြည့်ပါ။
✅ Key event manipulation ဟာ ဂိမ်းဖွံ့ဖြိုးတိုးတက်မှုအပြင် အခြားဘယ်လိုအသုံးဝင်မှုတွေ ရှိနိုင်တယ်လို့ တွေးနိုင်ပါသလဲ?
### အထူး key များ: သတိထားရမည့်အချက
### အထူးသော key များ: သတိပြုရန
အချို့ *အထူး* key တွေဟာ window ကို အကျိုးသက်ရောက်စေပါတယ်။ ဒါဟာ သင် `keyup` event ကို နားထောင်ပြီး သင့်ဟီးရိုကို အထူး key တွေကို အသုံးပြု၍ ရွှေ့လျှောက်တဲ့အခါ horizontal scrolling ကိုလည်း လုပ်ဆောင်နိုင်ပါတယ်။ ဒီအကြောင်းကြောင့် သင့်ဂိမ်းကို တည်ဆောက်တဲ့အခါ browser ရဲ့ built-in behavior ကို *ပိတ်ထား* လိုတယ်။ ဒီလိုလုပ်ဖို့အတွက် သင့်မှာ ဒီလိုကုဒ်လိုအပ်ပါတယ်။
အချို့သော *အထူး* key တွေဟာ window ကို သက်ရောက်စေပါတယ်။ ဒါကြောင့် `keyup` အဖြစ်အပျက်ကို နားထောင်နေတဲ့အခါ ဒီအထူး key တွေကို သုံးပြီး hero ကို လှုပ်ရှားစေမယ်ဆိုရင် horizontal scrolling ကိုလည်း လုပ်ဆောင်နိုင်ပါတယ်။ ဒီအကြောင်းကြောင့် ဂိမ်းကို တည်ဆောက်နေစဉ်မှာ ဒီ built-in browser behavior ကို *ပိတ်ထား* လိုက်ဖို့လိုပါတယ်။ ဒီလိုလုပ်ဖို့အတွက် အောက်ပါကုဒ်လိုမျိုး လိုအပ်ပါတယ်-
```javascript
let onKeyDown = function (e) {
@ -88,11 +88,11 @@ let onKeyDown = function (e) {
window.addEventListener('keydown', onKeyDown);
```
အထက်ပါကုဒ်ဟာ arrow-key တွေ နဲ့ space key ရဲ့ *default* behavior ကို ပိတ်ထားပါမယ်။ *ပိတ်ထား* mechanism ဟာ `e.preventDefault()` ကို ခေါ်တဲ့အခါ ဖြစ်ပေါ်ပါတယ်။
အထက်ပါကုဒ်ဟာ arrow key တွေ နဲ့ space key ရဲ့ *default* behavior ကို ပိတ်ထားစေမှာဖြစ်ပါတယ်။ ဒီ *ပိတ်ထားမှု* ကို `e.preventDefault()` ကို ခေါ်သုံးခြင်းဖြင့် ဖြစ်စေပါတယ်။
## ဂိမ်းကနေ ဖြစ်ပေါ်လာတဲ့ လှုပ်ရှားမှု
## ဂိမ်းမှ ဖြစ်ပေါ်သော လှုပ်ရှားမှု
Timer တွေကို အသုံးပြုခြင်းဖြင့် အရာဝတ္ထုတွေကို ကိုယ်တိုင် ရွှေ့လှုပ်စေနိုင်ပါတယ်။ ဥပမာ `setTimeout()` သို့မဟုတ် `setInterval()` function တွေကို အသုံးပြုပြီး အချိန်တစ်ခုစီမှာ အရာဝတ္ထုရဲ့ တည်နေရာကို update လုပ်နိုင်ပါတယ်။ ဒီလိုပုံစံနဲ့ ရေးနိုင်ပါတယ်:
`setTimeout()` သို့မဟုတ် `setInterval()` function တို့လို timer တွေကို အသုံးပြုပြီး အရာဝတ္ထုတစ်ခုရဲ့ တည်နေရာကို တစ်ခုချင်းစီ update လုပ်ခြင်းဖြင့် အရာဝတ္ထုတွေကို ကိုယ်တိုင် လှုပ်ရှားစေနိုင်ပါတယ်။ ဒီဟာကို အောက်ပါအတိုင်း ဖြစ်နိုင်ပါတယ်-
```javascript
let id = setInterval(() => {
@ -103,9 +103,9 @@ let id = setInterval(() => {
## ဂိမ်း loop
ဂိမ်း loop ဟာ အကြမ်းအားဖြင့် အချိန်အကွာအဝေးတစ်ခုစီမှာ ခေါ်ဆောင်ခံရတဲ့ function ဖြစ်ပါတယ်။ ဂိမ်း loop ဟာ အသုံးပြုသူအတွက် မြင်နိုင်တဲ့ အရာအားလုံးကို loop ထဲမှာ ရေးဆွဲပါတယ်။ ဂိမ်း loop ဟာ ဂိမ်းရဲ့ အစိတ်အပိုင်းဖြစ်တဲ့ game object တွေကို အသုံးပြုပြီး အရာအားလုံးကို ရေးဆွဲပေးပါတယ်။ ဥပမာ laser နဲ့ အာလီယန်ကို ထိမှန်ပြီး ပေါက်ကွဲသွားတဲ့အခါ အဲ့ဒီ object ဟာ လက်ရှိဂိမ်း loop ရဲ့ အစိတ်အပိုင်းမဖြစ်တော့ပါဘူး (ဒီအကြောင်းကို နောက်ပိုင်း သင်ခန်းစာတွေမှာ သင်ယူပါမယ်)။
ဂိမ်း loop ဆိုတာဟာ အချိန်အကွာအဝေးတစ်ခုအတွင်း ခေါ်သုံးတဲ့ function တစ်ခုဖြစ်ပါတယ်။ ဒါကို ဂိမ်း loop လို့ ခေါ်တာက အသုံးပြုသူအတွက် မြင်နိုင်တဲ့ အရာအားလုံးကို loop ထဲမှာ ဆွဲထားရလို့ပါ။ ဂိမ်း loop ဟာ ဂိမ်းရဲ့ အစိတ်အပိုင်းအားလုံးကို အသုံးပြုပြီး ဆွဲထားပါတယ်၊ သို့မဟုတ် တစ်ခုခုကြောင့် ဂိမ်းရဲ့ အစိတ်အပိုင်းတစ်ခုအနေနဲ့ မပါတော့ဘူးဆိုရင်တော့ မဆွဲတော့ပါဘူး။ ဥပမာအားဖြင့် ရန်သူတစ်ယောက်ဟာ laser နဲ့ ထိမှန်ပြီး ပေါက်ကွဲသွားရင်တော့ အဲ့ဒီအရာဟာ လက်ရှိဂိမ်း loop မှာ မပါတော့ပါဘူး (ဒီအကြောင်းကို နောက်ပိုင်းသင်ခန်းစာတွေမှာ ပိုမိုလေ့လာရမှာပါ)။
ဂိမ်း loop ဟာ 通常 ကုဒ်အနေနဲ့ ဒီလိုပုံစံရှိပါတယ်:
ဂိမ်း loop ဟာ ကုဒ်အနေနဲ့ အောက်ပါအတိုင်း ဖြစ်နိုင်ပါတယ်-
```javascript
let gameLoopId = setInterval(() =>
@ -119,18 +119,18 @@ let gameLoopId = setInterval(() =>
}, 200);
```
အထက်ပါ loop ဟာ canvas ကို ပြန်လည်ရေးဆွဲဖို့ `200` milliseconds တစ်ကြိမ်စီ ခေါ်ဆောင်ခံရပါတယ်။ သင့်ဂိမ်းအတွက် make sense ဖြစ်တဲ့ interval ကို ရွေးချယ်နိုင်ပါတယ်။
အထက်ပါ loop ဟာ `200` milliseconds တစ်ကြိမ်စီ ခေါ်သုံးပြီး canvas ကို ပြန်ဆွဲပါတယ်။ သင့်ဂိမ်းအတွက် make sense ဖြစ်တဲ့ interval ကို ရွေးချယ်နိုင်ပါတယ်။
## အာကာသဂိမ်းကို ဆက်လက်တိုးတက်အောင်လုပ်ခြင်း
## အာကာသဂိမ်းကို ဆက်လက်လုပ်ဆောင်ခြင်း
သင့ရဲ့ ရှိပြီးသားကုဒ်ကို ယူပြီး တိုးချဲ့ပါမယ်။ အပိုင်း I မှာ ပြီးစီးထားတဲ့ကုဒ်ကို သို့မဟုတ် [အပိုင်း II- starter](../../../../6-space-game/3-moving-elements-around/your-work) မှာရှိတဲ့ကုဒ်ကို သုံးပြုပါ။
သင့ရဲ့ ရှိပြီးသားကုဒ်ကို ယူပြီး တိုးချဲ့သွားပါမည်။ အပိုင်း I မှာ ပြီးစီးထားတဲ့ ကုဒ်ကို သုံးပါ၊ သို့မဟုတ် [Part II- starter](../../../../6-space-game/3-moving-elements-around/your-work) မှာ ရှိတဲ့ ကုဒ်ကို သုံးပါ။
- **ဟီးရိုကို ရွှေ့လျှောက်ခြင်း**: arrow key တွေကို အသုံးပြုပြီး ဟီးရိုကို ရွှေ့လျှောက်နိုင်ဖို့ ကုဒ်ထည့်ပါမယ်
- **အာလီယန်တွေကို ရွှေ့လျှောက်ခြင်း**: အာလီယန်တွေကို အပေါ်မှ အောက်သို့ သတ်မှတ်ထားတဲ့အမြန်နှုန်းနဲ့ ရွှေ့လျှောက်နိုင်ဖို့ ကုဒ်ထည့်ပါမယ်
- **Hero ကို လှုပ်ရှားခြင်း**: Arrow key တွေကို အသုံးပြုပြီး hero ကို လှုပ်ရှားနိုင်အောင် ကုဒ်ထည့်ပါ
- **ရန်သူတွေကို လှုပ်ရှားစေခြင်း**: ရန်သူတွေကို အချိန်အကွာအဝေးတစ်ခုအတွင်း အပေါ်ကနေ အောက်ကို လှုပ်ရှားစေဖို့ ကုဒ်ထည့်ပါ
## အကြံပြုအဆင့်များ
`your-work` sub folder ထဲမှာ ဖန်တီးထားတဲ့ ဖိုင်တွေကို ရှာပါ။ အောက်ပါအတိုင်း ပါဝင်ထားသင့်ပါတယ်
`your-work` sub folder ထဲမှာ ဖန်တီးထားတဲ့ ဖိုင်တွေကို ရှာပါ။ အောက်ပါအတိုင်း ပါဝင်ထားသင့်ပါတယ်-
```bash
-| assets
@ -141,22 +141,22 @@ let gameLoopId = setInterval(() =>
-| package.json
```
သင့် project ကို `your_work` folder မှာ စတင်ဖို့အတွက်:
`your_work` folder ထဲမှာ သင့် project ကို စတင်ဖို့အတွက် အောက်ပါ command ကို ရိုက်ပါ-
```bash
cd your-work
npm start
```
အထက်ပါအတိုင်း HTTP Server ကို `http://localhost:5000` လိပ်စာမှာ စတင်ပါမယ်။ Browser ကို ဖွင့်ပြီး အဲ့ဒီလိပ်စာကို ထည့်ပါ။ အခုအချိန်မှာ ဟီးရိုနဲ့ အာလီယန်တွေကို ပြသထားသင့်ပါတယ်။ ဒါပေမယ့် - အခုထိ ဘာမှ မရွှေ့လျှောက်သေးပါဘူး!
အထက်ပါ command ဟာ `http://localhost:5000` ဆိုတဲ့ လိပ်စာမှာ HTTP Server တစ်ခုကို စတင်ပါမည်။ Browser တစ်ခုကို ဖွင့်ပြီး အဲ့ဒီလိပ်စာကို ထည့်ပါ၊ အခုအချိန်မှာတော့ hero နဲ့ ရန်သူအားလုံးကို ပြသပေမယ့် ဘာမှ မလှုပ်ရှားသေးပါဘူး။
### ကုဒ်ထည့်ပါ
1. **`hero` နဲ့ `enemy` အတွက် အထူး object တွေ ထည့်ပါ**: `x` နဲ့ `y` property တွေပါဝင်သင့်ပါတယ်။ ([Inheritance or composition](../README.md) အပိုင်းကို သတိပါ။)
1. **Hero, Enemy, Game Object အတွက် အထူး object တွေ ထည့်ပါ**၊ သူတို့မှာ `x` နဲ့ `y` property တွေ ရှိသင့်ပါတယ်။ ([Inheritance or composition](../README.md) အပိုင်းကို သတိပြုပါ။)
*အကြံပြုချက်*: `game object` ဟာ `x` နဲ့ `y` နဲ့ canvas ပေါ်မှာ ကိုယ်တိုင်ကို ရေးဆွဲနိုင်တဲ့ စွမ်းရည်ရှိသင့်ပါတယ်။
*အကြံပြုချက်*: `game object` ဟာ `x` နဲ့ `y` နဲ့ သူ့ကို canvas ပေါ်မှာ ဆွဲနိုင်စွမ်း ရှိသင့်ပါတယ်။
>အကြံပြုချက်: အောက်ပါအတိုင်း GameObject class ကို ဖန်တီးပြီး canvas ပေါ်မှာ ရေးဆွဲပါ:
>အကြံပြုချက်: အောက်ပါအတိုင်း constructor နဲ့ GameObject class အသစ်တစ်ခုကို စတင်ထည့်ပါ၊ ပြီးရင် canvas ပေါ်မှာ ဆွဲပါ-
```javascript
@ -205,11 +205,11 @@ npm start
}
```
2. **Key-event handler တွေ ထည့်ပါ**: ဟီးရိုကို အပေါ်/အောက်/ဘယ်/ညာ ရွှေ့လျှောက်နိုင်ဖို့ ကီး navigation ကို handle လုပ်ပါ
2. **Key-event handler တွေ ထည့်ပါ** Hero ကို အပေါ်/အောက်/ဘယ်/ညာ လှုပ်ရှားစေဖို့
*သတိရပါ*: ကာတီရှီယန်စနစ်မှာ အပေါ်-ဘယ်က `0,0` ဖြစ်ပါတယ်။ Default behavior ကို ပိတ်ထားဖို့ ကုဒ်ထည့်ဖို့လည်း သတိရပါ။
*သတိပြုရန်*: ဒါဟာ ကားတီးရှန်းစနစ်ဖြစ်ပြီး၊ အပေါ်ဘက်-ဘယ်ဘက်က `0,0` ဖြစ်ပါတယ်။ Default behavior ကို ပိတ်ဖို့လည်း သတိပြုပါ။
>အကြံပြုချက်: သင့ရဲ့ onKeyDown function ကို ဖန်တီးပြီး window နဲ့ ချိတ်ဆက်ပါ:
>အကြံပြုချက်: သင့ရဲ့ onKeyDown function ကို ဖန်တီးပြီး window နဲ့ ဆက်စပ်ပါ-
```javascript
let onKeyDown = function (e) {
@ -221,13 +221,13 @@ npm start
window.addEventListener("keydown", onKeyDown);
```
ဒီအချိန်မှာ သင့ browser console ကို စစ်ဆေးပြီး keystroke တွေ log ဖြစ်နေတဲ့အခြေအနေကို ကြည့်ပါ။
ဒီအချိန်မှာ သင့ browser console ကို စစ်ဆေးပြီး keystroke တွေကို ကြည့်ပါ။
3. **[Pub sub pattern](../README.md) ကို အကောင်အထည်ဖော်ပါ**: သင့်ကုဒ်ကို သန့်ရှင်းစေဖို့ အပိုင်းတွေကို ဆက်လက်လုပ်ဆောင်ပါ
3. **[Pub sub pattern](../README.md) ကို အကောင်အထည်ဖော်ပါ**၊ ဒီဟာက သင့်ကုဒ်ကို သန့်ရှင်းစေမှာဖြစ်ပါတယ်
ဒီနောက်ဆုံးအပိုင်းကို လုပ်ဆောင်ဖို့:
ဒီအပိုင်းကို လုပ်ဖို့အတွက်-
1. **Event listener တစ်ခု ထည့်ပါ** window ပေါ်မှာ:
1. **Window မှာ event listener တစ်ခု ထည့်ပါ**:
```javascript
window.addEventListener("keyup", (evt) => {
@ -243,7 +243,7 @@ npm start
});
```
1. **EventEmitter class တစ်ခု ဖန်တီးပါ**: message တွေကို publish နဲ့ subscribe လုပ်နိုင်ဖို့:
1. **EventEmitter class တစ်ခု ဖန်တီးပါ** message တွေကို publish နဲ့ subscribe လုပ်ဖို့:
```javascript
class EventEmitter {
@ -285,7 +285,7 @@ npm start
eventEmitter = new EventEmitter();
```
1. **ဂိမ်းကို initialize လုပ်ပါ**
1. **ဂိမ်းကို စတင်ပါ**
```javascript
function initGame() {
@ -313,7 +313,7 @@ npm start
1. **ဂိမ်း loop ကို စတင်ပါ**
window.onload function ကို refactor လုပ်ပြီး ဂိမ်းကို initialize လုပ်ပါ။ အကောင်းဆုံး interval တစ်ခုမှာ game loop ကို စတင်ပါ။ Laser beam ကိုလည်း ထည့်ပါ:
Window.onload function ကို Refactor လုပ်ပြီး ဂိမ်းကို စတင်ပြီး interval ကောင်းတစ်ခုမှာ ဂိမ်း loop ကို စတင်ပါ။ Laser beam ကိုလည်း ထည့်ပါ-
```javascript
window.onload = async () => {
@ -334,9 +334,9 @@ npm start
};
```
5. **အာလီယန်တွေကို ရွှေ့လျှောက်ဖို့ ကုဒ်ထည့်ပါ**
5. **ရန်သူတွေကို အချိန်အကွာအဝေးတစ်ခုမှာ လှုပ်ရှားစေဖို့ ကုဒ်ထည့်ပါ**
`createEnemies()` function ကို refactor လုပ်ပြီး အာလီယန်တွေကို ဖန်တီးပြီး gameObjects class ထဲ push လုပ်ပါ:
`createEnemies()` function ကို Refactor လုပ်ပြီး ရန်သူတွေကို ဖန်တီးပြီး gameObjects class ထဲသို့ ထည့်ပါ:
```javascript
function createEnemies() {
@ -355,8 +355,8 @@ npm start
}
```
နောက်ပြီး `createHero()` function ကို ဟီးရိုအတွက် အတူတူလုပ်ဆောင်ပါ။
နောက်ပြီးတော့ Hero အတွက် `createHero()` function တစ်ခု ဖန်တီးပါ။
```javascript
function createHero() {
hero = new Hero(
@ -368,7 +368,7 @@ npm start
}
```
နောက်ဆုံးမှာ `drawGameObjects()` function ကို ထည့်ပြီး ရေးဆွဲစတင်ပါ:
နောက်ဆုံးမှာတော့ `drawGameObjects()` function တစ်ခု ထည့်ပြီး ဆွဲပါ-
```javascript
function drawGameObjects(ctx) {
@ -376,27 +376,27 @@ npm start
}
```
သင့်အာလီယန်တွေဟာ သင့်ဟီးရို spaceship ကို တိုက်ခိုက်ဖို့ စတင်ရောက်လာပါပြီ!
သင့်ရဲ့ ရန်သူတွေဟာ သင့် hero spaceship ကို တိုက်ခိုက်ဖို့ စတင်လှုပ်ရှားပါလိမ့်မည်!
---
## 🚀 စိန်ခေါ်မှု
သင့်ကုဒ်ဟာ function တွေ၊ variable တွေ၊ class တွေကို ထည့်သွင်းတဲ့အခါ 'spaghetti code' ဖြစ်လာနိုင်ပါတယ်။ သင့ကုဒ်ကို ပိုမိုဖတ်ရှုရလွယ်ကူစေဖို့ ဘယ်လိုစနစ်တစ်ခုကို အကောင်းဆုံး စီမံနိုင်မလဲ? Sketch တစ်ခုရေးဆွဲပြီး သင့ကုဒ်ကို စနစ်တကျ စီမံပါ။
သင်မြင်နိုင်သလို သငကုဒ်ဟာ function တွေ၊ variable တွေ၊ class တွေ ထည့်သွင်းလာတာနဲ့အမျှ 'spaghetti code' ဖြစ်လာနိုင်ပါတယ်။ သင့ကုဒ်ကို ပိုမိုဖတ်ရှုရလွယ်ကူအောင် ဘယ်လို ပိုမိုကောင်းမွန်စွာ စီမံနိုင်မလဲ? Sketch တစ်ခုရေးပြီး သင့ကုဒ်ကို စနစ်တကျ စီမံပါ၊ တစ်ဖိုင်ထဲမှာပဲ ရှိနေတယ်ဆိုရင်တောင်ပါ။
## မိန့်ခွန်းပြီးနောက် မေးခွန်း
## မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု
[မိန့်ခွန်းပြီးနောက် မေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/34)
[မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/34)
## ပြန်လည်သုံးသပ်ခြင်း & ကိုယ်တိုင်လေ့လာခြင်း
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
Framework များမသုံးဘဲ ဂိမ်းကိုရေးသားနေစဉ်မှာ JavaScript-based canvas framework တွေ အများကြီးရှိပါတယ်။ [ဒီ framework တွေ](https://github.com/collections/javascript-game-engines) အကြောင်းကို ဖတ်ရှုဖို့ အချိန်ယူပါ။
ကျွန်ုပ်တို့ ဂိမ်းကို framework မသုံးဘဲ ရေးသားနေသော်လည်း JavaScript-based canvas framework တွေ အများကြီး ရှိပါတယ်။ [ဒီ framework တွေ](https://github.com/collections/javascript-game-engines) အကြောင်း ဖတ်ရှုဖို့ အချိန်ယူပါ။
## လုပ်ငန်းတာဝန်
[သင့ကုဒ်ကို မှတ်ချက်ထည့်ပါ](assignment.md)
[သငကုဒ်ကို မှတ်ချက်ထည့်ပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရ အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,40 +1,40 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2e83e38c35dc003f046d7cc0bbfd4920",
"translation_date": "2025-08-27T22:22:49+00:00",
"original_hash": "a6ce295ff03bb49df7a3e17e6e7100a0",
"translation_date": "2025-08-28T18:39:05+00:00",
"source_file": "6-space-game/4-collision-detection/README.md",
"language_code": "my"
}
-->
# အာကာသဂိမ်း တည်ဆောက်ခြင်း အပိုင်း ၄: လေဆာထည့်သွင်းခြင်းနှင့် တိုက်မိမှုများကို စစ်ဆေးခြင်း
## မိန့်ခွန်းမတိုင်မီ စစ်တမ်
## သင်ခန်းစာမတိုင်မီ မေးခွန်းမျာ
[မိန့်ခွန်းမတိုင်မီ စစ်တမ်း](https://ff-quizzes.netlify.app/web/quiz/35)
[သင်ခန်းစာမတိုင်မီ မေးခွန်းများ](https://ff-quizzes.netlify.app/web/quiz/35)
ဒီသင်ခန်းစာမှာ JavaScript ကို အသုံးပြုပြီး လေဆာပစ်ပေါက်နည်းကို သင်ယူပါမည်။ ဂိမ်းမှာ အောက်ပါအရာ ၂ ခုကို ထည့်သွင်းပါမ်-
ဒီသင်ခန်းစာမှာ JavaScript ကို အသုံးပြုပြီး လေဆာပစ်ပေါက်နည်းကို သင်ယူပါမယ်! ဂိမ်းမှာ အောက်ပါအရာ ၂ ခုကို ထည့်သွင်းပါမ်-
- **လေဆာ**: ဒီလေဆာကို သင်၏သူရဲကောင်းရဲ့ သင်္ဘောမှ အပေါ်ဘက်သို့ ပစ်ပေါက်ပါမည်။
- **တိုက်မိမှု စစ်ဆေးခြင်း**: *ပစ်ပေါက်ခြင်း* စနစ်ကို အကောင်အထည်ဖော်ရာတွင် ဂိမ်းစည်းကမ်းများကို ထည့်သွင်းပါမည်။
- **လေဆာသည် ရန်သူကို ထိမိခြင်း**: ရန်သူသည် လေဆာထိမိပါက သေဆုံးမည်။
- **လေဆာသည် မျက်နှာပြင်အပေါ်ဘက်ကို ထိမိခြင်း**: လေဆာသည် မျက်နှာပြင်အပေါ်ဘက်ကို ထိမိပါက ဖျက်သိမ်းမည်။
- **ရန်သူနှင့် သူရဲကောင်း တိုက်မိခြင်း**: ရန်သူနှင့် သူရဲကောင်း တိုက်မိပါက နှစ်ဦးလုံး ဖျက်သိမ်းမည်။
- **ရန်သူသည် မျက်နှာပြင်အောက်ဘက်ကို ထိမိခြင်း**: ရန်သူသည် မျက်နှာပြင်အောက်ဘက်ကို ထိမိပါက ရန်သူနှင့် သူရဲကောင်း ဖျက်သိမ်းမည်။
- **လေဆာ**: ဒီလေဆာကို သင့်ရဲ့ ဟီးရိုးရဲ့ သင်္ဘောကနေ အပေါ်ဘက်ကို ပစ်ပေါက်ပါမယ်။
- **တိုက်မိမှု စစ်ဆေးခြင်း**: *ပစ်ပေါက်ခြင်း* စနစ်ကို အကောင်အထည်ဖော်ရာမှာ ဂိမ်းစည်းကမ်းများကို ထည့်သွင်းပါမယ်။
- **လေဆာက ရန်သူကို ထိမိခြင်း**: ရန်သူဟာ လေဆာကို ထိမိရင် သေဆုံးပါမယ်။
- **လေဆာက မျက်နှာပြင်အပေါ်ဘက်ကို ထိမိခြင်း**: လေဆာဟာ မျက်နှာပြင်အပေါ်ဘက်ကို ထိမိရင် ဖျက်သိမ်းပါမယ်။
- **ရန်သူနှင့် ဟီးရိုး တိုက်မိခြင်း**: ရန်သူနှင့် ဟီးရိုး တိုက်မိရင် နှစ်ခုလုံး ဖျက်သိမ်းပါမယ်။
- **ရန်သူက မျက်နှာပြင်အောက်ဘက်ကို ရောက်ခြင်း**: ရန်သူက မျက်နှာပြင်အောက်ဘက်ကို ရောက်ရင် ရန်သူနှင့် ဟီးရိုး နှစ်ခုလုံး ဖျက်သိမ်းပါမယ်။
အတိုချုံး来说၊ သင် -- *သူရဲကောင်း* -- သည် ရန်သူများကို မျက်နှာပြင်အောက်ဘက်သို့ ရောက်မီ လေဆာဖြင့် ထိမိစေရန် လိုအပ်ပါသည်။
အတိုချုံး来说ရင် သင် -- *ဟီးရိုး* -- ဟာ ရန်သူတွေကို မျက်နှာပြင်အောက်ဘက်ကို မရောက်ခင် လေဆာနဲ့ ပစ်ပေါက်ရပါမယ်။
✅ ကွန်ပျူတာဂိမ်းပထမဆုံးရေးသားခဲ့သော ဂိမ်းအကြောင်းကို သုတေသနလုပ်ပါ။ ၎င်း၏ လုပ်ဆောင်ချက်များက ဘာတွေလဲ?
✅ ကွန်ပျူတာဂိမ်းပထမဆုံးရေးသားခဲ့တဲ့ ဂိမ်းအကြောင်းကို သုတေသန လုပ်ကြည့်ပါ။ အဲဒီဂိမ်းရဲ့ လုပ်ဆောင်ချက်တွေက ဘာတွေလဲ?
အတူတူ သူရဲကောင်းဖြစ်ကြစို့!
အတူတူ ဟီးရိုးဖြစ်ကြရအောင်!
## တိုက်မိမှု စစ်ဆေးခြင်း
တိုက်မိမှုကို ဘယ်လိုလုပ်မလဲ? ဂိမ်းအရာဝတ္ထုများကို ရှုထောင့်များအဖြစ် သတ်မှတ်ပြီး ရွေ့လျားနေသည်ဟု စဉ်းစားရမည်။ ဘာကြောင့်လဲဆိုတော့ ဂိမ်းအရာဝတ္ထုကို ရေးဆွဲရန် အသုံးပြုသော ပုံရိပ်သည် ရှုထောင့်ပုံစံဖြစ်သည်။ ၎င်းတွင် `x`, `y`, `width` နှင့် `height` ရှိသည်။
တိုက်မိမှုကို ဘယ်လို စစ်ဆေးမလဲ? ဂိမ်းအရာဝတ္ထုတွေကို လှုပ်ရှားနေတဲ့ စတုရန်းပုံစံအနေနဲ့ တွေးရပါမယ်။ ဘာကြောင့်လဲဆိုတော့ ဂိမ်းအရာဝတ္ထုကို ရေးဆွဲဖို့ အသုံးပြုတဲ့ ပုံရိပ်ဟာ စတုရန်းပုံစံဖြစ်ပါတယ်။ အဲဒါမှာ `x`, `y`, `width` နဲ့ `height` ရှိပါတယ်။
ရှုထောင့် ၂ ခု (ဥပမာ သူရဲကောင်းနှင့် ရန်သူ) *ထိတွေ့*ပါက တိုက်မိမှုဖြစ်ပေါ်သည်။ ထိုအခါ ဘာဖြစ်ရမည်ဆိုသည်မှာ ဂိမ်းစည်းကမ်းများအပေါ် မူတည်သည်။ ထို့ကြောင့် တိုက်မိမှု စစ်ဆေးခြင်းကို အကောင်အထည်ဖော်ရန် အောက်ပါအရာများလိုအပ်သည်-
ဟီးရိုးနဲ့ ရန်သူ စတုရန်းပုံစံ ၂ ခု *ထိတွေ့*ရင် တိုက်မိမှု ဖြစ်ပါတယ်။ အဲဒီအချိန်မှာ ဘာဖြစ်ရမလဲဆိုတာက ဂိမ်းစည်းကမ်းတွေ အပေါ် မူတည်ပါတယ်။ တိုက်မိမှု စစ်ဆေးဖို့အတွက် အောက်ပါအရာတွေ လိုအပ်ပါတယ်-
1. ဂိမ်းအရာဝတ္ထု၏ ရှုထောင့်ကို ကိုယ်စားပြုနိုင်သော နည်းလမ်းတစ်ခု:
1. ဂိမ်းအရာဝတ္ထုရဲ့ စတုရန်းပုံစံကို ရယူနိုင်တဲ့ နည်းလမ်းတစ်ခု:
```javascript
rectFromGameObject() {
@ -47,7 +47,7 @@ CO_OP_TRANSLATOR_METADATA:
}
```
2. နှိုင်းယှဉ်မှုလုပ်ဆောင်ချက်တစ်ခု၊ ၎င်းလုပ်ဆောင်ချက်သည် အောက်ပါအတိုင်းဖြစ်နိုင်သည်-
2. နှိုင်းယှဉ်မှုလုပ်ဆောင်တဲ့ function တစ်ခု၊ ဒီ function ဟာ အောက်ပါအတိုင်း ဖြစ်နိုင်ပါတယ်-
```javascript
function intersectRect(r1, r2) {
@ -58,32 +58,32 @@ CO_OP_TRANSLATOR_METADATA:
}
```
## အရာဝတ္ထုများကို ဘယ်လိုဖျက်မလဲ
## အရာတွေကို ဘယ်လို ဖျက်သိမ်းမလဲ
ဂိမ်းတွင် အရာဝတ္ထုများကို ဖျက်ရန် ဂိမ်းကို ၎င်းအရာဝတ္ထုကို မျက်နှာပြင်ပေါ်တွင် ထပ်မပုံဖော်ရန် သတိပေးရမည်။ ၎င်းကို အရာဝတ္ထုကို *သေဆုံး*ဟု သတ်မှတ်ခြင်းဖြင့် ပြုလုပ်နိုင်သည်-
ဂိမ်းမှာ အရာတွေကို ဖျက်သိမ်းဖို့အတွက် ဂိမ်းကို အဲဒီအရာကို မျက်နှာပြင်မှာ ထပ်မပုံဖော်ဖို့ ပြောရပါမယ်။ အဲဒါကို *သေဆုံး*အဖြစ် သတ်မှတ်ခြင်းအားဖြင့် လုပ်ဆောင်နိုင်ပါတယ်၊ ဥပမာ-
```javascript
// collision happened
enemy.dead = true
```
ထို့နောက် *သေဆုံး*သော အရာဝတ္ထုများကို မျက်နှာပြင်ပေါ်တွင် ထပ်မပုံဖော်မီ စီစစ်နိုင်သည်-
ပြီးရင် *သေဆုံး*အရာတွေကို မျက်နှာပြင်ပုံဖော်မယ့်အခါမှာ စီမံနိုင်ပါတယ်၊ ဥပမာ-
```javascript
gameObjects = gameObject.filter(go => !go.dead);
```
## လေဆာကို ဘယ်လိုပစ်မလဲ
## လေဆာကို ဘယ်လို ပစ်ပေါက်မလဲ
လေဆာပစ်ခြင်းသည် key-event ကို တုံ့ပြန်ခြင်းနှင့် အပေါ်ဘက်သို့ ရွေ့လျားသော အရာဝတ္ထုတစ်ခုကို ဖန်တီးခြင်းဖြစ်သည်။ ထို့ကြောင့် အောက်ပါအဆင့်များကို လုပ်ဆောင်ရမည်-
လေဆာပစ်ပေါက်ခြင်းဟာ key-event ကို တုံ့ပြန်ပြီး အပေါ်ဘက်ကို လှုပ်ရှားတဲ့ object တစ်ခုကို ဖန်တီးခြင်းဖြစ်ပါတယ်။ အဲဒီအတွက် အောက်ပါအဆင့်တွေ လိုအပ်ပါတယ်-
1. **လေဆာအရာဝတ္ထုတစ်ခု ဖန်တီးပါ**: သူရဲကောင်းရဲ့ သင်္ဘောအပေါ်ဘက်မှ ဖန်တီးပြီး မျက်နှာပြင်အပေါ်ဘက်သို့ ရွေ့လျားစတင်ပါမည်။
2. **Key event ကို code ဖြင့် ချိတ်ဆက်ပါ**: ကီးဘုတ်ပေါ်ရှိ key တစ်ခုကို ရွေးချယ်ပြီး လေဆာပစ်ခြင်းကို ကိုယ်စားပြုရမည်။
3. **လေဆာပုံစံရှိသော ဂိမ်းအရာဝတ္ထုတစ်ခု ဖန်တီးပါ**: key ကို နှိပ်သောအခါ။
1. **လေဆာ object တစ်ခု ဖန်တီးပါ**: ဟီးရိုးရဲ့ သင်္ဘောအပေါ်ဘက်ကနေ ဖန်တီးပြီး မျက်နှာပြင်အပေါ်ဘက်ကို လှုပ်ရှားပါမယ်။
2. **key event နဲ့ code ကို ချိတ်ဆက်ပါ**: ကီးဘုတ်မှာ လေဆာပစ်ပေါက်ကို ကိုယ်စားပြုတဲ့ key တစ်ခုကို ရွေးချယ်ရပါမယ်။
3. **လေဆာပုံစံရှိတဲ့ ဂိမ်းအရာဝတ္ထုကို ဖန်တီးပါ**: key ကို နှိပ်တဲ့အခါ။
## လေဆာပစ်ခြင်းအတွက် Cooldown
## လေဆာပစ်ပေါက်အတွက် Cooldown
လေဆာသည် သင် key ကို နှိပ်တိုင်း ပစ်ရမည်။ ဥပမာ *space* key ကို အသုံးပြုပါ။ ဂိမ်းသည် အလွန်တိုတောင်းသောအချိန်အတွင်း လေဆာများ အလွန်များစွာ ဖန်တီးခြင်းကို ကာကွယ်ရန် လိုအပ်သည်။ ၎င်းကို *cooldown* ဟုခေါ်သော timer ကို အသုံးပြုခြင်းဖြင့် ပြုလုပ်နိုင်သည်။ ၎င်းကို အောက်ပါနည်းဖြင့် အကောင်အထည်ဖော်နိုင်သည်-
လေဆာဟာ သင့်ရဲ့ key ကို နှိပ်တိုင်း ပစ်ပေါက်ရပါမယ်၊ ဥပမာ *space* key ကို။ ဂိမ်းမှာ အလွန်များပြားတဲ့ လေဆာတွေကို အတိုင်းမသိ ဖန်တီးမရအောင် ကန့်သတ်ဖို့ လိုအပ်ပါတယ်။ အဲဒီကန့်သတ်မှုကို *cooldown* timer ကို အသုံးပြုပြီး လေဆာကို အချိန် interval တစ်ခုအတွင်းမှာပဲ ပစ်ပေါက်နိုင်အောင် လုပ်ဆောင်ရပါမယ်။ အဲဒီနည်းလမ်းကို အောက်ပါအတိုင်း အကောင်အထည်ဖော်နိုင်ပါတယ်-
```javascript
class Cooldown {
@ -109,23 +109,23 @@ class Weapon {
}
```
*Cooldowns* အကြောင်းကို သင်၏ အာကာသဂိမ်း စီးရီး၏ ပထမဆုံးသင်ခန်းစာမှ ပြန်လည်သတိရပါ။
*cooldowns* အကြောင်းကို အာကာသဂိမ်း စီးရီးရဲ့ အပိုင်း ၁ မှာ ပြန်လည်သတိရပါ။
## ဘာကို တည်ဆောက်မလဲ
သင်သည် ယခင်သင်ခန်းစာမှ ရှိပြီးသား code ကို (သင်သည် သန့်စင်ပြီး ပြန်လည်ဖွဲ့စည်းထားသင့်သည်) ယူပြီး တိုးချဲ့ပါမည်။ အပိုင်း II မှ code ကို စတင်အသုံးပြုပါ၊ သို့မဟုတ် [အပိုင်း III- starter](../../../../../../../../../your-work) တွင် code ကို အသုံးပြုပါ။
အရင်သင်ခန်းစာကနေ ရှိပြီးသား code ကို (သင့်ရဲ့ code ကို သန့်စင်ပြီး ပြန်လည်စီမံထားသင့်ပါတယ်) ယူပြီး တိုးချဲ့ပါမယ်။ အပိုင်း II မှ code ကို စတင်သုံးပါ၊ ဒါမှမဟုတ် [အပိုင်း III- starter](../../../../../../../../../your-work) မှ code ကို အသုံးပြုပါ။
> tip: သင်လုပ်ဆောင်ရမည့် လေဆာသည် assets folder တွင် ရှိပြီး သင်၏ code မှ ရည်ညွှန်းထားပြီးဖြစ်သည်။
> အကြံပြုချက်: သင်လုပ်ဆောင်မယ့် လေဆာဟာ assets folder မှာ ရှိပြီး သင့်ရဲ့ code မှာ reference လုပ်ထားပါတယ်။
- **တိုက်မိမှု စစ်ဆေးမှုကို ထည့်သွင်းပါ**၊ လေဆာသည် အရာဝတ္ထုတစ်ခုနှင့် တိုက်မိသောအခါ အောက်ပါစည်းကမ်းများကို လိုက်နာရမည်-
1. **လေဆာသည် ရန်သူကို ထိမိခြင်း**: ရန်သူသည် လေဆာထိမိပါက သေဆုံးမည်။
2. **လေဆာသည် မျက်နှာပြင်အပေါ်ဘက်ကို ထိမိခြင်း**: လေဆာသည် မျက်နှာပြင်အပေါ်ဘက်ကို ထိမိပါက ဖျက်သိမ်းမည်။
3. **ရန်သူနှင့် သူရဲကောင်း တိုက်မိခြင်း**: ရန်သူနှင့် သူရဲကောင်း တိုက်မိပါက နှစ်ဦးလုံး ဖျက်သိမ်းမည်။
4. **ရန်သူသည် မျက်နှာပြင်အောက်ဘက်ကို ထိမိခြင်း**: ရန်သူသည် မျက်နှာပြင်အောက်ဘက်ကို ထိမိပါက ရန်သူနှင့် သူရဲကောင်း ဖျက်သိမ်းမည်။
- **တိုက်မိမှု စစ်ဆေးခြင်း** ထည့်သွင်းပါ၊ လေဆာဟာ တိုက်မိတဲ့အခါ အောက်ပါစည်းကမ်းတွေကို လိုက်နာရပါမယ်-
1. **လေဆာက ရန်သူကို ထိမိခြင်း**: ရန်သူဟာ လေဆာကို ထိမိရင် သေဆုံးပါမယ်။
2. **လေဆာက မျက်နှာပြင်အပေါ်ဘက်ကို ထိမိခြင်း**: လေဆာဟာ မျက်နှာပြင်အပေါ်ဘက်ကို ထိမိရင် ဖျက်သိမ်းပါမယ်။
3. **ရန်သူနှင့် ဟီးရိုး တိုက်မိခြင်း**: ရန်သူနှင့် ဟီးရိုး တိုက်မိရင် နှစ်ခုလုံး ဖျက်သိမ်းပါမယ်။
4. **ရန်သူက မျက်နှာပြင်အောက်ဘက်ကို ရောက်ခြင်း**: ရန်သူနှင့် ဟီးရိုး နှစ်ခုလုံး ဖျက်သိမ်းပါမယ်။
## အကြံပြုထားသော အဆင့်များ
## အကြံပြုထားတဲ့ အဆင့်များ
`your-work` sub folder တွင် ဖန်တီးထားသော ဖိုင်များကို ရှာပါ။ ၎င်းတွင် အောက်ပါအရာများ ပါဝင်သင့်သည်-
`your-work` sub folder မှာ ဖန်တီးထားတဲ့ ဖိုင်တွေကို ရှာပါ။ အဲဒီ folder မှာ အောက်ပါအရာတွေ ပါဝင်သင့်ပါတယ်-
```bash
-| assets
@ -137,18 +137,18 @@ class Weapon {
-| package.json
```
သင်၏ project ကို `your_work` folder မှ စတင်ရန် အောက်ပါ command ကို ရိုက်ပါ-
သင့်ရဲ့ project ကို `your_work` folder မှာ စတင်ဖို့အတွက် အောက်ပါ command ကို ရိုက်ပါ-
```bash
cd your-work
npm start
```
အထက်ပါ command သည် HTTP Server ကို `http://localhost:5000` လိပ်စာတွင် စတင်ပါမည်။ Browser ကို ဖွင့်ပြီး ထိုလိပ်စာကို ထည့်သွင်းပါ။ ယခုအချိန်တွင် သူရဲကောင်းနှင့် ရန်သူများကို ဖော်ပြထားပြီး မည်သည့်အရာမျှ မရွေ့လျားသေးပါ
အထက်ပါ command ဟာ HTTP Server ကို `http://localhost:5000` မှာ စတင်ပါမယ်။ Browser ကို ဖွင့်ပြီး အဲဒီလိပ်စာကို ထည့်ပါ၊ အခုအချိန်မှာ ဟီးရိုးနဲ့ ရန်သူတွေကို ပြသပေမယ့် ဘာမှ မလှုပ်ရှားသေးပါဘူး
### Code ထည့်သွင်းပါ
1. **ဂိမ်းအရာဝတ္ထု၏ ရှုထောင့်ကို ကိုယ်စားပြုရန် code ကို စတင်ပါ** အောက်ပါ code သည် `GameObject` ၏ ရှုထောင့်ကို ကိုယ်စားပြုနိုင်သည်။ သင်၏ GameObject class ကို ပြင်ဆင်ပါ-
1. **ဂိမ်းအရာဝတ္ထုရဲ့ စတုရန်းပုံစံကို တည်ဆောက်ပါ**: တိုက်မိမှုကို စစ်ဆေးဖို့အတွက် အောက်ပါ code ဟာ `GameObject` ရဲ့ စတုရန်းပုံစံကို ရယူနိုင်ပါတယ်။ သင့်ရဲ့ `GameObject` class ကို ပြင်ဆင်ပါ-
```javascript
rectFromGameObject() {
@ -161,7 +161,7 @@ npm start
}
```
2. **တိုက်မိမှု စစ်ဆေးမှု code ကို ထည့်သွင်းပါ** ရှုထောင့် ၂ ခု တိုက်မိမိမိစစ်ဆေးသော လုပ်ဆောင်ချက်အသစ်တစ်ခုကို ဖန်တီးပါ-
2. **တိုက်မိမှုကို စစ်ဆေးတဲ့ code ထည့်ပါ**: စတုရန်း ၂ ခု *ထိတွေ့*မိတာကို စစ်ဆေးတဲ့ function အသစ်တစ်ခုကို ဖန်တီးပါ-
```javascript
function intersectRect(r1, r2) {
@ -174,8 +174,8 @@ npm start
}
```
3. **လေဆာပစ်ခြင်းစွမ်းရည်ကို ထည့်သွင်းပါ**
1. **Key-event message ကို ထည့်သွင်းပါ** *space* key သည် သူရဲကောင်းရဲ့ သင်္ဘောအပေါ်တွင် လေဆာတစ်ခု ဖန်တီးရမည်။ Messages object တွင် constants ၃ ခုကို ထည့်သွင်းပါ-
3. **လေဆာပစ်ပေါက်စနစ် ထည့်သွင်းပါ**
1. **key-event message ထည့်ပါ**: *space* key ဟာ ဟီးရိုးရဲ့ သင်္ဘောအပေါ်မှာ လေဆာကို ဖန်တီးရပါမယ်။ `Messages` object မှာ constants ၃ ခုကို ထည့်ပါ-
```javascript
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
@ -183,7 +183,7 @@ npm start
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
```
1. **Space key ကို ကိုင်တွယ်ပါ** `window.addEventListener` keyup function ကို ပြင်ဆင်ပြီး space key ကို ကိုင်တွယ်ပါ-
1. **space key ကို handle လုပ်ပါ**: `window.addEventListener` keyup function ကို ပြင်ဆင်ပြီး space key ကို handle လုပ်ပါ-
```javascript
} else if(evt.keyCode === 32) {
@ -191,7 +191,7 @@ npm start
}
```
1. **Listeners ကို ထည့်သွင်းပါ** `initGame()` function ကို ပြင်ဆင်ပြီး space bar ကို နှိပ်သောအခါ သူရဲကောင်းသည် လေဆာပစ်နိုင်ရန် သေချာပါစေ-
1. **listeners ထည့်ပါ**: `initGame()` function ကို ပြင်ဆင်ပြီး space bar ကို နှိပ်တဲ့အခါ ဟီးရိုးက လေဆာပစ်နိုင်အောင်လုပ်ပါ-
```javascript
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
@ -200,7 +200,7 @@ npm start
}
```
ှင့် ရန်သူသည် လေဆာနှင့် တိုက်မိသောအခါ လိုက်နာရမည့် အပြုအမူကို သေချာစေရန် `eventEmitter.on()` function အသစ်တစ်ခုကို ထည့်သွင်းပါ-
ဲ့ `eventEmitter.on()` function အသစ်ကို ထည့်ပြီး ရန်သူဟာ လေဆာနဲ့ တိုက်မိတဲ့အခါ behavior ကို သတ်မှတ်ပါ-
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -209,7 +209,7 @@ npm start
})
```
1. **Object ကို ရွေ့လျားပါ** လေဆာသည် မျက်နှာပြင်အပေါ်ဘက်သို့ တဖြည်းဖြည်း ရွေ့လျားရမည်။ သင်သည် `GameObject` ကို extend လုပ်ထားသည့်အတိုင်း Laser class အသစ်တစ်ခုကို ဖန်တီးပါ-
1. **object ကို လှုပ်ရှားပါ**: လေဆာဟာ မျက်နှာပြင်အပေါ်ဘက်ကို တဖြည်းဖြည်း လှုပ်ရှားရပါမယ်။ `GameObject` ကို extend လုပ်တဲ့ `Laser` class အသစ်ကို ဖန်တီးပါ-
```javascript
class Laser extends GameObject {
@ -230,7 +230,7 @@ npm start
}
```
1. **တိုက်မိမှုကို ကိုင်တွယ်ပါ** လေဆာအတွက် တိုက်မိမှုစည်းကမ်းများကို အကောင်အထည်ဖော်ပါ။ တိုက်မိသော objects များကို စစ်ဆေးသော `updateGameObjects()` function ကို ထည့်သွင်းပါ-
1. **တိုက်မိမှုကို handle လုပ်ပါ**: လေဆာအတွက် တိုက်မိမှုစည်းကမ်းတွေကို အကောင်အထည်ဖော်ပါ။ `updateGameObjects()` function ကို ဖန်တီးပြီး တိုက်မိတဲ့ object တွေကို စစ်ဆေးပါ-
```javascript
function updateGameObjects() {
@ -252,11 +252,11 @@ npm start
}
```
`window.onload` တွင် သင်၏ game loop ထဲသို့ `updateGameObjects()` ကို ထည့်သွင်းပါ။
`updateGameObjects()` function ကို `window.onload` ရဲ့ game loop မှာ ထည့်သွင်းပါ။
4. **လေဆာအတွက် cooldown ကို အကောင်အထည်ဖော်ပါ** လေဆာသည် အလွန်တိုတောင်းသောအချိန်အတွင်း ပစ်မရနိုင်ရန် သေချာစေရန်
4. **လေဆာအတွက် cooldown ကို အကောင်အထည်ဖော်ပါ**: လေဆာကို အချိန် interval တစ်ခုအတွင်းမှာပဲ ပစ်နိုင်အောင်လုပ်ပါ
နောက်ဆုံးတွင် Hero class ကို ပြင်ဆင်ပြီး cooldown လုပ်နိုင်စေရန်-
နောက်ဆုံးမှာ `Hero` class ကို ပြင်ဆင်ပြီး cooldown လုပ်နိုင်အောင်လုပ်ပါ-
```javascript
class Hero extends GameObject {
@ -285,27 +285,27 @@ npm start
}
```
ယခုအချိန်တွင် သင်၏ဂိမ်းတွင် functionality ရှိပါပြီ! Arrow keys ဖြင့် navigation ပြုလုပ်နိုင်ပြီး space bar ဖြင့် လေဆာပစ်နိုင်သည်။ ရန်သူများသည် လေဆာထိမိသောအခါ ပျောက်ကွယ်သွားသည်။ ကောင်းမွန်ပါတယ်!
ဒီအချိန်မှာ သင့်ရဲ့ဂိမ်းမှာ functionality ရှိပါပြီ! Arrow keys နဲ့ navigation လုပ်နိုင်ပြီး space bar နဲ့ လေဆာပစ်နိုင်ပါတယ်၊ ရန်သူတွေကို ထိမိရင် ဖျက်သိမ်းပါမယ်။ အောင်မြင်ပါတယ်!
---
## 🚀 စိန်ခေါ်မှု
ပေါက်ကွဲမှုကို ထည့်သွင်းပါ! [Space Art repo](../../../../6-space-game/solution/spaceArt/readme.txt) တွင် ရှိသော game assets ကို ကြည့်ပြီး ရန်သူကို လေဆာထိသောအခါ ပေါက်ကွဲမှုကို ထည့်သွင်းရန် ကြိုးစားပါ။
ပေါက်ကွဲမှုကို ထည့်သွင်းပါ! [Space Art repo](../../../../6-space-game/solution/spaceArt/readme.txt) မှ assets တွေကို ကြည့်ပြီး ရန်သူဟာ လေဆာနဲ့ တိုက်မိတဲ့အခါ ပေါက်ကွဲမှုကို ထည့်သွင်းကြည့်ပါ။
## မိန့်ခွန်းပြီးနောက် စစ်တမ်
## သင်ခန်းစာပြီးနောက် မေးခွန်းမျာ
[မိန့်ခွန်းပြီးနောက် စစ်တမ်း](https://ff-quizzes.netlify.app/web/quiz/36)
[သင်ခန်းစာပြီးနောက် မေးခွန်းများ](https://ff-quizzes.netlify.app/web/quiz/36)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
သင်၏ဂိမ်းတွင် interval များကို စမ်းသပ်ပါ။ ၎င်းကို ပြောင်းလဲသောအခါ ဘာဖြစ်မလဲ? [JavaScript timing events](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/) အကြောင်းပိုမိုဖတ်ရှုပါ။
ဂိမ်းမှာ interval တွေကို စမ်းသပ်ကြည့်ပါ။ အဲဒီ interval တွေကို ပြောင်းလဲတဲ့အခါ ဘာဖြစ်မလဲ? [JavaScript timing events](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/) အကြောင်းပိုမိုဖတ်ရှုပါ။
## လုပ်ငန်းတာဝန်
[တိုက်မိမှုများကို စူးစမ်းပါ](assignment.md)
[တိုက်မိမှုများကို စမ်းသပ်ပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေပါသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,23 +1,23 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4e8250db84b027c9ff816b4e4c093457",
"translation_date": "2025-08-27T22:21:04+00:00",
"original_hash": "adda95e02afa3fbee67b6e385b1109e1",
"translation_date": "2025-08-28T18:38:33+00:00",
"source_file": "6-space-game/5-keeping-score/README.md",
"language_code": "my"
}
-->
# အာကာသဂိမ်းတည်ဆောက်ခြင်း အပိုင်း ၅: အမှတ်ပေးခြင်းနှင့် အသက်များ
# အာကာသဂိမ်း တည်ဆောက်ခြင်း အပိုင်း ၅: အမှတ်နှင့် အသက်
## မိန့်ခွန်းမတင်မီ မေးခွန်းမျာ
## သင်ခန်းစာမတိုင်မီ မေးခွန်
[မိန့်ခွန်းမတင်မီ မေးခွန်းများ](https://ff-quizzes.netlify.app/web/quiz/37)
[သင်ခန်းစာမတိုင်မီ မေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/37)
ဒီသင်ခန်းစာမှာ သင်ဂိမ်းအတွက် အမှတ်ပေးခြင်းနှင့် အသက်တွက်ခြင်းကို ဘယ်လိုလုပ်ရမယ်ဆိုတာကို သင်ယူပါမယ်။
ဒီသင်ခန်းစာမှာ သင်သည် ဂိမ်းအမှတ်များ ထည့်သွင်းနည်းနှင့် အသက်တွက်ချက်နည်းကို လေ့လာမည်ဖြစ်သည်။
## မျက်နှာပြင်ပေါ်မှာ စာသားရေးခြင်း
## မျက်နှာပြင်ပေါ်တွင် စာသားရေးဆွဲခြင်း
ဂိမ်းအမှတ်ကို မျက်နှာပြင်ပေါ်မှာ ပြသနိုင်ဖို့အတွက် စာသားကို မျက်နှာပြင်ပေါ်မှာ ဘယ်လိုထားရမယ်ဆိုတာကို သိထားရပါမယ်။ အဖြေကတော့ canvas object ရဲ့ `fillText()` method ကို အသုံးပြုခြင်းဖြစ်ပါတယ်။ သင် font ဘယ်လိုသုံးမယ်၊ စာသားရဲ့ အရောင်၊ alignment (left, right, center) စတဲ့ အခြားသောအချက်တွေကိုလည်း ထိန်းချုပ်နိုင်ပါတယ်။ အောက်မှာ မျက်နှာပြင်ပေါ်မှာ စာသားရေးထားတဲ့ code ရှိပါတယ်။
ဂိမ်းအမှတ်ကို မျက်နှာပြင်ပေါ်တွင် ပြသနိုင်ရန် စာသားကို မျက်နှာပြင်ပေါ်တွင် ထားနိုင်ရမည်။ ဒီအတွက် `fillText()` method ကို canvas object ပေါ်တွင် အသုံးပြုနိုင်သည်။ သင်သည် စာသားအတွက် font, အရောင်၊ alignment (left, right, center) စသည်တို့ကိုလည်း ထိန်းချုပ်နိုင်သည်။ အောက်တွင် မျက်နှာပြင်ပေါ်တွင် စာသားရေးဆွဲထားသော ကုဒ်ကို ဖော်ပြထားသည်။
```javascript
ctx.font = "30px Arial";
@ -26,22 +26,22 @@ ctx.textAlign = "right";
ctx.fillText("show this on the screen", 0, 0);
```
✅ [Canvas မှာ စာသားထည့်သွင်းပုံ](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) အကြောင်းကို ပိုမိုလေ့လာပါ၊ သင့်အတွက် ပိုမိုလှပတဲ့ပုံစံတစ်ခုကို ဖန်တီးနိုင်ပါတယ်။
✅ [Canvas ပေါ်တွင် စာသားထည့်သွင်းနည်း](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) အကြောင်း ပိုမိုလေ့လာပါ၊ သင့်စိတ်ကြိုက် ပိုမိုလှပအောင် ပြင်ဆင်နိုင်ပါသည်။
## အသက် - ဂိမ်းအတွင်း အယူအဆ
ဂိမ်းအတွင်း အသက်ဆိုတာက ရေတွက်ချက်တစ်ခုသာဖြစ်ပါတယ်။ အာကာသဂိမ်းရဲ့ အကြောင်းအရာအနေနဲ့ သင့်ရဲ့ သင်္ဘောပျက်စီးတိုင်း အသက်တစ်ခုလျော့သွားမယ့် အသက်သတ်မှတ်ချက်ကို သတ်မှတ်ထားတာများပါတယ်။ ရေတွက်ချက်အစား သင်္ဘောငယ်များ သို့မဟုတ် နှလုံးပုံစံများကို အသက်အဖြစ် ပြသနိုင်ရင် ပိုမိုကောင်းမွန်ပါတယ်။
ဂိမ်းအတွင်း အသက်ဆိုသည်မှာ ကိန်းဂဏန်းတစ်ခုသာဖြစ်သည်။ အာကာသဂိမ်းအနေဖြင့် သင်၏ သင်္ဘောထိခိုက်မှုအခါတွင် အသက်တစ်ခုစီ လျော့နည်းသွားမည့် အသက်အရေအတွက်ကို သတ်မှတ်ထားလေ့ရှိသည်။ ကိန်းဂဏန်းအစား သင်္ဘောငယ်များ သို့မဟုတ် နှလုံးပုံများဖြင့် ပုံသဏ္ဍာန်ဖော်ပြနိုင်ပါက ပိုမိုကောင်းမွန်ပါသည်။
## ဘာတွေတည်ဆောက်မလဲ
## ဘာတွေ တည်ဆောက်မလဲ
သင့်ဂိမ်းမှာ အောက်ပါအချက်တွေကို ထည့်သွင်းပါ။
သင့်ဂိမ်းတွင် အောက်ပါအရာများကို ထည့်သွင်းပါ။
- **ဂိမ်းအမှတ်**: ရန်သူသင်္ဘောတစ်စင်းကို ဖျက်ဆီးတိုင်း သင်္ဘောပိုင်ရှင်ကို အမှတ်ပေးပါမယ်။ သင်္ဘောတစ်စင်းကို ၁၀၀ အမှတ်ပေးဖို့ အကြံပြုပါတယ်။ ဂိမ်းအမှတ်ကို အောက်ဘက်ဘယ်ဖက်မှာ ပြသပါမယ်။
- **အသက်**: သင့်သင်္ဘောမှာ အသက်သုံးခုရှိပါတယ်။ ရန်သူသင်္ဘောနဲ့ တိုက်မိတိုင်း အသက်တစ်ခုလျော့သွားပါမယ်။ အသက်အမှတ်ကို အောက်ဘက်ညာဖက်မှာ ပြသပြီး အောက်ပါပုံစံဖြစ်တဲ့ ![life image](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.my.png) ကို အသုံးပြုပါမယ်။
- **ဂိမ်းအမှတ်**: ရန်သူသင်္ဘောတစ်စင်းကို ဖျက်ဆီးတိုင်း သင်္ဘောပိုင်ရှင်သည် အမှတ် ၁၀၀ ရရှိရမည်။ ဂိမ်းအမှတ်ကို ဘေးဘက်အောက်ခြေတွင် ပြသရမည်။
- **အသက်**: သင်၏ သင်္ဘောတွင် အသက် ၃ ခု ရှိသည်။ ရန်သူသင်္ဘောနှင့် တိုက်မိတိုင်း အသက်တစ်ခု လျော့နည်းသွားမည်။ အသက်အရေအတွက်ကို ဘေးဘက်အောက်ခြေတွင် ![life image](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.my.png) ပုံဖြင့် ပြသရမည်။
## အကြံပြုထားသော လုပ်ဆောင်မှုများ
## အကြံပြု လုပ်ဆောင်မှုအဆင့်များ
`your-work` sub folder ထဲမှာ ဖန်တီးထားတဲ့ ဖိုင်တွေကို ရှာပါ။ အောက်ပါအချက်တွေပါဝင်ထားရပါမယ်။
`your-work` sub folder တွင် ဖန်တီးထားသော ဖိုင်များကို ရှာပါ။ အောက်ပါအရာများ ပါဝင်ရမည်-
```bash
-| assets
@ -53,24 +53,24 @@ ctx.fillText("show this on the screen", 0, 0);
-| package.json
```
သင့် project ကို `your_work` folder ထဲမှာ စတင်ဖို့အတွက် အောက်ပါ command ကို ရိုက်ပါ:
သင့် project ကို `your_work` folder မှ စတင်ရန် အောက်ပါ command ကို ရိုက်ထည့်ပါ-
```bash
cd your-work
npm start
```
အထက်ပါ command က HTTP Server ကို `http://localhost:5000` မှာ စတင်ပါမယ်။ Browser ကို ဖွင့်ပြီး အဲဒီလိပ်စာကို ထည့်သွင်းပါ။ အခုအချိန်မှာ သင်္ဘောပိုင်ရှင်နဲ့ ရန်သူတွေကို ပြသထားပြီး သင့်ရဲ့ left နှင့် right arrow keys ကို နှိပ်လိုက်ရင် သင်္ဘောပိုင်ရှင်ကို ရွှေ့နိုင်ပြီး ရန်သူတွေကို ပစ်ခတ်နိုင်ပါတယ်။
အထက်ပါ command သည် `http://localhost:5000` တွင် HTTP Server တစ်ခု စတင်မည်။ Browser တစ်ခုဖွင့်ပြီး အဆိုပါလိပ်စာကို ထည့်သွင်းပါ။ ယခုအချိန်တွင် သင်္ဘောပိုင်ရှင်နှင့် ရန်သူများကို မြင်ရမည်။ ဘယ်နှင့်ညာ အရိုးများကို နှိပ်လိုက်ပါက သင်္ဘောပိုင်ရှင် သွားလာနိုင်ပြီး ရန်သူများကို ပစ်ခတ်နိုင်သည်။
### Code ထည့်သွင်းခြင်း
### ကုဒ်ထည့်သွင်းခြင်း
1. **လိုအပ်သော assets များကို ကူးယူပါ**။ `solution/assets/` folder ထဲက `your-work` folder ထဲကို `life.png` asset ကို ထည့်သွင်းပါ။ `lifeImg` ကို window.onload function ထဲမှာ ထည့်သွင်းပါ:
1. **လိုအပ်သော asset များကို ကူးယူပါ**။ `solution/assets/` folder မှ `your-work` folder သို့ `life.png` asset ကို ထည့်သွင်းပါ။ `lifeImg` ကို `window.onload` function ထဲတွင် ထည့်ပါ-
```javascript
lifeImg = await loadTexture("assets/life.png");
```
1. `lifeImg` ကို assets စာရင်းထဲမှာ ထည့်သွင်းပါ:
1. `lifeImg` ကို asset များစာရင်းထဲသို့ ထည့်ပါ-
```javascript
let heroImg,
@ -80,9 +80,9 @@ npm start
eventEmitter = new EventEmitter();
```
2. **Variables ထည့်သွင်းပါ**။ အမှတ်စုစုပေါင်း (0) နှင့် အသက်ကျန် (3) ကို ကိုယ်စားပြု code ထည့်သွင်းပြီး မျက်နှာပြင်ပေါ်မှာ ပြသပါ။
2. **Variable များ ထည့်သွင်းပါ**။ စုစုပေါင်းအမှတ် (0) နှင့် ကျန်ရှိသော အသက် (3) ကို ကိုယ်စားပြုသော ကုဒ်ကို ထည့်သွင်းပြီး မျက်နှာပြင်ပေါ်တွင် ပြသပါ။
3. **`updateGameObjects()` function ကို တိုးချဲ့ပါ**။ ရန်သူနဲ့ တိုက်မိမှုကို ကိုင်တွယ်နိုငဖို့ `updateGameObjects()` function ကို တိုးချဲ့ပါ:
3. **`updateGameObjects()` function ကို တိုးချဲ့ပါ**။ ရန်သူနှင့် တိုက်မိမှုကို ကိုင်တွယ်န် `updateGameObjects()` function ကို တိုးချဲ့ပါ-
```javascript
enemies.forEach(enemy => {
@ -93,15 +93,15 @@ npm start
})
```
4. **အသက်နှင့် အမှတ်များ ထည့်သွင်းပါ**။
1. **Variables ကို Initialize လုပ်ပါ**။ `Hero` class ရဲ့ `this.cooldown = 0` အောက်မှာ အသက်နှင့် အမှတ်များကို သတ်မှတ်ပါ:
4. **အသက်နှင့် အမှတ်များ ထည့်သွင်းပါ**။
1. **Variable များ Initialize လုပ်ပါ**။ `Hero` class တွင် `this.cooldown = 0` အောက်တွင် အသက်နှင့် အမှတ်များကို သတ်မှတ်ပါ-
```javascript
this.life = 3;
this.points = 0;
```
1. **Variables များကို မျက်နှာပြင်ပေါ်မှာ ရေးပါ**။ အဲဒီ value တွေကို မျက်နှာပြင်ပေါ်မှာ ရေးပါ:
1. **Variable များကို မျက်နှာပြင်ပေါ်တွင် ရေးဆွဲပါ**-
```javascript
function drawLife() {
@ -128,18 +128,18 @@ npm start
```
1. **Game loop မှာ Methods ထည့်သွင်းပါ**။ `updateGameObjects()` အောက်မှာ ဒီ function တွေကို window.onload function ထဲမှာ ထည့်သွင်းပါ:
1. **Game loop ထဲသို့ Function များ ထည့်သွင်းပါ**။ `updateGameObjects()` အောက်တွင် အောက်ပါ function များ ထည့်သွင်းပါ-
```javascript
drawPoints();
drawLife();
```
1. **ဂိမ်းစည်းကမ်းများကို အကောင်အထည်ဖော်ပါ**။ အောက်ပါဂိမ်းစည်းကမ်းများကို အကောင်အထည်ဖော်ပါ:
1. **ဂိမ်းစည်းမျဉ်းများ အကောင်အထည်ဖော်ပါ**။ အောက်ပါစည်းမျဉ်းများကို အကောင်အထည်ဖော်ပါ-
1. **Hero နဲ့ ရန်သူတိုက်မိမှုတိုင်း** အသက်တစ်ခုလျော့ပါ။
`Hero` class ကို တိုးချဲ့ပြီး အသက်လျော့ခြင်းကို လုပ်ဆောင်ပါ:
1. **Hero နှင့် ရန်သူတိုက်မိမှုတိုင်း**တွင် အသက်တစ်ခု လျော့ပါ။
`Hero` class ကို တိုးချဲ့ပြီး အသက်လျော့ပါ-
```javascript
decrementLife() {
@ -150,9 +150,9 @@ npm start
}
```
2. **Laser တစ်ခု ရန်သူကို ထိတိုင်း** ဂိမ်းအမှတ်ကို ၁၀၀ အမှတ်တိုးပါ။
2. **Laser တစ်ခု ရန်သူကို ထိတိုင်း** ဂိမ်းအမှတ်ကို ၁၀၀ ဖြင့် တိုးပါ။
Hero class ကို တိုးချဲ့ပြီး အမှတ်တိုးခြင်းကို လုပ်ဆောင်ပါ:
`Hero` class ကို တိုးချဲ့ပြီး အမှတ်တိုးပါ-
```javascript
incrementPoints() {
@ -160,7 +160,7 @@ npm start
}
```
Collision Event Emitters ထဲမှာ ဒီ function တွေကို ထည့်သွင်းပါ:
Collision Event Emitters တွင် အောက်ပါ function များ ထည့်သွင်းပါ-
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -175,29 +175,29 @@ npm start
});
```
✅ JavaScript/Canvas ကို အသုံးပြုပြီး ဖန်တီးထားတဲ့ အခြားဂိမ်းတွေကို ရှာဖွေပါ။ အဲဒီဂိမ်းတွေမှာ ဘာတွေကို ပုံမှန်တွေ့ရလဲ?
✅ JavaScript/Canvas အသုံးပြု၍ ဖန်တီးထားသော အခြားဂိမ်းများကို ရှာဖွေပါ။ ၎င်းတို့၏ ပုံမှန်လက္ခဏာများကို လေ့လာပါ။
ဒီအလုပ်အပြီးမှာ သင့်ရဲ့ ဂိမ်းမှာ အောက်ဘက်ညာဖက်မှာ သင်္ဘောငယ်တွေကို အသက်အဖြစ် ပြသထားပြီး အမှတ်တွေကို အောက်ဘက်ဘယ်ဖက်မှာ ပြသထားရမယ်။ ရန်သူနဲ့ တိုက်မိတိုင်း အသက်ကျန်အရေအတွက် လျော့သွားပြီး ရန်သူကို ပစ်တိုင်း အမှတ်တိုးသွားရမယ်။ ကောင်းပြီ! သင့်ဂိမ်းက အပြီးသတ်နီးပါးဖြစ်နေပါပြီ။
ဒီအလုပ်အပြီးတွင် သင့်ဂိမ်းတွင် ဘေးဘက်အောက်ခြေတွင် သင်္ဘောငယ်များဖြင့် အသက်များကို မြင်ရမည်၊ အမှတ်များကို ဘေးဘက်အောက်ခြေတွင် မြင်ရမည်၊ ရန်သူနှင့် တိုက်မိတိုင်း အသက်လျော့သွားပြီး ရန်သူကို ပစ်တိုင်း အမှတ်တိုးသွားမည်ဖြစ်သည်။ ကောင်းစွာလုပ်ဆောင်နိုင်ပါပြီ! သင့်ဂိမ်းသည် အပြီးသတ်ရန် နီးကပ်နေပါပြီ။
---
## 🚀 စိန်ခေါ်မှု
သင့် code က အပြီးသတ်နီးပါးဖြစ်နေပါပြီ။ နောက်တစ်ဆင့်မှာ ဘာတွေလုပ်ဆောင်မလဲဆိုတာ စဉ်းစားနိုင်ပါသလား?
သင့်ကုဒ်သည် အပြီးသတ်ရန် နီးကပ်နေပါပြီ။ နောက်ထပ်အဆင့်များကို သင်စိတ်ကူးနိုင်ပါသလား?
## မိန့်ခွန်းပြီးနောက် မေးခွန်းများ
## သင်ခန်းစာပြီးနောက် မေးခွန်း
[မိန့်ခွန်းပြီးနောက် မေးခွန်းများ](https://ff-quizzes.netlify.app/web/quiz/38)
[သင်ခန်းစာပြီးနောက် မေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/38)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
ဂိမ်းအမှတ်နှင့် အသက်များကို တိုးခြင်းနှင့် လျော့ခြင်းလုပ်ဆောင်ပုံကို ရှာဖွေပါ။ [PlayFab](https://playfab.com) ကဲ့သို့သော စိတ်ဝင်စားဖွယ်ဂိမ်း engine တွေရှိပါတယ်။ ဒီအရာတွေကို သင့်ဂိမ်းမှာ အသုံးပြုရင် ဘယ်လိုတိုးတက်မှုတွေ ရနိုင်မလဲ?
ဂိမ်းအမှတ်နှင့် အသက်များကို တိုးခြင်းနှင့် လျော့ခြင်းနည်းလမ်းများကို လေ့လာပါ။ [PlayFab](https://playfab.com) ကဲ့သို့သော စိတ်ဝင်စားဖွယ် ဂိမ်းအင်ဂျင်များကို လေ့လာပါ။ ၎င်းတို့ကို အသုံးပြုခြင်းက သင့်ဂိမ်းကို ဘယ်လိုတိုးတက်စေမည်နည်း?
## လုပ်ငန်းတာဝန်
## အိမ်စာ
[အမှတ်ပေးဂိမ်းတည်ဆောက်ပါ](assignment.md)
[အမှတ်ပေးဂိမ်း တည်ဆောက်ပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့ရှိသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှားမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,41 +1,41 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "01336cddd638242e99b133614111ea40",
"translation_date": "2025-08-27T22:25:48+00:00",
"original_hash": "05be6c37791668e3719c4fba94566367",
"translation_date": "2025-08-28T18:40:18+00:00",
"source_file": "6-space-game/6-end-condition/README.md",
"language_code": "my"
}
-->
# အာကာသဂိမ်း တည်ဆောက်ခြင်း အပိုင်း ၆: အဆုံးသတ်ခြင်းနှင့် ပြန်စတင်ခြင်း
# အာကာသဂိမ်း တည်ဆောက်ခြင်း အပိုင်း ၆: အဆုံးနှင့် ပြန်စတင်ခြင်း
## မိန့်ခွန်းမတိုင်မီ စမ်းမေးခွန်း
## မိန့်ခွန်းမတိုင်မီ စစ်ဆေးမှု
[မိန့်ခွန်းမတိုင်မီ စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/39)
[မိန့်ခွန်းမတိုင်မီ စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/39)
ဂိမ်းတစ်ခုမှာ *အဆုံးသတ်အခြေအနေ* ကို ဖော်ပြဖို့ နည်းလမ်းအမျိုးမျိုးရှိပါတယ်။ ဂိမ်းကို ဖန်တီးသူအနေနဲ့ ဂိမ်းအဆုံးသတ်ရတဲ့ အကြောင်းရင်းကို သတ်မှတ်ရမယ်။ အခုအထိ သင်တည်ဆောက်နေတဲ့ အာကာသဂိမ်းကို အခြေခံပြီး အောက်ပါအကြောင်းရင်းတွေကို တွေးဆနိုင်ပါတယ်-
ဂိမ်းတစ်ခုအတွက် *အဆုံးအခြေအနေ* ကို ဖော်ပြရန် နည်းလမ်းအမျိုးမျိုးရှိပါတယ်။ ဂိမ်းဖန်တီးသူအနေနဲ့ ဂိမ်းအဆုံးသတ်ရတဲ့အကြောင်းရင်းကို သတ်မှတ်ရမှာဖြစ်ပါတယ်။ အခုအထိ သင်တည်ဆောက်နေတဲ့ အာကာသဂိမ်းကို အခြေခံပြီး အောက်ပါအကြောင်းရင်းများကို တွေးဆနိုင်ပါတယ်-
- **`N` ရန်သူသင်္ဘောတွေ ဖျက်ဆီးပြီး**: ဂိမ်းကို အဆင့်အလိုက် ခွဲခြားထားတဲ့အခါမှာ `N` ရန်သူသင်္ဘောတွေ ဖျက်ဆီးရမယ်ဆိုတာ အတော်လေး ရိုးရိုးတွေ့ရပါတယ်။
- **သင့်သင်္ဘော ဖျက်ဆီးခံရပြီ**: သင့်သင်္ဘော ဖျက်ဆီးခံရရင် ဂိမ်းရှုံးရတဲ့ ဂိမ်းတွေ ရှိပါတယ်။ နောက်ထပ် ရိုးရိုးတွေ့ရတာကတော့ အသက်အရေအတွက်ကို သတ်မှတ်ထားတာပါ။ သင့်သင်္ဘော ဖျက်ဆီးခံရတိုင်း အသက်တစ်ခု လျော့သွားပါတယ်။ အသက်အားလုံးဆုံးသွားရင် ဂိမ်းရှုံးရပါတယ်။
- **`N` အမှတ်စုဆောင်းပြီး**: အမှတ်စုဆောင်းတာကို အဆုံးသတ်အခြေအနေအနေနဲ့ သတ်မှတ်ထားတဲ့ ဂိမ်းတွေ ရှိပါတယ်။ အမှတ်တွေကို ဘယ်လိုရမလဲဆိုတာ သင့်အပေါ်မှာ မူတည်ပါတယ်။ ရန်သူသင်္ဘော ဖျက်ဆီးတာ၊ သို့မဟုတ် ဖျက်ဆီးခံရတဲ့အခါမှာ *ကျန်ရှိတဲ့ပစ္စည်းတွေ* စုဆောင်းတာကို အမှတ်ပေးတာတွေ ရှိပါတယ်။
- **အဆင့်တစ်ခု ပြီးမြောက်ခြင်း**: ဒါဟာ `X` ရန်သူသင်္ဘော ဖျက်ဆီးပြီး၊ `Y` အမှတ်စုဆောင်းပြီး၊ သို့မဟုတ် သတ်မှတ်ထားတဲ့ ပစ္စည်းတစ်ခုကို စုဆောင်းပြီးဖြစ်နိုင်ပါတယ်။
- **`N` ရန်သူသင်္ဘောများကို ဖျက်ဆီးပြီးဖြစ်သည်**: ဂိမ်းကို အဆင့်အလိုက် ခွဲခြားထားတဲ့အခါ `N` ရန်သူသင်္ဘောများကို ဖျက်ဆီးရမည်ဆိုတာ အတော်လေးတွေ့ရပါတယ်။
- **သင့်သင်္ဘော ဖျက်ဆီးခံရပြီ**: သင့်သင်္ဘော ဖျက်ဆီးခံရတာနဲ့ ဂိမ်းရှုံးသွားတဲ့ ဂိမ်းတွေရှိပါတယ်။ တစ်ခြားနည်းလမ်းတစ်ခုကတော့ အသက်အရေအတွက်ကို သတ်မှတ်ထားတာပါ။ သင့်သင်္ဘော ဖျက်ဆီးခံရတိုင်း အသက်တစ်ခု လျော့သွားပြီး အသက်အားလုံးဆုံးရှုံးသွားရင် ဂိမ်းရှုံးသွားပါတယ်။
- **`N` အမှတ်များ စုဆောင်းပြီးဖြစ်သည်**: အမှတ်များ စုဆောင်းခြင်းကလည်း အဆုံးအခြေအနေတစ်ခုဖြစ်ပါတယ်။ အမှတ်ရရှိဖို့ နည်းလမ်းတွေက သင့်အပေါ်မူတည်ပြီး ရန်သူသင်္ဘော ဖျက်ဆီးခြင်း၊ သို့မဟုတ် ဖျက်ဆီးပြီးနောက် ကျန်ရှိတဲ့ ပစ္စည်းများကို စုဆောင်းခြင်းစသဖြင့် အမှတ်ပေးနိုင်ပါတယ်။
- **အဆင့်တစ်ခု ပြီးမြောက်ခြင်း**: ဥပမာအားဖြင့် `X` ရန်သူသင်္ဘောများ ဖျက်ဆီးပြီး၊ `Y` အမှတ်များ စုဆောင်းပြီး၊ သို့မဟုတ် သတ်မှတ်ထားတဲ့ ပစ္စည်းတစ်ခုကို ရရှိပြီးဖြစ်နိုင်ပါတယ်။
## ပြန်စတင်ခြင်း
လူတွေ သင့်ဂိမ်းကို နှစ်သက်ရင် ပြန်ကစားချင်နိုင်ပါတယ်။ ဂိမ်းအဆုံးသတ်သွားတဲ့အခါမှာ ပြန်စတင်ဖို့ ရွေးချယ်စရာပေးသင့်ပါတယ်။
လူတွေ သင့်ဂိမ်းကို နှစ်သက်ရင် ပြန်ကစားချင်ကြမှာပါ။ ဂိမ်းအဆုံးသတ်သွားတဲ့အခါ ပြန်စတင်နိုင်တဲ့ ရွေးချယ်မှုတစ်ခုကို ပေးသင့်ပါတယ်။
✅ ဂိမ်းအဆုံးသတ်တဲ့ အခြေအနေတွေကို တွေးကြည့်ပြီး ပြန်စတင်ဖို့ ဘယ်လို အကြောင်းပြချက်တွေ ရှိနိုင်မလဲ တွေးကြည့်ပါ။
✅ ဂိမ်းတစ်ခုအဆုံးသတ်တဲ့အခြေအနေတွေကို တွေးပြီး ပြန်စတင်ဖို့ ဘယ်လိုအကြောင်းပြချက်တွေရှိနိုင်မလဲ စဉ်းစားကြည့်ပါ။
## ဘာကို တည်ဆောက်မလဲ
## ဘာတွေ တည်ဆောက်မလဲ
သင့်ဂိမ်းမှာ အောက်ပါ စည်းကမ်းတွေ ထည့်သွင်းပါမယ်-
သင့်ဂိမ်းအတွက် အောက်ပါ စည်းမျဉ်းများကို ထည့်သွင်းပါမည်-
1. **ဂိမ်းအနိုင်ရခြင်း**: ရန်သူသင်္ဘောအားလုံး ဖျက်ဆီးပြီးရင် ဂိမ်းအနိုင်ရပါတယ်။ ထို့အပြင် အနိုင်ရတဲ့ မက်ဆေ့ဂျ်တစ်ခုကို ဖော်ပြပါ။
1. **ပြန်စတင်ခြင်း**: သင့်အသက်အားလုံးဆုံးသွားတဲ့အခါ သို့မဟုတ် ဂိမ်းအနိုင်ရတဲ့အခါ ပြန်စတင်ဖို့ ရွေးချယ်စရာပေးပါ။ သတိထားပါ! ဂိမ်းကို ပြန်စတင်ဖို့ အစအဆင့်တွေကို ပြန်စတင်ပြီး ယခင်ဂိမ်းအခြေအနေကို ရှင်းလင်းထားရပါမယ်။
1. **ဂိမ်းအနိုင်ရခြင်း**: ရန်သူသင်္ဘောအားလုံး ဖျက်ဆီးပြီးဖြစ်သောအခါ ဂိမ်းအနိုင်ရသည်ဟု သတ်မှတ်ပါ။ ထို့အပြင် အနိုင်ရကြောင်း သတင်းစကားတစ်ခုကို ပြပါ။
1. **ပြန်စတင်ခြင်း**: အသက်အားလုံးဆုံးရှုံးသွားသောအခါ သို့မဟုတ် ဂိမ်းအနိုင်ရသောအခါ ပြန်စတင်နိုင်ရန် ရွေးချယ်မှုတစ်ခုကို ပေးပါ။ သတိပြုပါ! ဂိမ်းကို ပြန်စတင်ရန်အတွက် အစပိုင်းအခြေအနေကို ပြန်လည်သတ်မှတ်ရမည်ဖြစ်ပြီး ယခင်ဂိမ်းအခြေအနေများကို ရှင်းလင်းရမည်ဖြစ်သည်။
## အကြံပြုအဆင့်များ
`your-work` sub folder ထဲမှာ ဖန်တီးထားတဲ့ ဖိုင်တွေကို ရှာပါ။ အောက်ပါအတိုင်း ပါဝင်ထားရပါမယ်-
`your-work` ဆိုတဲ့ sub folder ထဲမှာ ဖန်တီးထားတဲ့ ဖိုင်တွေကို ရှာပါ။ အောက်ပါအတိုင်း ပါဝင်ထားရမည်-
```bash
-| assets
@ -48,20 +48,20 @@ CO_OP_TRANSLATOR_METADATA:
-| package.json
```
သင့်ပရောဂျက်ကို `your_work` folder ထဲမှာ စတင်ဖို့ အောက်ပါ command ကို ရိုက်ပါ-
`your_work` folder ထဲမှာ သင့် project ကို စတင်ရန် အောက်ပါ command ကို ရိုက်ပါ-
```bash
cd your-work
npm start
```
အထက်ပါ command က `http://localhost:5000` လိပ်စာမှာ HTTP Server ကို စတင်ပါမယ်။ Browser ကို ဖွင့်ပြီး အဲ့ဒီလိပ်စာကို ထည့်ပါ။ သင့်ဂိမ်းကို ကစားနိုင်တဲ့အခြေအနေမှာ ရှိရပါမယ်။
အထက်ပါ command က `http://localhost:5000` လိပ်စာမှာ HTTP Server တစ်ခု စတင်ပေးပါမည်။ Browser တစ်ခုဖွင့်ပြီး အဆိုပါ လိပ်စာကို ထည့်သွင်းပါ။ သင့်ဂိမ်းကို ကစားနိုင်အောင် ပြင်ဆင်ထားရမည်။
> tip: Visual Studio Code မှာ warning မရဖို့ `window.onload` function ကို `gameLoopId` ကို `let` မပါဘဲ ခေါ်ဖို့ ပြင်ဆင်ပါ၊ နောက်ဆုံးမှာ `let gameLoopId;` ကို ဖိုင်အပေါ်ဆုံးမှာ သီးသန့်ကြေညာပါ။
> အကြံပြုချက်: Visual Studio Code မှာ warning မထွက်အောင် `window.onload` function ကို ပြင်ပြီး `gameLoopId` ကို `let` မပါဘဲ ခေါ်ပါ။ ထို့အပြင် ဖိုင်အပေါ်ဆုံးမှာ `let gameLoopId;` ကို သီးသန့်ကြေညာပါ။
### Code ထည့်သွင်းပါ
### ကုဒ်ထည့်သွင်းခြင်း
1. **အဆုံးသတ်အခြေအနေကို ထိန်းသိမ်းပါ**: ရန်သူအရေအတွက်ကို သို့မဟုတ် သင့်သင်္ဘော ဖျက်ဆီးခံရတာကို ထိန်းသိမ်းဖို့ အောက်ပါ function နှစ်ခုကို ထည့်ပါ-
1. **အဆုံးအခြေအနေကို ထိန်းသိမ်းပါ**: ရန်သူအရေအတွက် သို့မဟုတ် သင့်သင်္ဘော ဖျက်ဆီးခံရမှုကို ထိန်းသိမ်းရန် အောက်ပါ function နှစ်ခုကို ထည့်ပါ-
```javascript
function isHeroDead() {
@ -74,7 +74,7 @@ npm start
}
```
1. **Message handler တွေကို logic ထည့်ပါ**: `eventEmitter` ကို အောက်ပါအခြေအနေတွေကို handle လုပ်ဖို့ ပြင်ဆင်ပါ-
1. **Message handler တွင် logic ထည့်ပါ**: `eventEmitter` ကို ပြင်ပြီး အောက်ပါအခြေအနေများကို ကိုင်တွယ်ပါ-
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -108,16 +108,16 @@ npm start
});
```
1. **Message အမျိုးအစားအသစ်တွေ ထည့်ပါ**: အောက်ပါ Messages တွေကို constants object ထဲမှာ ထည့်ပါ-
1. **Message အမျိုးအစားအသစ်များ ထည့်ပါ**: အောက်ပါ Messages များကို constants object ထဲထည့်ပါ-
```javascript
GAME_END_LOSS: "GAME_END_LOSS",
GAME_END_WIN: "GAME_END_WIN",
```
2. **ပြန်စတင်ဖို့ code ထည့်ပါ**: သတ်မှတ်ထားတဲ့ button ကို နှိပ်ပြီး ဂိမ်းကို ပြန်စတင်နိုင်အောင် code ထည့်ပါ။
2. **ပြန်စတင်ရန် ကုဒ်ထည့်ပါ**: သတ်မှတ်ထားတဲ့ ခလုတ်ကို နှိပ်လိုက်ရုံနဲ့ ဂိမ်းကို ပြန်စတင်နိုင်အောင် ပြင်ဆင်ပါ။
1. **Key press `Enter` ကို နားထောင်ပါ**: window ရဲ့ eventListener ကို ပြင်ဆင်ပြီး key press ကို နားထောင်ပါ-
1. **`Enter` ခလုတ်ကို နားထောင်ပါ**: window ရဲ့ eventListener ကို ပြင်ပြီး အဆိုပါ ခလုတ်ကို နားထောင်ပါ-
```javascript
else if(evt.key === "Enter") {
@ -125,17 +125,17 @@ npm start
}
```
1. **ပြန်စတင်မက်ဆေ့ဂျ် ထည့်ပါ**: Messages constant ထဲမှာ အောက်ပါ Message ကို ထည့်ပါ-
1. **ပြန်စတင် Message ထည့်ပါ**: Messages constant ထဲမှာ အောက်ပါ Message ကို ထည့်ပါ-
```javascript
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
```
1. **ဂိမ်းစည်းကမ်းတွေကို အကောင်အထည်ဖော်ပါ**: အောက်ပါဂိမ်းစည်းကမ်းတွေကို အကောင်အထည်ဖော်ပါ-
1. **ဂိမ်းစည်းမျဉ်းများကို အကောင်အထည်ဖော်ပါ**: အောက်ပါ စည်းမျဉ်းများကို အကောင်အထည်ဖော်ပါ-
1. **Player အနိုင်ရအခြေအနေ**: ရန်သူသင်္ဘောအားလုံး ဖျက်ဆီးပြီးရင် အနိုင်ရတဲ့ မက်ဆေ့ဂျ်ကို ဖော်ပြပါ။
1. **Player အနိုင်ရအခြေအနေ**: ရန်သူသင်္ဘောအားလုံး ဖျက်ဆီးပြီးဖြစ်သောအခါ အနိုင်ရကြောင်း သတင်းစကားကို ပြပါ။
1. ပထမဆုံး `displayMessage()` function ကို ဖန်တီးပါ-
1. ပထမဦးစွာ `displayMessage()` function တစ်ခု ဖန်တီးပါ-
```javascript
function displayMessage(message, color = "red") {
@ -146,7 +146,7 @@ npm start
}
```
1. `endGame()` function ကို ဖန်တီးပါ-
1. `endGame()` function တစ်ခု ဖန်တီးပါ-
```javascript
function endGame(win) {
@ -171,9 +171,9 @@ npm start
}
```
1. **ပြန်စတင် logic**: အသက်အားလုံးဆုံးသွားတဲ့အခါ သို့မဟုတ် player အနိုင်ရတဲ့အခါ ပြန်စတင်နိုင်ကြောင်း ဖော်ပြပါ။ ထို့အပြင် *ပြန်စတင်* key ကို နှိပ်တဲ့အခါ ဂိမ်းကို ပြန်စတင်ပါ (ဘယ် key ကို ပြန်စတင်ဖို့ သတ်မှတ်မလဲ သင်ဆုံးဖြတ်နိုင်ပါတယ်)
1. **ပြန်စတင် logic**: အသက်အားလုံးဆုံးရှုံးသွားသောအခါ သို့မဟုတ် Player အနိုင်ရသောအခါ ပြန်စတင်နိုင်ကြောင်း ပြပါ။ ထို့အပြင် *ပြန်စတင်* ခလုတ်ကို နှိပ်လိုက်ရုံနဲ့ ဂိမ်းကို ပြန်စတင်နိုင်အောင် ပြင်ဆင်ပါ
1. `resetGame()` function ကို ဖန်တီးပါ-
1. `resetGame()` function တစ်ခု ဖန်တီးပါ-
```javascript
function resetGame() {
@ -194,7 +194,7 @@ npm start
}
```
1. `initGame()` function ထဲမှာ `eventEmitter` ကို ခေါ်ဖို့ code ထည့်ပါ-
1. `initGame()` ထဲမှာ `eventEmitter` ကို ခေါ်ပြီး ဂိမ်းကို ပြန်စတင်ရန် call ထည့်ပါ-
```javascript
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
@ -202,7 +202,7 @@ npm start
});
```
1. EventEmitter ထဲမှာ `clear()` function ကို ထည့်ပါ-
1. EventEmitter ထဲမှာ `clear()` function တစ်ခု ထည့်ပါ-
```javascript
clear() {
@ -210,27 +210,27 @@ npm start
}
```
👽 💥 🚀 ဂိမ်းပြီးမြောက်ပါပြီ၊ Captain! အလုပ်ကောင်းပါတယ်! 🚀 💥 👽
👽 💥 🚀 ဂုဏ်ယူပါတယ်၊ ကပ္ပတိန်! သင့်ဂိမ်း ပြီးစီးပါပြီ! ကောင်းမွန်စွာ လုပ်ဆောင်နိုင်ခဲ့ပါတယ်! 🚀 💥 👽
---
## 🚀 စိန်ခေါ်မှု
အသံထည့်ပါ! Laser hit ဖြစ်တဲ့အခါ၊ hero သေဆုံးတဲ့အခါ သို့မဟုတ် အနိုင်ရတဲ့အခါ အသံထည့်နိုင်မလား? JavaScript ကို အသုံးပြုပြီး အသံဖွင့်နည်းကို သင်ယူဖို့ [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) ကို ကြည့်ပါ။
အသံထည့်ပါ! သင့်ဂိမ်းကို ပိုမိုစိတ်လှုပ်ရှားစေဖို့ အသံတစ်ခု ထည့်နိုင်မလား? ဥပမာအားဖြင့် လေဆာထိမှန်တဲ့အခါ၊ သင်္ဘောပျက်စီးတဲ့အခါ သို့မဟုတ် အနိုင်ရတဲ့အခါ အသံထည့်ပါ။ JavaScript နဲ့ အသံဖွင့်နည်းကို သင်ယူဖို့ [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) ကို ကြည့်ပါ။
## မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း
## မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု
[မိန့်ခွန်းပြီးနောက် စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/40)
[မိန့်ခွန်းပြီးနောက် စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/40)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
## ပြန်လည်ဆန်းစစ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာမှု
သင့်တာဝန်က နမူနာဂိမ်းအသစ်တစ်ခု ဖန်တီးဖို့ ဖြစ်ပါတယ်။ ဘယ်လိုဂိမ်းမျိုးကို တည်ဆောက်နိုင်မလဲဆိုတာ သိဖို့ စိတ်ဝင်စားဖွယ် ဂိမ်းတွေကို စူးစမ်းကြည့်ပါ။
သင့်တာဝန်မှာ ဂိမ်းအသစ်တစ်ခု ဖန်တီးရမှာဖြစ်ပါတယ်။ စိတ်ဝင်စားဖွယ် ဂိမ်းအမျိုးမျိုးကို စူးစမ်းပြီး သင်တည်ဆောက်ချင်တဲ့ ဂိမ်းအမျိုးအစားကို တွေးဆပါ။
## တာဝန်
[နမူနာဂိမ်းတစ်ခု တည်ဆောက်ပါ](assignment.md)
[ဂိမ်းတစ်ခု ဖန်တီးပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရ အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,31 +1,31 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "8da1b5e2c63f749808858c53f37b8ce7",
"translation_date": "2025-08-27T22:07:57+00:00",
"original_hash": "8a07db14e75ac62f013b7de5df05981d",
"translation_date": "2025-08-28T18:33:10+00:00",
"source_file": "7-bank-project/1-template-route/README.md",
"language_code": "my"
}
-->
# ဘဏ်အက်ပ်တည်ဆောက်ခြင်း အပိုင်း ၁: Web App တွင် HTML Templates နှင့် Routes
# ဘဏ်အက်ပ်တည်ဆောက်ခြင်း အပိုင်း ၁: HTML Templates နှင့် Web App Routes
## မိန့်ခွန်းမတင်မီ စမ်းမေးခွန်း
## မိန့်ခွန်းမပြောမီ စစ်ဆေးမှု
[မိန့်ခွန်းမတင်မီ စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/41)
[မိန့်ခွန်းမပြောမီ စစ်ဆေးမှု](https://ff-quizzes.netlify.app/web/quiz/41)
### နိဒါန်း
JavaScript ကို browser တွင် အသုံးပြုလာပြီးနောက်ပိုင်းကစ၍ ဝဘ်ဆိုဒ်များသည် ယခင်ထက် ပိုမိုအကျိုးရှိပြီး ရှုပ်ထွေးလာသည်။ ယနေ့ခေတ်တွင် ဝဘ်နည်းပညာများကို browser အတွင်းမှ တိုက်ရိုက်လည်ပတ်နိုင်သော [ဝဘ်အက်ပ်](https://en.wikipedia.org/wiki/Web_application) များ ဖန်တီးရန် အသုံးပြုလေ့ရှိသည်။ ဝဘ်အက်ပ်များသည် အလွန်အကျိုးရှိသောကြောင့် အသုံးပြုသူများသည် လုပ်ဆောင်ချက်တစ်ခုစီအတွက် စာမျက်နှာတစ်ခုလုံး ပြန်လည်တင်ရန် စောင့်ဆိုင်းလိုကြခြင်းမရှိပါ။ ထို့ကြောင့် JavaScript ကို DOM ကို အသုံးပြု၍ HTML ကို တိုက်ရိုက် ပြောင်းလဲရန် အသုံးပြုပြီး အသုံးပြုသူအတွေ့အကြုံကို ပိုမိုချောမွေ့စေသည်။
JavaScript ကို browser တွေမှာ အသုံးပြုလာတာနဲ့အတူ၊ ဝဘ်ဆိုဒ်တွေဟာ ယခင်ထက်ပိုမို အပြန်အလှန်ဆက်သွယ်နိုင်ပြီး ရှုပ်ထွေးလာပါတယ်။ Web နည်းပညာတွေကို browser ထဲမှာတင် အပြည့်အဝ လုပ်ဆောင်နိုင်တဲ့ [web applications](https://en.wikipedia.org/wiki/Web_application) တွေ ဖန်တီးဖို့ အသုံးပြုလာကြပါတယ်။ Web apps တွေဟာ အပြန်အလှန်ဆက်သွယ်မှုများစွာရှိတာကြောင့်၊ အသုံးပြုသူတွေဟာ လုပ်ဆောင်ချက်တစ်ခုစီအတွက် စာမျက်နှာတစ်ခုလုံး ပြန်လည်တင်သွင်းဖို့ စောင့်နေချင်ကြတာမဟုတ်ပါဘူး။ ဒါကြောင့် JavaScript ကို DOM ကို အသုံးပြုပြီး HTML ကို တိုက်ရိုက် update လုပ်ဖို့ အသုံးပြုကြပြီး၊ အသုံးပြုသူတွေ အဆင်ပြေစေတဲ့ အတွေ့အကြုံကို ပေးစွမ်းနိုင်ပါတယ်။
ဒီသင်ခန်းစာတွင် HTML templates ကို အသုံးပြု၍ စာမျက်နှာတစ်ခုလုံး ပြန်လည်တင်ရန် မလိုဘဲ မျက်နှာပြင်များစွာ ဖန်တီးနိုင်ရန် အခြေခံအဆောက်အအုံများကို တည်ဆောက်သွားမည်ဖြစ်သည်။
ဒီသင်ခန်းစာမှာတော့၊ HTML templates ကို အသုံးပြုပြီး စာမျက်နှာအမျိုးမျိုး ဖန်တီးကာ၊ HTML စာမျက်နှာတစ်ခုလုံး ပြန်လည်တင်သွင်းစရာမလိုဘဲ ပြသနိုင်ပြီး update လုပ်နိုင်တဲ့ ဘဏ် web app တစ်ခု ဖန်တီးဖို့ အခြေခံအဆောက်အအုံတွေကို တည်ဆောက်သွားမှာဖြစ်ပါတယ်။
### ကြိုတင်လိုအပ်ချက်
ဒီသင်ခန်းစာတွင် ဖန်တီးမည့် ဝဘ်အက်ပ်ကို စမ်းသပ်ရန် သင့်တွင် ဒေသခံ web server တစ်ခု လိုအပ်ပါသည်။ သင့်တွင် မရှိသေးပါက [Node.js](https://nodejs.org) ကို ထည့်သွင်းပြီး သင့်ပရောဂျက်ဖိုလ်ဒါမှ `npx lite-server` command ကို အသုံးပြုနိုင်ပါသည်။ ၎င်းသည် ဒေသခံ web server တစ်ခု ဖန်တီးပြီး သင့်အက်ပ်ကို browser တွင် ဖွင့်ပေးမည်ဖြစ်သည်။
ဒီသင်ခန်းစာမှာ တည်ဆောက်မယ့် web app ကို စမ်းသပ်ဖို့၊ သင့်မှာ ဒေသခံ web server တစ်ခု လိုအပ်ပါတယ်။ သင့်မှာ မရှိသေးပါက [Node.js](https://nodejs.org) ကို install လုပ်ပြီး `npx lite-server` command ကို သင့် project folder ထဲကနေ အသုံးပြုနိုင်ပါတယ်။ ဒါဟာ ဒေသခံ web server တစ်ခု ဖန်တီးပြီး သင့် app ကို browser ထဲမှာ ဖွင့်ပေးပါလိမ့်မယ်။
### ပြင်ဆင်မှု
သင့်ကွန်ပျူတာတွင် `bank` ဟုအမည်ပေးထားသော ဖိုလ်ဒါတစ်ခု ဖန်တီးပြီး `index.html` ဟုအမည်ပေးထားသော ဖိုင်တစ်ခု ထည့်ပါ။ ကျွန်ုပ်တို့သည် ဒီ HTML [boilerplate](https://en.wikipedia.org/wiki/Boilerplate_code) မှ စတင်ပါမည်-
သင့်ကွန်ပျူတာမှာ `bank` လို့အမည်ပေးထားတဲ့ folder တစ်ခု ဖန်တီးပြီး၊ `index.html` လို့အမည်ပေးထားတဲ့ ဖိုင်တစ်ခု ထဲမှာ ထည့်ပါ။ အောက်ပါ HTML [boilerplate](https://en.wikipedia.org/wiki/Boilerplate_code) ကို စတင်အသုံးပြုပါ။
```html
<!DOCTYPE html>
@ -45,26 +45,26 @@ JavaScript ကို browser တွင် အသုံးပြုလာပြ
## HTML Templates
ဝဘ်စာမျက်နှာအတွက် မျက်နှာပြင်များစွာ ဖန်တီးလိုပါက၊ မျက်နှာပြင်တစ်ခုစီအတွက် HTML ဖိုင်တစ်ခုစီ ဖန်တီးရန် သင်္ကေတတစ်ခုဖြစ်နိုင်သည်။ သို့သော်၊ ဒီနည်းလမ်းတွင် အခက်အခဲအချို့ရှိသည်-
Web page တစ်ခုအတွက် စာမျက်နှာအမျိုးမျိုး ဖန်တီးချင်တယ်ဆိုရင်၊ အကောင်းဆုံးနည်းလမ်းတစ်ခုကတော့ ပြသလိုတဲ့ စာမျက်နှာတစ်ခုစီအတွက် HTML ဖိုင်တစ်ခုစီ ဖန်တီးတာဖြစ်ပါတယ်။ သို့သော် ဒီနည်းလမ်းမှာ အခက်အခဲအချို့ရှိပါတယ်။
- မျက်နှာပြင်ပြောင်းလဲသည့်အခါ HTML အပြည့်အစုံကို ပြန်လည်တင်ရမည်ဖြစ်ပြီး၊ ၎င်းသည် နှေးကွေးနိုင်သည်။
- မတူညီသော မျက်နှာပြင်များအကြား ဒေတာမျှဝေရန် ခက်ခဲသည်။
- စာမျက်နှာပြောင်းတဲ့အခါ HTML တစ်ခုလုံး ပြန်လည်တင်သွင်းရတာကြောင့် နှေးကွေးနိုင်ပါတယ်။
- စာမျက်နှာအမျိုးမျိုးအကြား ဒေတာမျှဝေရတာ ခက်ခဲပါတယ်။
အခြားနည်းလမ်းတစ်ခုမှာ HTML ဖိုင်တစ်ခုသာရှိပြီး `<template>` element ကို အသုံးပြု၍ [HTML templates](https://developer.mozilla.org/docs/Web/HTML/Element/template) များစွာ သတ်မှတ်ခြင်းဖြစ်သည်။ Template သည် browser မှ မမြင်ရသော HTML block တစ်ခုဖြစ်ပြီး JavaScript ကို အသုံးပြု၍ runtime တွင် instantiate လုပ်ရန် လိုအပ်သည်။
နောက်ထပ်နည်းလမ်းတစ်ခုကတော့ HTML ဖိုင်တစ်ခုတည်းကို အသုံးပြုပြီး၊ `<template>` element ကို အသုံးပြုကာ [HTML templates](https://developer.mozilla.org/docs/Web/HTML/Element/template) အများအပြားကို သတ်မှတ်ဖန်တီးခြင်းဖြစ်ပါတယ်။ Template တစ်ခုဟာ browser ကနေ တိုက်ရိုက်ပြသမယ့် HTML block မဟုတ်ဘဲ၊ JavaScript ကို အသုံးပြုပြီး runtime မှာ instantiate လုပ်ရမယ့် reusable HTML block တစ်ခုဖြစ်ပါတယ်။
### တာဝန်
### လုပ်ဆောင်ရန်
ကျွန်ုပ်တို့သည် login စာမျက်နှာနှင့် dashboard စာမျက်နှာတို့ပါဝင်သည့် ဘဏ်အက်ပ်တစ်ခု ဖန်တီးမည်ဖြစ်သည်။ ပထမဦးစွာ၊ HTML body အတွင်း app ၏ မျက်နှာပြင်များကို instantiate လုပ်ရန် အသုံးပြုမည့် placeholder element တစ်ခု ထည့်ပါ-
ဘဏ်အက်ပ်တစ်ခုကို login စာမျက်နှာနဲ့ dashboard စာမျက်နှာနှစ်ခုပါဝင်အောင် ဖန်တီးသွားပါမယ်။ ပထမဦးစွာ HTML body ထဲမှာ placeholder element တစ်ခု ထည့်ပါ၊ ဒါကို app ရဲ့ စာမျက်နှာအမျိုးမျိုးကို instantiate လုပ်ဖို့ အသုံးပြုသွားမှာဖြစ်ပါတယ်။
```html
<div id="app">Loading...</div>
```
JavaScript ဖြင့် နောက်ပိုင်းတွင် ရှာဖွေရန် လွယ်ကူစေရန် `id` တစ်ခု ပေးထားပါသည်။
JavaScript နဲ့ အလွယ်တကူ ရှာဖွေနိုင်ဖို့ `id` တစ်ခု ပေးထားပါတယ်။
> အကြံပြုချက်- ဒီ element ၏ အကြောင်းအရာကို အစားထိုးမည်ဖြစ်သောကြောင့်၊ အက်ပ်တင်နေစဉ် ပြသမည့် loading message သို့မဟုတ် indicator တစ်ခု ထည့်နိုင်ပါသည်။
> အကြံပြုချက်: ဒီ element ရဲ့ အကြောင်းအရာကို အစားထိုးမယ့်အတွက်၊ app တင်နေစဉ် ပြသဖို့ loading message တစ်ခု သို့မဟုတ် indicator တစ်ခု ထည့်ထားနိုင်ပါတယ်။
ထို့နောက် login စာမျက်နှာအတွက် HTML template ကို ထည့်ပါ။ ယာယီအားဖြင့် title တစ်ခုနှင့် navigation ပြုလုပ်ရန် အသုံးပြုမည့် link ပါဝင်သည့် section တစ်ခု ထည့်ပါမည်။
နောက်တစ်ဆင့်မှာတော့ login စာမျက်နှာအတွက် HTML template ကို ထည့်ပါ။ အခုအချိန်မှာတော့ title တစ်ခုနဲ့ navigation လုပ်ဖို့ အသုံးပြုမယ့် link ပါဝင်တဲ့ section တစ်ခုကို ထည့်ပါမယ်။
```html
<template id="login">
@ -75,11 +75,11 @@ JavaScript ဖြင့် နောက်ပိုင်းတွင် ရှ
</template>
```
ထို့နောက် dashboard စာမျက်နှာအတွက် HTML template တစ်ခု ထည့်ပါမည်။ ဒီစာမျက်နှာတွင် အောက်ပါ section များပါဝင်မည်-
ထို့နောက် dashboard စာမျက်နှာအတွက် HTML template တစ်ခု ထည့်ပါမယ်။ ဒီစာမျက်နှာမှာ အောက်ပါ section တွေ ပါဝင်ပါမယ်။
- title နှင့် logout link ပါဝင်သည့် header
- ဘဏ်အကောင့်၏ လက်ရှိလက်ကျန်ငွေ
- အပြောင်းအလဲများကို table ဖြင့် ပြသထားသော စာရင်း
- Title နဲ့ logout link ပါဝင်တဲ့ header
- ဘဏ်အကောင့်ရဲ့ လက်ရှိလက်ကျန်
- Transactions တွေကို table အဖြစ် ပြသထားတဲ့ စာရင်း
```html
<template id="dashboard">
@ -106,31 +106,31 @@ JavaScript ဖြင့် နောက်ပိုင်းတွင် ရှ
</template>
```
> အကြံပြုချက်- HTML templates ဖန်တီးစဉ်၊ ၎င်း၏ ပုံစံကို ကြည့်လိုပါက `<template>` နှင့် `</template>` ကို `<!-- -->` ဖြင့် comment ထားနိုင်သည်။
> အကြံပြုချက်: HTML templates ဖန်တီးတဲ့အခါ၊ ဘယ်လိုပုံစံဖြစ်မလဲဆိုတာ ကြည့်ချင်ရင် `<template>` နဲ့ `</template>` ကို `<!-- -->` နဲ့ comment ထားနိုင်ပါတယ်။
✅ Template များတွင် `id` attributes ကို အသုံးပြုရသည့်အကြောင်းကို သင်ထင်သလဲ။ classes တို့ကဲ့သို့ အခြားအရာများကို အသုံးပြုနိုင်မည်လား။
✅ Template တွေမှာ `id` attribute တွေကို ဘာကြောင့် အသုံးပြုသလဲ? Classes တို့လို အခြားအရာတွေကို အသုံးပြုလို့ရမလား?
## JavaScript ဖြင့် Templates ပြသခြင်း
## JavaScript နဲ့ Templates ပြသခြင်း
သင့် HTML ဖိုင်ကို browser တွင် စမ်းကြည့်ပါက `Loading...` သာ ပြသနေမည်ဖြစ်သည်။ ၎င်းသည် HTML templates များကို instantiate လုပ်ပြီး ပြသရန် JavaScript code ထည့်ရန် လိုအပ်သည့်အတွက်ဖြစ်သည်။
HTML ဖိုင်ကို browser မှာ စမ်းကြည့်ပါက `Loading...` ဆိုပြီးပဲ ရပ်နေပါလိမ့်မယ်။ ဒါဟာ HTML templates တွေကို instantiate လုပ်ပြီး ပြသဖို့ JavaScript code ထည့်ထားရမလိုတဲ့အတွက် ဖြစ်ပါတယ်။
Template တစ်ခုကို instantiate လုပ်ရန် 通常 ၃ ချက်လိုအပ်သည်-
Template တစ်ခုကို instantiate လုပ်ဖို့ 通常 ၃ ချက်အဆင့်လိုအပ်ပါတယ်။
1. DOM အတွင်းမှ template element ကို ရှာဖွေပါ၊ ဥပမာ [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById) ကို အသုံးပြုပါ။
2. Template element ကို [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode) ဖြင့် ကူးယူပါ။
3. ၎င်းကို DOM အတွင်း မြင်နိုင်သော element တစ်ခုအောက်တွင် [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) ဖြင့် ထည့်ပါ။
1. DOM ထဲက template element ကို [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById) နဲ့ ရှာဖွေပါ။
2. Template element ကို [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode) နဲ့ ကူးယူပါ။
3. Template ကို DOM ထဲမှာ ပြသနိုင်တဲ့ element တစ်ခုအောက်မှာ [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) နဲ့ ထည့်ပါ။
✅ Template ကို DOM တွင် ထည့်မီ ကူးယူရန် လိုအပ်သည့်အကြောင်းကို သင်ထင်သလဲ။ ဒီအဆင့်ကို ကျော်လွှားပါက ဘာဖြစ်မည်လဲ။
✅ Template ကို DOM ထဲမှာ ထည့်မယ့်အခါ ကူးယူဖို့ ဘာကြောင့် လိုအပ်သလဲ? ဒီအဆင့်ကို ကျော်လိုက်ရင် ဘာဖြစ်မလဲ?
### တာဝန်
### လုပ်ဆောင်ရန်
သင့် project ဖိုလ်ဒါတွင် `app.js` ဟုအမည်ပေးထားသော ဖိုင်အသစ်တစ်ခု ဖန်တီးပြီး HTML ၏ `<head>` အပိုင်းတွင် ၎င်းကို import လုပ်ပါ-
သင့် project folder ထဲမှာ `app.js` လို့အမည်ပေးထားတဲ့ ဖိုင်တစ်ခု ဖန်တီးပြီး၊ HTML ရဲ့ `<head>` အပိုင်းထဲမှာ import လုပ်ပါ။
```html
<script src="app.js" defer></script>
```
ထို့နောက် `app.js` တွင် `updateRoute` ဟုအမည်ပေးထားသော function အသစ်တစ်ခု ဖန်တီးပါ-
အခုတော့ `app.js` ထဲမှာ `updateRoute` လို့အမည်ပေးထားတဲ့ function တစ်ခု ဖန်တီးပါ။
```js
function updateRoute(templateId) {
@ -142,19 +142,19 @@ function updateRoute(templateId) {
}
```
ဒီနေရာတွင် ကျွန်ုပ်တို့သည် အထက်ဖော်ပြထားသော ၃ ချက်ကို အတိအကျ လုပ်ဆောင်ပါသည်။ `templateId` ဖြင့် id ရှိသော template ကို instantiate လုပ်ပြီး၊ ၎င်း၏ cloned content ကို app placeholder အတွင်း ထည့်ပါသည်။ `cloneNode(true)` ကို အသုံးပြု၍ template ၏ subtree အပြည့်အစုံကို ကူးယူရန် လိုအပ်သည်
ဒီမှာ ကျွန်တော်တို့လုပ်တာက အထက်မှာ ဖော်ပြထားတဲ့ ၃ ချက်အဆင့်အတိုင်းပါပဲ။ `templateId` နဲ့ id ရှိတဲ့ template ကို instantiate လုပ်ပြီး၊ app placeholder ထဲမှာ cloned content ကို ထည့်ထားပါတယ်။ Template ရဲ့ subtree အားလုံးကို ကူးယူဖို့ `cloneNode(true)` ကို အသုံးပြုရတာကို သတိပြုပါ
ယခု function ကို template တစ်ခုနှင့်အတူ ခေါ်ပြီး ရလဒ်ကို ကြည့်ပါ-
အခု function ကို template တစ်ခုနဲ့ ခေါ်ပြီး ရလဒ်ကို ကြည့်ပါ။
```js
updateRoute('login');
```
`app.innerHTML = '';` ဟုရေးထားသော code ၏ ရည်ရွယ်ချက်ကဘာလဲ။ ၎င်းမပါဘဲဖြစ်ပါက ဘာဖြစ်မည်လဲ။
ဒီ code `app.innerHTML = '';` ရဲ့ ရည်ရွယ်ချက်က ဘာလဲ? ဒါမပါဘဲဆိုရင် ဘာဖြစ်မလဲ?
## Routes ဖန်တီးခြင်း
ဝဘ်အက်ပ်နှင့်ပတ်သက်၍ Routes ဆိုသည်မှာ **URLs** ကို ပြသရန် မျက်နှာပြင်များနှင့် ဆက်စပ်ရန် ရည်ရွယ်ချက်ဖြစ်သည်။ HTML ဖိုင်များစွာပါဝင်သော ဝဘ်ဆိုဒ်တွင်၊ ၎င်းကို အလိုအလျောက် ပြုလုပ်နိုင်သည်။ ဥပမာ၊ သင့် project ဖိုလ်ဒါတွင် အောက်ပါဖိုင်များရှိပါက-
Web app တစ်ခုအတွက် Routes ဆိုတာက URL တွေကို ပြသဖို့လိုတဲ့ စာမျက်နှာတွေနဲ့ ဆက်စပ်ပေးတဲ့ ရည်ရွယ်ချက်ကို ဆိုလိုပါတယ်။ HTML ဖိုင်အများအပြားပါဝင်တဲ့ website တစ်ခုမှာတော့၊ URL mapping ကို ဖိုင်လမ်းကြောင်းတွေက အလိုအလျောက် ပြသပေးပါတယ်။ ဥပမာ၊ သင့် project folder ထဲမှာ အောက်ပါဖိုင်တွေရှိတယ်ဆိုပါစို့-
```
mywebsite/index.html
@ -162,7 +162,7 @@ mywebsite/login.html
mywebsite/admin/index.html
```
`mywebsite` ကို root အဖြစ် သတ်မှတ်ထားသော web server တစ်ခု ဖန်တီးပါက၊ URL mapping သည်-
`mywebsite` ကို root အဖြစ် သတ်မှတ်ထားတဲ့ web server တစ်ခု ဖန်တီးပါက၊ URL mapping က အောက်ပါအတိုင်းဖြစ်ပါလိမ့်မယ်-
```
https://site.com --> mywebsite/index.html
@ -170,11 +170,11 @@ https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
```
သို့သော်၊ ကျွန်ုပ်တို့၏ ဝဘ်အက်ပ်သည် မျက်နှာပြင်အားလုံးပါဝင်သော HTML ဖိုင်တစ်ခုသာ အသုံးပြုနေသောကြောင့် ဒီ default အပြုအမူသည် အကျိုးမရှိပါ။ ကျွန်ုပ်တို့သည် ဒီ mapping ကို ကိုယ်တိုင် ဖန်တီးပြီး JavaScript ကို အသုံးပြု၍ ပြသမည့် template ကို ပြောင်းလဲရမည်ဖြစ်သည်။
သို့သော်၊ ကျွန်တော်တို့ web app မှာ HTML ဖိုင်တစ်ခုတည်းကို အသုံးပြုပြီး စာမျက်နှာအားလုံးကို ထည့်ထားတာကြောင့် ဒီ default behavior က အကျိုးမပေးပါဘူး။ ကျွန်တော်တို့ကိုယ်တိုင် map တစ်ခု ဖန်တီးပြီး JavaScript ကို အသုံးပြုကာ ပြသမယ့် template ကို update လုပ်ရပါမယ်။
### တာဝန်
### လုပ်ဆောင်ရန်
URL paths နှင့် templates များကို [map](https://en.wikipedia.org/wiki/Associative_array) တစ်ခုဖြင့် ဆက်စပ်ရန် ရိုးရှင်းသော object တစ်ခုကို `app.js` ဖိုင်၏ အပေါ်ဆုံးတွင် ထည့်ပါ။
URL paths နဲ့ templates တွေကို [map](https://en.wikipedia.org/wiki/Associative_array) လုပ်ဖို့ object တစ်ခုကို `app.js` ဖိုင်ရဲ့ အပေါ်ဆုံးမှာ ထည့်ပါ။
```js
const routes = {
@ -183,7 +183,7 @@ const routes = {
};
```
ထို့နောက် `updateRoute` function ကို အနည်းငယ် ပြောင်းလဲပါ။ `templateId` ကို တိုက်ရိုက် argument အဖြစ် ပေးပို့ခြင်းမပြုဘဲ၊ လက်ရှိ URL ကို ကြည့်ပြီး၊ map ကို အသုံးပြု၍ သက်ဆိုင်ရာ template ID ကို ရယူလိုပါသည်။ [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) ကို အသုံးပြု၍ URL ၏ path အပိုင်းကိုသာ ရယူနိုင်သည်။
အခုတော့ `updateRoute` function ကို နည်းနည်းပြင်ဆင်ပါ။ `templateId` ကို တိုက်ရိုက် argument အဖြစ် ပေးပို့မယ့်အစား၊ လက်ရှိ URL ကို ကြည့်ပြီး၊ map ကို အသုံးပြုကာ တိကျတဲ့ template ID ကို ရယူပါမယ်။ URL ရဲ့ path အပိုင်းကိုသာ ရယူဖို့ [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) ကို အသုံးပြုနိုင်ပါတယ်။
```js
function updateRoute() {
@ -198,26 +198,26 @@ function updateRoute() {
}
```
ဒီနေရာတွင် ကျွန်ုပ်တို့ သတ်မှတ်ထားသော routes များကို သက်ဆိုင်ရာ template နှင့် mapping ပြုလုပ်ထားသည်။ Browser တွင် URL ကို လက်ဖြင့် ပြောင်းလဲပြီး စမ်းကြည့်ပါ။
ဒီမှာ ကျွန်တော်တို့ သတ်မှတ်ထားတဲ့ routes တွေကို တိကျတဲ့ template နဲ့ ဆက်စပ်ပေးထားပါတယ်။ Browser မှာ URL ကို လက်ဖြင့် ပြောင်းပြီး စမ်းကြည့်ပါ။
✅ URL တွင် မသိသော path တစ်ခု ထည့်ပါက ဘာဖြစ်မည်လဲ။ ၎င်းကို ဘယ်လို ဖြေရှင်းနိုင်မည်လဲ။
✅ URL မှာ မသိတဲ့ path တစ်ခု ထည့်လိုက်ရင် ဘာဖြစ်မလဲ? ဒီပြဿနာကို ဘယ်လို ဖြေရှင်းနိုင်မလဲ?
## Navigation ထည့်သွင်းခြင်း
ကျွန်ုပ်တို့၏ app ၏ နောက်တစ်ဆင့်မှာ URL ကို လက်ဖြင့် ပြောင်းလဲရန် မလိုဘဲ စာမျက်နှာများအကြား navigation ပြုလုပ်နိုင်စေရန်ဖြစ်သည်။ ၎င်းသည် အောက်ပါ ၂ ချက်ကို အဓိကပါဝင်သည်-
App အတွက် နောက်တစ်ဆင့်က URL ကို လက်ဖြင့် ပြောင်းစရာမလိုဘဲ စာမျက်နှာအကြား navigation လုပ်နိုင်စေဖို့ ဖြစ်ပါတယ်။ ဒါဟာ အောက်ပါအရာနှစ်ခုကို အဓိကပါဝင်စေပါတယ်-
1. လက်ရှိ URL ကို ပြောငးလဲခြင်း
2. Template ကို အသစ်ပြောင်းလဲထားသော URL အပေါ် မူတည်၍ ပြသခြင်း
1. လက်ရှိ URL ကို update လုပ်ခြင်း
2. URL အသစ်အပေါ် မူတည်ပြီး ပြသမယ့် template ကို update လုပ်ခြင်း
`updateRoute` function ဖြင့် ဒုတိယအပိုင်းကို ပြုလုပ်ပြီးဖြစ်သောကြောင့်၊ လက်ရှိ URL ကို ပြောင်းလဲရန်သာ လိုအပ်ပါသည်။
`updateRoute` function နဲ့ ဒုတိယအပိုင်းကို ကျွန်တော်တို့ပြီးစီးထားပြီးဖြစ်ပါတယ်၊ ဒါကြောင့် လက်ရှိ URL ကို update လုပ်ဖို့သာ လိုအပ်ပါတယ်။
JavaScript ကို အသုံးပြုရမည်ဖြစ်ပြီး၊ HTML ကို ပြန်လည်တင်ခြင်းမပြုဘဲ URL ကို ပြောင်းလဲပြီး browsing history တွင် entry အသစ်တစ်ခု ဖန်တီးရန် [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) ကို အသုံးပြုရမည်ဖြစ်သည်
JavaScript ကို အသုံးပြုပြီး [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) ကို အသုံးပြုကာ URL ကို update လုပ်ပြီး browsing history မှာ entry အသစ်တစ်ခု ဖန်တီးနိုင်ပါတယ်၊ HTML ကို ပြန်လည်တင်သွင်းစရာမလိုပါ
> မှတ်ချက်- HTML anchor element [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) ကို အသုံးပြု၍ URL များသို့ hyperlink ဖန်တီးနိုင်သော်လည်း၊ default အနေဖြင့် browser သည် HTML ကို ပြန်လည်တင်မည်ဖြစ်သည်။ preventDefault() function ကို click event တွင် အသုံးပြု၍ ဒီအပြုအမူကို တားဆီးရန် လိုအပ်သည်။
> မှတ်ချက်: HTML anchor element [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) ကို URL အမျိုးမျိုးကို hyperlink ဖန်တီးဖို့ အသုံးပြုနိုင်သော်လည်း၊ default အနေဖြင့် browser က HTML ကို ပြန်လည်တင်သွင်းပါလိမ့်မယ်။ Custom JavaScript နဲ့ routing ကို handle လုပ်တဲ့အခါ ဒီ behavior ကို တားဆီးဖို့ `preventDefault()` function ကို click event မှာ အသုံးပြုရပါမယ်။
### တာဝန်
### လုပ်ဆောင်ရန်
App အတွင်း navigation ပြုလုပ်ရန် အသုံးပြုနိုင်သော function အသစ်တစ်ခု ဖန်တီးပါ-
App ထဲမှာ navigation လုပ်နိုင်ဖို့ အသုံးပြုမယ့် function အသစ်တစ်ခု ဖန်တီးပါ။
```js
function navigate(path) {
@ -226,9 +226,9 @@ function navigate(path) {
}
```
ဒီ method သည် ပေးထားသော path အပေါ်မူတည်၍ လက်ရှိ URL ကို update ပြုလုပ်ပြီး၊ template ကို update ပြုလုပ်သည်။ `window.location.origin` သည် URL root ကို ပြန်ပေးပြီး၊ ပေးထားသော path မှ URL အပြည့်အစုံကို ပြန်လည်တည်ဆောက်ရန် ခွင့်ပြုသည်။
ဒီ method က path ကို အခြေခံပြီး လက်ရှိ URL ကို update လုပ်ပြီး၊ template ကို update လုပ်ပါတယ်။ `window.location.origin` property က URL root ကို ပြန်ပေးပြီး၊ path တစ်ခုကို အခြေခံကာ ပြည့်စုံတဲ့ URL တစ်ခု ပြန်ဖန်တီးနိုင်စေပါတယ်။
ယခု function ရှိပြီးနောက်၊ path တစ်ခုသည် သတ်မှတ်ထားသော route များနှင့် မကိုက်ညီပါက ဖြစ်ပေါ်သော ပြဿနာကို ဖြေရှင်းနိုင်ပါသည်။ `updateRoute` function ကို ပြောင်းလဲပြီး၊ မကိုက်ညီသောအခါ ရှိပြီးသား route တစ်ခုသို့ fallback ပြုလုပ်ပါမည်။
ဒီ function ရှိပြီးနောက်၊ မည်သည့် route နဲ့မကိုက်ညီတဲ့ path တစ်ခုရိုက်ထည့်လိုက်ရင် ဖြစ်တဲ့ပြဿနာကို ဖြေရှင်းနိုင်ပါပြီ။ `updateRoute` function ကို နည်းနည်းပြင်ပြီး၊ မကိုက်ညီတဲ့ path တွေအတွက် ရှိပြီးသား route တစ်ခုကို fallback အဖြစ် သတ်မှတ်ပါမယ်။
```js
function updateRoute() {
@ -242,9 +242,9 @@ function updateRoute() {
...
```
Route တစ်ခုကို ရှာမတွေ့ပါက ယခုတွင် `login` စာမျက်နှာသို့ redirect ပြုလုပ်မည်ဖြစ်သည်။
Route တစ်ခုကို မတွေ့ရင်၊ အခုတော့ `login` စာမျက်နှာကို ပြန်လည်သွားပါလိမ့်မယ်။
Link တစ်ခုကို click ပြုလုပ်သောအခါ URL ကို ရယူပြီး browser ၏ default link အပြုအမူကို တားဆီးရန် function တစ်ခု ဖန်တီးပါ-
Link တစ်ခုကို click လုပ်တဲ့အခါ URL ကို ရယူပြီး၊ browser ရဲ့ default link behavior ကို တားဆီးဖို့ function တစ်ခု ဖန်တီးပါ။
```js
function onLinkClick(event) {
@ -253,7 +253,7 @@ function onLinkClick(event) {
}
```
Login နှင့် Logout links များကို HTML တွင် binding ပြုလုပ်၍ navigation system ကို ပြည့်စုံစေပါမည်
Login နဲ့ Logout links တွေကို HTML ထဲမှာ binding လုပ်ပြီး navigation system ကို ပြည့်စုံအောင်လုပ်ပါ
```html
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
@ -261,40 +261,40 @@ Login နှင့် Logout links များကို HTML တွင် bindi
<a href="/login" onclick="onLinkClick(event)">Logout</a>
```
အထက်ပါ `event` object သည် `click` event ကို ဖမ်းယူပြီး ၎င်းကို `onLinkClick` function သို့ ပေးပို့သည်။
အထက်ပါ `event` object က `click` event ကို ဖမ်းပြီး၊ `onLinkClick` function ကို ပေးပို့ပါတယ်။
[`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) attribute ကို အသုံးပြု`click` event ကို JavaScript code (ဤနေရာတွင် `navigate()` function ကို ခေါ်ခြင်း) နှင့် bind ပြုလုပ်ပါ။
[`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) attribute ကို အသုံးပြုပြီး `click` event ကို JavaScript code နဲ့ bind လုပ်ပါ၊ ဒီနေရာမှာတော့ `navigate()` function ကို ခေါ်ပါ။
ဒီ links များကို click ပြုလုပ်ကြည့်ပါ၊ app ၏ မျက်နှာပြင်များအကြား navigation ပြုလုပ်နိုင်ရမည်ဖြစ်သည်
ဒီ links တွေကို click လုပ်ကြည့်ပါ၊ အခုတော့ app ရဲ့ စာမျက်နှာအမျိုးမျိုးအကြား navigation လုပ်နိုင်ပါပြီ
`history.pushState` method သည် HTML5 စံနှင့်အညီဖြစ်ပြီး [ခေတ်မီ browser များအားလုံး](https://caniuse.com/?search=pushState) တွင် အကောင်အထည်ဖော်ထားသည်။ သို့သော်၊ သင်ဟောင်းနောက်ကျသော browser များအတွက် ဝဘ်အက်ပ်တစ်ခု တည်ဆောက်နေပါက၊ ဒီ API အစား အသုံးပြုနိုင်သော နည်းလမ်းတစ်ခုရှိသည်- path မတိုင်မီ [hash (`#`)](https://en.wikipedia.org/wiki/URI_fragment) ကို အသုံးပြု၍ regular anchor navigation ဖြင့် ပြုလုပ်နိုင်ပြီး စာမျက်နှာကို ပြန်လည်တင်မည်မဟုတ်ပါ၊ ၎င်း၏ ရည်ရွယ်ချက်မှာ စာမျက်နှာအတွင်း internal links ဖန်တီးရန်ဖြစ်သည်။
`history.pushState` method ဟာ HTML5 standard ရဲ့ အစိတ်အပိုင်းတစ်ခုဖြစ်ပြီး [ခေတ်သစ် browser အားလုံး](https://caniuse.com/?search=pushState) မှာ အကောင်အထည်ဖော်ထားပါတယ်။ အဟောင်း browser တွေအတွက် web app တစ်ခု တည်ဆောက်နေတယ်ဆိုရင်၊ ဒီ API အစား အသုံးပြုနိုင်တဲ့ နည်းလမ်းတစ်ခုရှိပါတယ်- path ရဲ့ အရှေ့မှာ [hash (`#`)](https://en.wikipedia.org/wiki/URI_fragment) ကို အသုံးပြုကာ၊ regular anchor navigation နဲ့အတူ အလုပ်လုပ်ပြီး စာမျက်နှာကို ပြန်လည်တင်သွင်းစရာမလိုတဲ့ routing ကို အကောင်အထည်ဖော်နိုင်ပါတယ်။
## Browser ၏ Back နှင့် Forward Buttons ကို ကိုင်တွယ်ခြင်း
## Browser ရဲ့ Back နဲ့ Forward Buttons ကို Handle လုပ်ခြင်း
`history.pushState` ကို အသုံးပြုခြင်းဖြင့် browser ၏ navigation history တွင် entry အသစ်များ ဖန်တီးသည်။ Browser ၏ *back button* ကို ဖိထားကြည့်ပါက အောက်ပါအတိုင်း ပြသမည်ဖြစ်သည်-
`history.pushState` ကို အသုံးပြုခြင်းက browser ရဲ့ navigation history မှာ အသစ်တစ်ခု ထည့်ပေးပါတယ်။ Browser ရဲ့ *back button* ကို ဖိထားပြီး စမ်းကြည့်ပါ၊ အောက်ပါအတိုင်း ပြသပေးပါလိမ့်မယ်-
![Navigation history ၏ Screenshot](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.my.png)
![Navigation History Screenshot](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.my.png)
Back button ကို အကြိမ်အများကြိမ် click ပြုလုပ်ကြည့်ပါက၊ လက်ရှိ URL သည် ပြောင်းလဲပြီး history ကို update ပြုလုပ်မည်ဖြစ်သော်လည်း၊ template တူညီသည်ကိုသာ ပြသနေမည်ဖြစ်သည်။
Back button ကို အကြိမ်ကြိမ် click လုပ်ကြည့်ပါ၊ လက်ရှိ URL က ပြောင်းသွားပြီး history က update လုပ်ပေမယ့်၊ တူညီတဲ့ template ပဲ ပြသနေပါလိမ့်မယ်။
၎င်းသည် state ပြောင်းလဲမှု - URL တစ်ခုမှ တစ်ခုသို့ ရွှေ့ပြောင်းမှု - ဖြစ်ပေါ်ပါက [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) event ကို trigger ပြုလုပ်သည်ဟု [`history.pushState` documentation](https://developer.mozilla.org/docs/Web/API/History/pushState) တွင် ဖော်ပြထားသည်။ ဒီပြဿနာကို ဖြေရှင်းရန် ၎င်းကို အသုံးပြုမည်ဖြစ်သည်။
ဒါဟာ application က history ပြောင်းလဲမှုကို updateRoute() ကို ခေါ်ဖို့ မသိတဲ့အတွက် ဖြစ်ပါတယ်။ [`history.pushState` documentation](https://developer.mozilla.org/docs/Web/API/History/pushState) ကို ကြည့်ပါက၊ state ပြောင်းလဲမှုဖြစ်ရင် - URL တစ်ခုကို ပြောင်းလဲသွားပြီဆိုတာ - [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) event တစ်ခု trigger လုပ်တယ်ဆိုတာ တွေ့ရပါမယ်။ ဒီအရာကို အသုံးပြုပြီး ပြဿနာကို ဖြေရှင်းသွားပါမယ်။
### တာဝန်
### လုပ်ဆောင်ရန်
Browser history ပြောင်းလဲမှုအခါတွင် ပြသထားသော template ကို update ပြုလုပ်ရန် `updateRoute()` ကို ခေါ်သည့် function အသစ်တစ်ခုကို `app.js` ဖိုင်၏ အောက်ဆုံးတွင် ထည့်ပါ-
Browser history ပြောင်းလဲမှုဖြစ်တဲ့အခါ ပြသမယ့် template ကို update လုပ်စေရန် `updateRoute()` ကို ခေါ်တဲ့ function အသစ်တစ်ခုကို `app.js` ဖိုင်ရဲ့ အောက်ဆုံးမှာ ထည့်ပါ။
```js
window.onpopstate = () => updateRoute();
updateRoute();
```
> မှတ်ချက်- ဒီနေရာတွင် `popstate` event handler ကို ရှင်းလင်းစွာ ဖော်ပြရန် [arrow function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) ကို အသုံးပြုထားသော်လည်း၊ ပုံမှန် function တစ်ခုလည်း အလားတူအလုပ်လုပ်မည်ဖြစ်သည်။
> မှတ်ချက်: ဒီမှာ `popstate` event handler ကို ကြောင်းတိုအောင် [arrow function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) ကို အသုံးပြုပြီး သတ်မှတ်ထားပါတယ်၊ သို့သော် regular function တစ်ခုလည်း အလားတူအလုပ်လုပ်ပါလိမ့်မယ်။
Arrow functions အကြောင်း refresher video-
Arrow functions အကြောင်း refresher video တစ်ခု-
[![Arrow Functions](https://img.youtube.com/vi/OP6eEbOj2sc/0
[![Arrow Functions](https://img.youtube.com/vi/OP6eEbOj2
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်မှု ဝန်ဆောင်မှုကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုယူသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှားမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,36 +1,36 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b667b7d601e2ee19acb5aa9d102dc9f3",
"translation_date": "2025-08-27T22:03:25+00:00",
"original_hash": "8baca047d77a5f43fa4099c0578afa42",
"translation_date": "2025-08-28T18:31:11+00:00",
"source_file": "7-bank-project/2-forms/README.md",
"language_code": "my"
}
-->
# ဘဏ်အက်ပ်တည်ဆောက်ခြင်း အပိုင်း ၂: Login နှင့် Registration Form တည်ဆောက်ခြင်း
## မိန့်ခွန်းမတင်မီ မေးခွန်းများ
## မိန့်ခွန်းမတိုင်မီ စမ်းမေးခွန်း
[မိန့်ခွန်းမတင်မီ မေးခွန်းများ](https://ff-quizzes.netlify.app/web/quiz/43)
[မိန့်ခွန်းမတိုင်မီ စမ်းမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/43)
### အကျဉ်းချုပ်
### နိဒါန်း
ခေတ်မီ ဝက်ဘ်အက်ပ်များအများစုတွင် သင့်ကိုယ်ပိုင် အကောင့်တစ်ခုဖွင့်ိုင်ပြီး ကိုယ်ပိုင်နေရာတစ်ခုရရှိနိုင်သည်။ က်ဘ်အက်ပ်ကို အသုံးပြုသူများစွာ တစ်ချိန်တည်းတွင် ဝင်ရောက်အသုံးပြုနိုင်သောကြောင့် အသုံးပြုသူတစ်ဦးချင်းစီ၏ ကိုယ်ရေးအချက်အလက်များကို သီးခြားသိမ်းဆည်းရန်နှင့် ပြသရန်အချက်အလက်များကို ရွေးချယ်ရန် စနစ်တစ်ခုလိုအပ်သည်။ [အသုံးပြုသူအတိအကျမှတ်ပုံတင်မှု](https://en.wikipedia.org/wiki/Authentication) ကို လုံခြုံစွာ စီမံခန့်ခွဲပုံကို မလေ့လာသေးပါ၊ ဒါပေမယ့် သုံးစွဲသူတစ်ဦး (သို့) အကောင့်များစွာ ဖွင့်နိုင်ရန် သေချာစေပါမည်။
ခေတ်သစ်ဝဘ်အက်ပ်များအများစုတွင် သင့်ကိုယ်ပိုင်အကောင့်တစ်ခုဖန်တီးပြီး ကိုယ်ပိုင်နေရာတစ်ခုရရှိနိုင်သည်။ ဝဘ်အက်ပ်ကို အသုံးပြုသူများစွာ တစ်ချိန်တည်းတွင် ဝင်ရောက်အသုံးပြုနိုင်သောကြောင့် အသုံးပြုသူတစ်ဦးချင်းစီ၏ ကိုယ်ရေးအချက်အလက်များကို သီးခြားသိမ်းဆည်းရန်နှင့် ပြသရန်အချက်အလက်များကို ရွေးချယ်ရန် စနစ်တစ်ခုလိုအပ်သည်။ [အသုံးပြုသူအတည်ပြုမှုကို လုံခြုံစွာ စီမံခန့်ခွဲခြင်း](https://en.wikipedia.org/wiki/Authentication) အကြောင်းကို မလေ့လာသေးပေမယ့် ကျွန်ုပ်တို့၏အက်ပ်တွင် အသုံးပြုသူတစ်ဦး (သို့မဟုတ်) အကောင့်များစွာ ဖန်တီးနိုင်စေရန် သေချာစေပါမည်။
ဒီအပိုင်းမှာ HTML forms ကို အသုံးပြုပြီး ဝက်ဘ်အက်ပ်မှာ login နှင့် registration ပေါင်းထည့်ပါမည်။ ဒေတာကို server API သို့ programmatically ပို့ပေးပုံနှင့် အသုံးပြုသူ input များအတွက် အခြေခံအတိအကျစစ်ဆေးမှု စည်းမျဉ်းများ သတ်မှတ်ပုံကိုလည်း လေ့လာပါမည်။
ဤအပိုင်းတွင် HTML ဖောင်များကို အသုံးပြု၍ ဝဘ်အက်ပ်တွင် login နှင့် registration ထည့်သွင်းပါမည်။ ဒေတာကို server API သို့ programmatically ပို့ပေးပုံနှင့် အသုံးပြုသူ input များအတွက် အခြေခံအတည်ပြုစည်းမျဉ်းများ သတ်မှတ်ပုံကိုလည်း လေ့လာပါမည်။
### ကြိုတင်လိုအပ်ချက်
ဒီသင်ခန်းစာအတွက် [HTML templates နှင့် routing](../1-template-route/README.md) ကိုပြီးစီးထားရမည်။ [Node.js](https://nodejs.org) ကို install လုပ်ပြီး [server API](../api/README.md) ကို locally run လုပ်ထားရမည်။ ဒါမှသာ အကောင့်ဖွင့်ရန် ဒေတာပို့နိုင်မည်။
သင်ခန်းစာအတွက် [HTML templates နှင့် routing](../1-template-route/README.md) ကို ပြီးစီးထားရန် လိုအပ်ပါသည်။ [Node.js](https://nodejs.org) ကို ထည့်သွင်းပြီး [server API](../api/README.md) ကို ဒေသတွင်းတွင် run လုပ်ထားရန်လည်း လိုအပ်ပါသည်။ ဒါမှသာ အကောင့်ဖန်တီးရန် ဒေတာပို့နိုင်မည်ဖြစ်သည်။
**သတိပြုရန်**
သင်မှာ တစ်ချိန်တည်းတွင် terminal နှစ်ခု run လုပ်ထားရမည်။
1. [HTML templates နှင့် routing](../1-template-route/README.md) သင်ခန်းစာတွင် တည်ဆောက်ထားသော အဓိကဘဏ်အက်ပ်အတွက်
2. အထက်တွင် setup လုပ်ထားသော [Bank APP server API](../api/README.md) အတွက်
သင်သည် အောက်တွင် ဖော်ပြထားသည့်အတိုင်း terminal နှစ်ခုကို တစ်ချိန်တည်းတွင် run လုပ်ထားရမည်။
1. [HTML templates နှင့် routing](../1-template-route/README.md) သင်ခန်းစာတွင် တည်ဆောက်ထားသော ဘဏ်အက်ပ်အတွက် terminal
2. အထက်တွင် ပြင်ဆင်ထားသော [Bank APP server API](../api/README.md) အတွက် terminal
Server နှစ်ခုလုံး run လုပ်ထားရမည်။ Port `3000` နှင့် port `5000` တွင် နားထောင်နေသောကြောင့် အားလုံးအဆင်ပြေပါမည်။
သင်ခန်းစာ၏ ကျန်ရှိသောအပိုင်းများကို ဆက်လက်လုပ်ဆောင်နိုင်ရန် server နှစ်ခုလုံးကို run လုပ်ထားရမည်။ ၎င်းတို့သည် port `3000` နှင့် port `5000`ို့တွင် နားထောင်နေသောကြောင့် အားလုံးအဆင်ပြေမည်ဖြစ်သည်။
Server run လုပ်နေမှုကို စစ်ဆေးရန် terminal တွင် အောက်ပါ command ကို run လုပ်ပါ
server သည် မှန်ကန်စွာ run လုပ်နေကြောင်း စစ်ဆေးရန် terminal တွင် အောက်ပါ command ကို run လုပ်ပါ:
```sh
curl http://localhost:5000/api
@ -41,29 +41,29 @@ curl http://localhost:5000/api
## Form နှင့် controls
`<form>` element သည် HTML document တစ်ခုတွင် အသုံးပြုသူ input နှင့် interactive controls ဖြင့် ဒေတာပေးပို့နိုင်သော အပိုင်းကို encapsulate လုပ်ပေးသည်။ Form အတွင်း အသုံးပြုနိုင်သော user interface (UI) controls များစွာရှိပြီး `<input>` နှင့် `<button>` element များသည် အများဆုံးအသုံးပြုသော control ဖြစ်သည်။
`<form>` element သည် အသုံးပြုသူမှ interactive controls များဖြင့် ဒေတာထည့်သွင်းပြီး ပေးပို့နိုင်သော HTML စာရွက်၏ အပိုင်းတစ်ခုကို encapsulate လုပ်ပေးသည်။ form အတွင်းတွင် အသုံးပြုနိုင်သော user interface (UI) controls များစွာရှိပြီး အများဆုံးအသုံးပြုသော control သည် `<input>` နှင့် `<button>` elements ဖြစ်သည်။
ဥပမာအားဖြင့် အသုံးပြုသူ၏ username ထည့်ရန် field တစ်ခုဖန်တီးလိုပါက အောက်ပါအတိုင်းရေးနိုင်သည်-
ဥပမာအားဖြင့် အသုံးပြုသူ၏ username ထည့်သွင်းရန် field တစ်ခုဖန်တီးလိုပါက အောက်ပါအတိုင်းရေးနိုင်သည်-
```html
<input id="username" name="username" type="text">
```
`name` attribute သည် form data ပေးပို့သောအခါ property name အဖြစ်အသုံးပြုမည်။ `id` attribute သည် `<label>` ကို form control နှင့် ဆက်စပ်ရန်အသုံးပြုသည်။
`name` attribute သည် form data ပေးပို့သောအခါ property name အဖြစ် အသုံးပြုမည်ဖြစ်သည်။ `id` attribute သည် `<label>` နှင့် form control ကို ဆက်စပ်ရန် အသုံးပြုသည်။
> [`<input>` types](https://developer.mozilla.org/docs/Web/HTML/Element/input) နှင့် [form controls](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) များ၏ စာရင်းကိုကြည့်ပြီး သင့် UI တည်ဆောက်ရာတွင် အသုံးပြုနိုင်သော native UI elements များကို သိရှိပါ။
> [`<input>` types](https://developer.mozilla.org/docs/Web/HTML/Element/input) နှင့် [form controls](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) များ၏ စာရင်းအားလုံးကို ကြည့်ရှု၍ သင့် UI တည်ဆောက်ရာတွင် အသုံးပြုနိုင်သော native UI elements များကို သိရှိနိုင်ပါသည်
`<input>` သည် [empty element](https://developer.mozilla.org/docs/Glossary/Empty_element) ဖြစ်ပြီး closing tag မထည့်သင့်ပါ။ Self-closing `<input/>` notation ကို အသုံးပြုနိုင်သော်လည်း မလိုအပ်ပါ။
`<input>` သည် [empty element](https://developer.mozilla.org/docs/Glossary/Empty_element) ဖြစ်ပြီး closing tag ကို ထည့်သွင်းမထားသင့်ပါ။ သို့သော် self-closing `<input/>` notation ကို အသုံးပြုနိုင်သော်လည်း မလိုအပ်ပါ။
Form အတွင်းရှိ `<button>` element သည် အနည်းငယ်ထူးခြားသည်။ `type` attribute ကို သတ်မှတ်မထားပါက button ကိုနှိပ်သောအခါ form data ကို server သို့ ပေးပို့မည်။ အောက်ပါ `type` values များရှိသည်-
form အတွင်းရှိ `<button>` element သည် အနည်းငယ်ထူးခြားသည်။ ၎င်း၏ `type` attribute ကို သတ်မှတ်မထားပါက button ကို နှိပ်သောအခါ form data ကို server သို့ အလိုအလျောက် ပေးပို့မည်ဖြစ်သည်။ type အမျိုးအစားများမှာ-
- `submit`: Form အတွင်း default ဖြစ်ပြီး button ကိုနှိပ်သောအခါ form submit action ကို trigger လုပ်သည်။
- `reset`: Form control များအားလုံးကို original value သို့ ပြန်လည်ပြောင်းသည်။
- `button`: Button ကိုနှိပ်သောအခါ default behavior မပေးပါ။ JavaScript အသုံးပြု၍ custom actions သတ်မှတ်နိုင်သည်။
- `submit`: `<form>` အတွင်း default ဖြစ်ပြီး button ကို နှိပ်သောအခါ form submit လုပ်ပေးသည်။
- `reset`: button ကို နှိပ်သောအခါ form control များအားလုံးကို မူလတန်ဖိုးများသို့ ပြန်လည်သတ်မှတ်ပေးသည်။
- `button`: button ကို နှိပ်သောအခါ default အပြုအမူမရှိပါ။ JavaScript ကို အသုံးပြု၍ custom actions များ သတ်မှတ်နိုင်သည်။
### လုပ်ဆောင်ရန်
`login` template တွင် form တစ်ခုထည့်ပါ။ *username* field နှင့် *Login* button လိုအပ်ပါမည်။
`login` template တွင် form တစ်ခုထည့်သွင်းပါ။ *username* field နှင့် *Login* button တစ်ခုလိုအပ်ပါမည်။
```html
<template id="login">
@ -79,14 +79,14 @@ Form အတွင်းရှိ `<button>` element သည် အနည်းင
</template>
```
အနည်းငယ်သေချာကြည့်ပါက `<label>` element ကိုလည်း ထည့်ထားသည်ကို တွေ့နိုင်ပါသည်။ `<label>` element များသည် username field ကဲ့သို့ UI controls များကို အမည်ပေးရန်အသုံးပြုသည်။ Labels သည် form များကို ဖတ်ရှုနိုင်စေရန် အရေးကြီးသည့်အပြင် အောက်ပါ အကျိုးကျေးဇူးများလည်းရှိသည်-
သေချာစွာကြည့်ပါက `<label>` element ကိုလည်း ထည့်သွင်းထားကြောင်း တွေ့နိုင်ပါသည်။ `<label>` elements များကို UI controls များ (ဥပမာ- username field) အတွက် အမည်ထည့်ရန် အသုံးပြုသည်။ Labels များသည် form များ၏ ဖတ်ရှုနိုင်မှုအတွက် အရေးကြီးသည့်အပြင် အောက်ပါအကျိုးကျေးဇူးများလည်း ပါရှိသည်-
- Label ကို form control နှင့် ဆက်စပ်ထားခြင်းအားဖြင့် assistive technologies (screen reader ကဲ့သို့) အသုံးပြုသူများအတွက် ထည့်ရန်အချက်အလက်ကို နားလည်စေရန် အထောက်အကူပြုသည်။
- Label ကို click လုပ်ခြင်းအားဖြင့် touch-screen devices တွင် input ကိုရောက်ရန် လွယ်ကူစေသည်။
- Label ကို form control နှင့် ဆက်စပ်ထားခြင်းဖြင့် assistive technologies (ဥပမာ- screen reader) အသုံးပြုသူများအတွက် ထည့်သွင်းရန်လိုအပ်သော ဒေတာကို နားလည်ရန် ကူညီပေးသည်။
- Label ကို နှိပ်ခြင်းဖြင့် ဆက်စပ်ထားသော input ကို တိုက်ရိုက် focus ထားနိုင်ပြီး touch-screen အခြေပြု devices များတွင်လည်း လွယ်ကူစေသည်။
> [က်ဘ်ပေါ်တွင် Accessibility](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) သည် အရေးကြီးသည့်အကြောင်းအရာဖြစ်ပြီး မျက်နှာမူမကျသောအကြောင်းအရာတစ်ခုဖြစ်သည်။ [semantic HTML elements](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) ကို သေချာအသုံးပြုပါက accessible content တည်ဆောက်ရန် မခက်ခဲပါ။ [Accessibility](https://developer.mozilla.org/docs/Web/Accessibility) အကြောင်းကို ဖတ်ရှုပြီး common mistakes မဖြစ်စေရန် developer တစ်ဦးအဖြစ် တာဝန်ယူပါ
> [ဘ်ပေါ်တွင် အနားယူမှု](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) သည် မျက်မမြင်သောအရေးကြီးသောအကြောင်းအရာတစ်ခုဖြစ်သည်။ [semantic HTML elements](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) ကို မှန်ကန်စွာ အသုံးပြုပါက accessible content ဖန်တီးရန် အခက်အခဲမရှိပါ။ [အနားယူမှု](https://developer.mozilla.org/docs/Web/Accessibility) အကြောင်းကို ဖတ်ရှု၍ အလွဲများကို ရှောင်ရှားပြီး တာဝန်ရှိ developer တစ်ဦးဖြစ်လာနိုင်ပါသည်
အခုတော့ registration အတွက် form တစ်ခုကို အပေါ်ရှိ form အောက်တွင် ထည့်ပါမည်-
ယခုအခါ login form အောက်တွင် registration အတွက် ဒုတိယ form တစ်ခု ထည့်သွင်းပါမည်-
```html
<hr/>
@ -104,152 +104,13 @@ Form အတွင်းရှိ `<button>` element သည် အနည်းင
</form>
```
`value` attribute ကို အသုံးပြု၍ input တစ်ခုအတွက် default value ကို သတ်မှတ်နိုင်သည်။
`balance` input သည် `number` type ဖြစ်သည်ကို သတိပြုပါ။ အခြား input များနှင့် မတူဘဲ ကြည့်ရုံဖြင့် ကွဲပြားမှုရှိပါသလား။ Try interacting with it.
`value` attribute ကို အသုံးပြု၍ input တစ်ခုအတွက် မူလတန်ဖိုးကို သတ်မှတ်နိုင်သည်။ `balance` input သည် `number` type ဖြစ်သည်ကိုလည်း သတိပြုပါ။ ၎င်းသည် အခြား input များနှင့် မတူဘဲ ပုံစံကွဲပြားနေပါသလား။ ၎င်းကို စမ်းသပ်ကြည့်ပါ။
✅ Keyboard ကိုသာ အသုံးပြု၍ form များကို navigate နှင့် interact လုပ်နိုင်ပါသလား? ဘယ်လိုလုပ်မလဲ?
## Server သို့ ဒေတာပေးပို့ခြင်း
UI ကို functional ဖြစ်ပြီးနောက် ဒေတာကို server သို့ ပေးပို့ရန် လိုအပ်သည်။ လက်ရှိ code ကို အသုံးပြု၍ *Login* သို့မဟုတ် *Register* button ကို click လုပ်ပါက ဘာဖြစ်မည်ကို စမ်းကြည့်ပါ။
Browser URL section တွင် ပြောင်းလဲမှုကို သတိထားမိပါသလား?
![Register button ကို click လုပ်ပြီးနောက် browser URL ပြောင်းလဲမှု screenshot](../../../../translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.my.png)
`<form>` ၏ default action သည် form data ကို current server URL သို့ [GET method](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3) ကို အသုံးပြု၍ URL တွင် data ကို append လုပ်ပေးသည်။ ဒီနည်းလမ်းတွင် အောက်ပါ အားနည်းချက်များရှိသည်-
- ပေးပို့သော data သည် အရွယ်အစားကန့်သတ်ထားသည် (2000 characters ခန့်)
- Data သည် URL တွင် တိုက်ရိုက်မြင်နိုင်သည် (password များအတွက် မသင့်တော်)
- File upload များနှင့် အလုပ်မလုပ်နိုင်
ဒါကြောင့် [POST method](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5) ကို အသုံးပြု၍ form data ကို HTTP request body တွင် server သို့ ပေးပို့နိုင်သည်။ အထက်ပါ အားနည်းချက်များမရှိပါ။
> POST သည် data ပေးပို့ရန် အများဆုံးအသုံးပြုသော method ဖြစ်သော်လည်း [အချို့သောအခြေအနေများတွင်](https://www.w3.org/2001/tag/doc/whenToUseGet.html) GET method ကို အသုံးပြုသင့်သည်။ ဥပမာအားဖြင့် search field တစ်ခုတည်ဆောက်သောအခါ။
### လုပ်ဆောင်ရန်
Registration form တွင် `action` နှင့် `method` properties ထည့်ပါ-
```html
<form id="registerForm" action="//localhost:5000/api/accounts" method="POST">
```
အခုတော့ သင့်နာမည်ဖြင့် အကောင့်အသစ်တစ်ခု register လုပ်ပါ။ *Register* button ကို click လုပ်ပြီးနောက် အောက်ပါအတိုင်းမြင်ရမည်-
![localhost:5000/api/accounts URL တွင် JSON string ပြသမှု browser screenshot](../../../../translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.my.png)
အဆင်ပြေပါက server သည် request ကို [JSON](https://www.json.org/json-en.html) response ဖြင့် ပြန်လည်ဖြေကြားပြီး ဖန်တီးထားသော account data ကို ပြသမည်။
✅ တူညီသောနာမည်ဖြင့် ထပ်မံ register လုပ်ပါ။ ဘာဖြစ်မည်?
## Page reload မရှိဘဲ data ပေးပို့ခြင်း
အခုလိုနည်းလမ်းတွင် အနည်းငယ်ပြဿနာရှိသည်ကို သတိထားမိပါသလား- form ကို submit လုပ်သောအခါ app မှထွက်ပြီး browser သည် server URL သို့ redirect လုပ်သည်။ Single-page application (SPA) တစ်ခုတည်ဆောက်နေသောကြောင့် page reload မရှိစေရန် ကြိုးစားနေပါသည်။
Page reload မရှိဘဲ data ကို server သို့ ပေးပို့ရန် JavaScript code ကို အသုံးပြုရမည်။ `<form>` element ၏ `action` property တွင် URL ထည့်ခြင်းအစား `javascript:` string ဖြင့် custom action ကို JavaScript code ဖြင့် ပြုလုပ်နိုင်သည်။ ဒါကို အသုံးပြုခြင်းအားဖြင့် browser အလိုအလျောက်လုပ်ဆောင်သောအလုပ်များကို ကိုယ်တိုင်လုပ်ဆောင်ရမည်-
- Form data ကို retrieve လုပ်ခြင်း
- Form data ကို သင့်တော်သော format သို့ convert နှင့် encode လုပ်ခြင်း
- HTTP request တစ်ခုဖန်တီးပြီး server သို့ ပေးပို့ခြင်း
### လုပ်ဆောင်ရန်
Registration form ၏ `action` ကို အောက်ပါအတိုင်း ပြောင်းပါ-
```html
<form id="registerForm" action="javascript:register()">
```
`app.js` ကိုဖွင့်ပြီး `register` ဟုခေါ်သော function အသစ်တစ်ခုထည့်ပါ-
```js
function register() {
const registerForm = document.getElementById('registerForm');
const formData = new FormData(registerForm);
const data = Object.fromEntries(formData);
const jsonData = JSON.stringify(data);
}
```
ဒီမှာ form element ကို `getElementById()` ဖြင့် retrieve လုပ်ပြီး [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) helper ကို အသုံးပြု၍ form control များမှ key/value pairs အနေနှင့် data ကို extract လုပ်သည်။ ထို့နောက် data ကို [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) ဖြင့် regular object သို့ ပြောင်းပြီး [JSON](https://www.json.org/json-en.html) သို့ serialize လုပ်သည်။ JSON သည် ဝက်ဘ်ပေါ်တွင် data ပေးပို့ရန် အများဆုံးအသုံးပြုသော format ဖြစ်သည်။
Data သည် server သို့ ပေးပို့ရန်အဆင်သင့်ဖြစ်ပါပြီ။ `createAccount` ဟုခေါ်သော function အသစ်တစ်ခုဖန်တီးပါ-
```js
async function createAccount(account) {
try {
const response = await fetch('//localhost:5000/api/accounts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: account
});
return await response.json();
} catch (error) {
return { error: error.message || 'Unknown error' };
}
}
```
ဒီ function ဘာလုပ်နေပါသလဲ? အရင်ဆုံး `async` keyword ကို သတိပြုပါ။ ဒီ function တွင် [**asynchronous**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) code ပါဝင်သည်။ `await` keyword ကို အသုံးပြုသောအခါ asynchronous code ကို run လုပ်ပြီး server response ကိုစောင့်နေသည်။
`fetch()` API ကို အသုံးပြု၍ JSON data ကို server သို့ ပေးပို့သည်။ ဒီ method သည် parameters ၂ ခုယူသည်-
- Server URL, ဒီမှာ `//localhost:5000/api/accounts` ကို ထည့်ပါ။
- Request settings, method ကို `POST` သတ်မှတ်ပြီး request body ကို provide လုပ်သည်။ JSON data ကို server သို့ ပေးပို့နေသောကြောင့် `Content-Type` header ကို `application/json` သတ်မှတ်ရန်လိုအပ်သည်။
Server သည် JSON ဖြင့် request ကို response ပြန်လည်ပေးမည်ဖြစ်သောကြောင့် `await response.json()` ကို အသုံးပြု၍ JSON content ကို parse လုပ်ပြီး resulting object ကို return ပြန်သည်။ ဒီ method သည် asynchronous ဖြစ်သောကြောင့် parsing အတွင်း error များကို catch လုပ်ရန် `await` keyword ကို အသုံးပြုပါ။
အခုတော့ `register` function တွင် `createAccount()` ကို call လုပ်ရန် code ထည့်ပါ-
```js
const result = await createAccount(jsonData);
```
`await` keyword ကို အသုံးပြုသောကြောင့် `register` function အရှေ့တွင် `async` keyword ထည့်ရန်လိုအပ်သည်-
```js
async function register() {
```
နောက်ဆုံးတွင် result ကို စစ်ဆေးရန် log များထည့်ပါ။ Final function သည် အောက်ပါအတိုင်းဖြစ်ရမည်-
```js
async function register() {
const registerForm = document.getElementById('registerForm');
const formData = new FormData(registerForm);
const jsonData = JSON.stringify(Object.fromEntries(formData));
const result = await createAccount(jsonData);
if (result.error) {
return console.log('An error occurred:', result.error);
}
console.log('Account created!', result);
}
```
အခုတော့ အတော်လေးရှည်လျားသွားခဲ့ပေမယ့် အဆင့်သို့ရောက်ပါပြီ! [browser developer tools](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) ကိုဖွင့်ပြီး အကောင့်အသစ် register လုပ်ပါ။ Web page တွင် ဘာမှမပြောင်းလဲသော်လည်း console တွင် message တစ်ခုပေါ်လာပြီး အားလုံးအဆင်ပြေကြောင်း အတည်ပြုပါမည်။
![Browser console တွင် log message ပြသမှု screenshot](../../../../translated_images/browser-console.efaf0b51aaaf67782a29e1a0bb32cc063f189b18e894eb5926e02f1abe864ec2.my.png)
✅ Data သည် server သို့ လုံခြုံစွာပေးပို့နေသည်ဟု သင်ထင်ပါသလား? တစ်စုံတစ်ဦးက request ကို ဖမ်းဆီးနိုင်ခဲ့လျှင် ဘာဖြစ်မည်? [HTTPS](https://en.wikipedia.org/wiki/HTTPS) အကြောင်းကို ဖတ်ရှုပြီး လုံခြုံစွာ data communication ပြုလုပ်ပုံကို သိရှိပါ။
## Data validation
Username မသတ်မှတ်ဘဲ အကောင့်အသစ် register လုပ်ကြည့်ပါက server သည် [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).) status code ဖြင့် error ပြန်လည်ပေးသည်ကို တွေ့ရမည်။
Server သို့ data ပေးပို့မီ [form data](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) ကို validate လုပ်ခြင်းသည် valid request ပေးပို့ရန်အတွက် အကောင်းဆုံးနည်းလမ်းဖြစ်သည်။ HTML5 form controls တွင် built-in validation ကို အောက်ပါ attributes များဖြင့် ပံ့ပိုးပေးသည်-
- `required`: Field ကို ဖြည့်ရန်လိုအပ်ပြီး form ကို submit မလုပ်နိုင်ပါ။
- `minlength` နှင့် `maxlength`: Text fields တွင် အနည်းဆုံးနှင့် အများဆုံး character အရေအတွက်ကို သတ်မှတ်သည်။
- `min` နှင့် `max`: Numerical field ၏ အနည်းဆုံးနှင့် အများဆုံးတန်ဖိုးကို သတ်မှတ်သည်။
- `type`: `number`, `email`, `file` ကဲ့သို့ data အမျိုးအစားကို သတ်မှတ်သည်။ ဒီ attribute သည် form control ၏ visual rendering ကိုလည်း ပြောင်းလဲနိုင်သည်။
- `pattern`: [Regular expression](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) pattern ကို သတ်မှတ်ပြီး data သည် valid ဖြစ်/မဖြစ် စစ်ဆေးသည်။
အကြံပြုချက် - သင့်ဖောင်ထိန်းချုပ်မှုများသည် သက်ဆိုင်မှုရှိမရှိပေါ်မူတည်၍ `:valid` နှင့် `:invalid` CSS pseudo-classes ကို အသုံးပြု၍ အပြင်အဆင်ကို စိတ်ကြိုက်ပြင်ဆင်နိုင်ပါသည်။
✅ သင်သည် keyboard သာ အသုံးပြု၍ form များကို navigation ပြုလုပ်ပြီး အပြုအမူများလုပ်ဆောင်နိုင်ပါသလား။ ၎င်းကို ဘယ်လိုလုပ်မလဲ?
အကြံပြုချက် - သင့်ဖောင်ထိန်းချုပ်မှုများသည် မှန်ကန်မှုရှိမရှိပေါ်မူတည်ပြီး ရုပ်ရည်ကို စိတ်ကြိုက်ပြင်ဆင်နိုင်ပါသည်။ `:valid` နှင့် `:invalid` CSS pseudo-classes ကို အသုံးပြုပါ။
### Task
အကောင့်အသစ်တစ်ခုဖန်တီးရန်အတွက် `username` နှင့် `currency` ဟာ မဖြစ်မနေဖြည့်ရမည့်အကွက်များဖြစ်ပြီး၊ အခြားအကွက်များက optional ဖြစ်ပါတယ်။ အကွက် label တွေမှာ `required` attribute နဲ့အတူစာသားထည့်ပြီး HTML form ကို update လုပ်ပါ။
အကောင့်အသစ်တစ်ခုကိုတည်ဆောက်ရန်အတွက် `username` နှင့် `currency` ဟာ မဖြစ်မနေလိုအပ်တဲ့ field နှစ်ခုဖြစ်ပြီး၊ အခြား field တွေက optional ဖြစ်ပါတယ်။ Form ရဲ့ HTML ကို update လုပ်ပြီး `required` attribute နဲ့ field label ထဲမှာ text ထည့်ပါ:
```html
<label for="user">Username (required)</label>
@ -259,9 +120,9 @@ Server သို့ data ပေးပို့မီ [form data](https://develop
<input id="currency" name="currency" type="text" value="$" required>
```
ဒီ server implementation မှာ field တွေရဲ့ maximum length ကို အတိအကျကန့်သတ်ထားတာမရှိပေမယ့်၊ user text entry အတွက် reasonable limits သတ်မှတ်ထားတာက အမြဲကောင်းတဲ့အလေ့အကျင့်ဖြစ်ပါတယ်။
ဒီ particular server implementation က field တွေရဲ့ အရှည်အပေါ်မှာ အကန့်အသတ်တွေ enforce မလုပ်ပေမယ့်၊ အသုံးပြုသူ text entry အတွက် reasonable limits တွေ သတ်မှတ်ထားတာက အမြဲကောင်းတဲ့အလေ့အထဖြစ်ပါတယ်။
Text field တွေမှာ `maxlength` attribute ထည့်ပါ
Text field တွေမှာ `maxlength` attribute ထည့်ပါ:
```html
<input id="user" name="user" type="text" maxlength="20" required>
@ -271,21 +132,21 @@ Text field တွေမှာ `maxlength` attribute ထည့်ပါ။
<input id="description" name="description" type="text" maxlength="100">
```
အခု *Register* ခလုတ်ကိုနှိပ်ပြီး validation rule တစ်ခုခုကိုမလိုက်နာတဲ့အကွက်ရှိရင်၊ အောက်ပါအတိုင်း error message တစ်ခုကိုတွေ့ရပါမယ်
အခု *Register* button ကိုနှိပ်ပြီး validation rule တွေကို မလိုက်နာတဲ့ field ရှိရင်၊ အောက်ပါအတိုင်း error message တစ်ခုကိုတွေ့ရပါမယ်:
![Screenshot showing the validation error when trying to submit the form](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.my.png)
ဒီလို validation ကို data ကို server ကိုပို့မီ *client-side* validation လို့ခေါ်ပါတယ်။ ဒါပေမယ့် data ကိုမပို့ဘဲနဲ့ အချို့သော check တွေကိုလုပ်ဖို့မဖြစ်နိုင်ပါဘူး။ ဥပမာအားဖြင့် username တူညီတဲ့အကောင့်တစ်ခုရှိပြီးမရှိဘူးဆိုတာကို server ကို request ပို့မသွားဘဲနဲ့ ဒီမှာစစ်ဆေးလို့မရပါဘူး။ Server မှာလုပ်ဆောင်တဲ့ အပို validation ကို **server-side** validation လို့ခေါ်ပါတယ်။
ဒီလို validation ကို data ကို server ကိုပို့မီ *client-side* validation လို့ခေါ်ပါတယ်။ ဒါပေမယ့် data ကိုမပို့ဘဲ အချို့သော check တွေကိုလုပ်နိုင်မှာမဟုတ်ပါဘူး။ ဥပမာအားဖြင့် username တူညီတဲ့အကောင့်တစ်ခုရှိပြီးသားလားဆိုတာကို server ကို request ပို့မသွားဘဲ ဒီမှာစစ်ဆေးလို့မရပါဘူး။ Server မှာเพิ่มเติมစစ်ဆေးမှုတွေကို **server-side** validation လို့ခေါ်ပါတယ်။
အများအားဖြင့် client-side validation နဲ့ server-side validation နှစ်ခုလုံးကို implement လုပ်ဖို့လိုအပ်ပါတယ်။ Client-side validation က user ကိုအမြန် feedback ပေးပြီး user experience ကိုတိုးတက်စေသလို၊ server-side validation က user data ကို sound နဲ့ safe ဖြစ်စေဖို့အရေးကြီးပါတယ်။
အများအားဖြင့် client-side validation နဲ့ server-side validation နှစ်ခုလုံးကို implement လုပ်ဖို့လိုအပ်ပါတယ်။ Client-side validation က အသုံးပြုသူကို အမြန် feedback ပေးပြီး user experience ကိုတိုးတက်စေသလို၊ server-side validation က အသုံးပြုသူ data ကို sound နဲ့ safe ဖြစ်စေဖို့အရေးကြီးပါတယ်။
---
## 🚀 Challenge
User ရှိပြီးသားဆိုရင် HTML မှာ error message တစ်ခုပြပါ။
အသုံးပြုသူရှိပြီးသားဆိုရင် HTML မှာ error message တစ်ခုပြပါ။
ဒီ login page ကို CSS styles နဲ့အတူအနည်းငယ်အလှဆင်ပြီးနောက်ဆုံးရလဒ်အဖြစ်ရနိုင်တဲ့ပုံစံက ဒီလိုဖြစ်နိုင်ပါတယ်။
ဒီ login page ကို CSS styles နဲ့အတူ အနည်းငယ်အလှဆင်ပြီးနောက်ပိုင်းရဲ့ နမူနာကို အောက်မှာကြည့်နိုင်ပါတယ်:
![Screenshot of the login page after adding CSS styles](../../../../translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.my.png)
@ -295,7 +156,7 @@ User ရှိပြီးသားဆိုရင် HTML မှာ error messa
## Review & Self Study
Developer တွေဟာ form တွေကိုဖန်တီးတဲ့အခါ validation strategy တွေကိုအလွန်ဖန်တီးမှုရှိစွာအသုံးပြုလာကြပါတယ်။ [CodePen](https://codepen.com) ကိုကြည့်ပြီး form flow အမျိုးမျိုးကိုလေ့လာပါ။ စိတ်ဝင်စားဖွယ်ရာနဲ့ အတုယူဖို့ကောင်းတဲ့ form တွေကိုရှာနိုင်ပါသလား?
Developer တွေဟာ form တည်ဆောက်မှုနဲ့ validation strategy တွေကို အလွန်ဖန်တီးမှုရှိစွာလုပ်ဆောင်နေကြပါတယ်။ [CodePen](https://codepen.com) ကိုကြည့်ပြီး form flow အမျိုးမျိုးကိုလေ့လာပါ။ စိတ်ဝင်စားဖွယ်ရာနဲ့ အားကျစရာ form တွေကိုရှာဖွေနိုင်ပါသလား?
## Assignment
@ -304,4 +165,4 @@ Developer တွေဟာ form တွေကိုဖန်တီးတဲ့အ
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှားမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရ အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားယူမှုမှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,29 +1,29 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f587e913e3f7c0b1c549a05dd74ee8e5",
"translation_date": "2025-08-27T22:00:28+00:00",
"original_hash": "89d0df9854ed020f155e94882ae88d4c",
"translation_date": "2025-08-28T18:29:16+00:00",
"source_file": "7-bank-project/3-data/README.md",
"language_code": "my"
}
-->
# ဘဏ်အက်ပ်တည်ဆောက်ခြင်း အပိုင်း ၃: ဒေတာရယူခြင်းနှင့် အသုံးပြုခြင်းနည်းလမ်းများ
## မိန့်ခွန်းမတိုင်မီမေးခွန်းများ
## မိန့်ခွန်းမတိုင်မီမေးခွန်း
[မိန့်ခွန်းမတိုင်မီမေးခွန်းများ](https://ff-quizzes.netlify.app/web/quiz/45)
[မိန့်ခွန်းမတိုင်မီမေးခွန်း](https://ff-quizzes.netlify.app/web/quiz/45)
### အကျဉ်းချုပ်
ဝက်ဘ်အက်ပ်တစ်ခုရဲ့ အဓိကအချက်က *ဒေတာ* ဖြစ်ပါတယ်။ ဒေတာက အမျိုးမျိုးသောပုံစံများရှိနိုင်ပေမယ့် အဓိကရည်ရွယ်ချက်က အသုံးပြုသူကို အချက်အလက်များကို ပြသပေးခြင်းဖြစ်ပါတယ်။ ဝက်ဘ်အက်ပ်များ ပိုမိုအကျိုးရှိပြီး ရှုပ်ထွေးလာတာနဲ့အမျှ အသုံးပြုသူက အချက်အလက်များကို ရယူခြင်းနှင့် အပြန်အလှန်ဆက်သွယ်ခြင်းနည်းလမ်းက ဝက်ဘ်တိုးတက်မှုရဲ့ အရေးကြီးသောအပိုင်းတစ်ခုဖြစ်လာပါတယ်။
ဝက်ဘ်အက်ပ်လျှောက်လွှာတိုင်း၏ အဓိကအချက်မှာ *ဒေတာ* ဖြစ်သည်။ ဒေတာသည် အမျိုးမျိုးသောပုံစံများရှိနိုင်သော်လည်း ၎င်း၏အဓိကရည်ရွယ်ချက်မှာ အသုံးပြုသူထံသို့ အချက်အလက်ကို ပြသခြင်းဖြစ်သည်။ ဝက်ဘ်အက်ပ်များသည် ပိုမိုအကျိုးရှိစွာနှင့် ရှုပ်ထွေးလာသည့်အခါတွင် အသုံးပြုသူသည် အချက်အလက်များကို ရယူခြင်းနှင့် အပြန်အလှန်ဆက်သွယ်ခြင်းနည်းလမ်းသည် ဝက်ဘ်ဖွံ့ဖြိုးတိုးတက်မှု၏ အရေးပါသောအပိုင်းတစ်ခုဖြစ်လာသည်။
ဒီသင်ခန်းစာမှာတော့ ဒေတာကို server မှ asynchronous နည်းလမ်းဖြင့် ရယူပြီး HTML ကို ပြန်လည် reload မလုပ်ဘဲ ဝက်ဘ်စာမျက်နှာပေါ်မှာ အချက်အလက်များကို ပြသပေးနည်းကို လေ့လာပါမယ်။
ဒီသင်ခန်းစာတွင်၊ server မှ ဒေတာကို asynchronous နည်းလမ်းဖြင့် ရယူပြီး HTML ကို ပြန်လည်တင်မထားဘဲ ဝက်ဘ်စာမျက်နှာပေါ်တွင် အချက်အလက်ကို ပြသရန် ဒီဒေတာကို အသုံးပြုနည်းကို လေ့လာပါမည်။
### ကြိုတင်လိုအပ်ချက်
ဒီသင်ခန်းစာအတွက် [Login နှင့် Registration Form](../2-forms/README.md) ကို တည်ဆောက်ပြီးသားဖြစ်ရပါမယ်။ [Node.js](https://nodejs.org) ကို install လုပ်ပြီး [server API](../api/README.md) ကို locally run လုပ်ထားဖို့လည်း လိုအပ်ပါတယ်။ ဒါမှ account data ကို ရယူနိုင်ပါမယ်။
ဒီသင်ခန်းစာအတွက် [Login နှင့် Registration Form](../2-forms/README.md) ကို တည်ဆောက်ပြီးဖြစ်ရမည်။ [Node.js](https://nodejs.org) ကို install လုပ်ပြီး [server API](../api/README.md) ကို locally run လုပ်ထားရမည်။ ဒါမှ account data ကို ရယူနိုင်မည်။
server အလုပ်လုပ်နေမှုကို terminal မှာ အောက်ပါ command ကို run လုပ်ပြီး စစ်ဆေးနိုင်ပါတယ်။
server သေချာစွာ run လုပ်နေသည်ကို terminal မှာ အောက်ပါ command ကို run လုပ်ပြီး စမ်းသပ်နိုင်သည်-
```sh
curl http://localhost:5000/api
@ -34,21 +34,21 @@ curl http://localhost:5000/api
## AJAX နှင့် ဒေတာရယူခြင်း
ရိုးရာဝက်ဘ်ဆိုဒ်များမှာ အသုံးပြုသူ link ကိုရွေးချယ်ခြင်း သို့မဟုတ် form ကို submit လုပ်ခြင်းဖြင့် ပြသထားသော content ကို update လုပ်ပြီး HTML စာမျက်နှာကို ပြန်လည် reload လုပ်ပါတယ်။ ဒေတာအသစ်များကို load လုပ်ဖို့လိုအပ်တဲ့အခါမှာ ဝက်ဘ် server က HTML စာမျက်နှာအသစ်တစ်ခုကို ပြန်ပေးပို့ပြီး browser မှ process လုပ်ရပါတယ်။ ဒီလုပ်ငန်းစဉ်က အသုံးပြုသူရဲ့ လက်ရှိလုပ်ဆောင်မှုကို ခေတ္တရပ်တန့်စေပြီး reload အတွင်းမှာ interaction များကို ကန့်သတ်စေပါတယ်။ ဒီ workflow ကို *Multi-Page Application* (MPA) လို့ခေါ်ပါတယ်။
ရိုးရာဝက်ဘ်ဆိုဒ်များသည် အသုံးပြုသူ link ကိုရွေးချယ်ခြင်း သို့မဟုတ် form ကို submit လုပ်ခြင်းဖြင့် ပြသထားသော content ကို update လုပ်သည်။ ဒါကို HTML စာမျက်နှာကို ပြန်လည်တင်ခြင်းဖြင့် ပြုလုပ်သည်။ ဒေတာအသစ်တစ်ခု load လုပ်ရန်လိုအပ်သည့်အခါတွင် ဝက်ဘ် server သည် HTML စာမျက်နှာအသစ်တစ်ခုကို ပြန်ပေးသည်။ ဒါကို browser မှ process လုပ်ရမည်ဖြစ်ပြီး အသုံးပြုသူ၏ လက်ရှိလုပ်ဆောင်မှုကို ခေတ္တရပ်တန့်စေပြီး reload အတွင်းတွင် အပြန်အလှန်ဆက်သွယ်မှုများကို ကန့်သတ်သည်။ ဒီ workflow ကို *Multi-Page Application* (MPA) ဟုခေါ်သည်။
![Multi-page application မှာ update workflow](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.my.png)
![Multi-page application တွင် update workflow](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.my.png)
ဝက်ဘ်အက်ပ်များ ပိုမိုရှုပ်ထွေးလာတာနဲ့အမျှ [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) ဆိုတဲ့နည်းလမ်းအသစ်တစ်ခု ပေါ်ထွက်လာပါတယ်။ ဒီနည်းလမ်းက JavaScript ကို အသုံးပြုပြီး server မှ ဒေတာကို asynchronous နည်းလမ်းဖြင့် ပို့ပေးခြင်းနှင့် ရယူခြင်းကို HTML စာမျက်နှာကို reload မလုပ်ဘဲ လုပ်ဆောင်နိုင်စေပါတယ်။ ဒေတာအသစ်ကို server မှရရှိတဲ့အခါ JavaScript ကို အသုံးပြုပြီး HTML စာမျက်နှာကို [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API ဖြင့် update လုပ်နိုင်ပါတယ်။ အချိန်ကြာလာတာနဲ့အမျှ ဒီနည်းလမ်းက [*Single-Page Application* (SPA)](https://en.wikipedia.org/wiki/Single-page_application) လို့ခေါ်တဲ့နည်းလမ်းအဖြစ် တိုးတက်လာပါတယ်။
ဝက်ဘ်လျှောက်လွှာများ ပိုမိုရှုပ်ထွေးလာသည့်အခါတွင် [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) ဟုခေါ်သောနည်းလမ်းအသစ်တစ်ခု ပေါ်ထွက်လာသည်။ ဒီနည်းလမ်းသည် JavaScript ကို အသုံးပြု၍ server မှ ဒေတာကို asynchronous နည်းလမ်းဖြင့် ပို့ခြင်းနှင့် ရယူခြင်းကို ခွင့်ပြုသည်။ HTML စာမျက်နှာကို ပြန်လည်တင်ရန်မလိုအပ်ဘဲ update လုပ်ခြင်းများကို ပိုမိုလျင်မြန်စေပြီး အသုံးပြုသူအတွေ့အကြုံကို ပိုမိုချောမွေ့စေသည်။ Server မှ ဒေတာအသစ်ရရှိလာသောအခါ၊ လက်ရှိ HTML စာမျက်နှာကို JavaScript ကို အသုံးပြု၍ [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API ဖြင့် update လုပ်နိုင်သည်။ အချိန်ကြာလာသည်နှင့်အမျှ ဒီနည်းလမ်းသည် [*Single-Page Application* (SPA)](https://en.wikipedia.org/wiki/Single-page_application) ဟုခေါ်သောအဆင့်သို့ တိုးတက်လာသည်။
![Single-page application မှာ update workflow](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.my.png)
![Single-page application တွင် update workflow](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.my.png)
AJAX ကို ပထမဆုံးမိတ်ဆက်ခဲ့တဲ့အခါ asynchronous ဒေတာရယူဖို့ [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest) API တစ်ခုသာ ရရှိနိုင်ခဲ့ပါတယ်။ ဒါပေမယ့် အခေတ်မီ browser များမှာ promises ကို အသုံးပြုပြီး JSON ဒေတာကို ပိုမိုလွယ်ကူစွာ manipulate လုပ်နိုင်တဲ့ [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API) ကို support လုပ်လာပါတယ်။
AJAX ကို ပထမဆုံးမိတ်ဆက်ခဲ့သောအခါတွင် asynchronous နည်းလမ်းဖြင့် ဒေတာရယူရန်ရရှိနိုင်သော API တစ်ခုတည်းမှာ [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest) ဖြစ်သည်။ သို့သော် modern browser များသည် promises ကို အသုံးပြုပြီး JSON ဒေတာကို ပိုမိုကောင်းမွန်စွာ manipulate လုပ်နိုင်သည့် [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API) ကိုလည်း support လုပ်သည်။
> အခေတ်မီ browser များအားလုံးက `Fetch API` ကို support လုပ်ပေမယ့် သင့်ဝက်ဘ်အက်ပ်ကို အဟောင်း browser များမှာလည်း အလုပ်လုပ်စေချင်ရင် [caniuse.com](https://caniuse.com/fetch) မှာ compatibility table ကို စစ်ဆေးဖို့ အမြဲကောင်းပါတယ်။
> Modern browser အားလုံးသည် `Fetch API` ကို support လုပ်သော်လည်း သင့်ဝက်ဘ်လျှောက်လွှာကို legacy သို့မဟုတ် အဟောင်း browser များတွင် အသုံးပြုနိုင်စေရန်လိုအပ်ပါက [caniuse.com](https://caniuse.com/fetch) တွင် compatibility table ကိုစစ်ဆေးရန် အမြဲကောင်းသည်။
### လုပ်ဆောင်ရန်
[အရင်သင်ခန်းစာ](../2-forms/README.md) မှာ account တစ်ခုကို ဖန်တီးဖို့ registration form ကို implement လုပ်ထားပါတယ်။ အခုတော့ ရှိပြီးသား account ကို အသုံးပြုပြီး login လုပ်ဖို့ code ကို ထည့်သွင်းပါမယ်။ `app.js` ဖိုင်ကို ဖွင့်ပြီး `login` function အသစ်တစ်ခုကို ထည့်ပါ:
[ယခင်သင်ခန်းစာ](../2-forms/README.md) တွင် account တစ်ခုဖန်တီးရန် registration form ကို implement လုပ်ခဲ့သည်။ အခုတော့ ရှိပြီးသား account ကို အသုံးပြု၍ login လုပ်ပြီး ဒေတာကို fetch လုပ်ရန် code ကို ထည့်သွင်းပါမည်။ `app.js` ဖိုင်ကိုဖွင့်ပြီး `login` function အသစ်တစ်ခုထည့်ပါ-
```js
async function login() {
@ -57,9 +57,9 @@ async function login() {
}
```
ဒီမှာတော့ form element ကို `getElementById()` ဖြင့် ရယူပြီး `loginForm.user.value` ဖြင့် input မှ username ကို ရယူပါတယ်။ HTML မှာ `name` attribute ဖြင့် သတ်မှတ်ထားသော form control တစ်ခုစီကို form ရဲ့ property အနေနဲ့ access လုပ်နိုင်ပါတယ်။
ဒီမှာ `getElementById()` ကို အသုံးပြု၍ form element ကို retrieve လုပ်ပြီး `loginForm.user.value` ဖြင့် input မှ username ကိုရယူသည်။ HTML တွင် `name` attribute ဖြင့် သတ်မှတ်ထားသော form control တစ်ခုစီကို form ၏ property အဖြစ် access လုပ်နိုင်သည်။
Registration အတွက် လုပ်ခဲ့သလိုပဲ server request ကို လုပ်ဆောင်ဖို့ function အသစ်တစ်ခုကို ဖန်တီးပါမယ်၊ ဒါပေမယ့် ဒီတစ်ခါမှာတော့ account data ကို ရယူဖို့ဖြစ်ပါတယ်:
Registration အတွက် ပြုလုပ်ခဲ့သည့်နည်းလမ်းနှင့်တူညီစွာ၊ server request ကို perform လုပ်ရန် function အသစ်တစ်ခုဖန်တီးပါမည်။ ဒါပေမယ့် ဒီတစ်ခါမှာ account data ကို retrieve လုပ်ရန်ဖြစ်သည်-
```js
async function getAccount(user) {
@ -72,11 +72,11 @@ async function getAccount(user) {
}
```
ဒီမှာတော့ server မှ ဒေတာကို asynchronous နည်းလမ်းဖြင့် request လုပ်ဖို့ `fetch` API ကို အသုံးပြုပါတယ်။ ဒေတာကို query လုပ်ဖို့ URL ကိုသာလိုအပ်ပြီး အပို parameters မလိုအပ်ပါဘူး။ `fetch` က default အနေဖြင့် [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP request ကို ဖန်တီးပေးပြီး ဒီမှာလိုအပ်တဲ့အရာဖြစ်ပါတယ်။
ဒီမှာ `fetch` API ကို အသုံးပြု၍ server မှ ဒေတာကို asynchronous နည်းလမ်းဖြင့် request လုပ်သည်။ ဒါပေမယ့် URL ကို call လုပ်ရန်အပြင် အခြား parameter မလိုအပ်ပါ။ ဒါကြောင့် `fetch` သည် default အနေဖြင့် [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP request ကိုဖန်တီးသည်။
`encodeURIComponent()` ဆိုတာ URL အတွက် special characters များကို escape လုပ်ပေးတဲ့ function ဖြစ်ပါတယ်။ ဒီ function ကို မခေါ်ဘဲ `user` value ကို URL မှာ တိုက်ရိုက်အသုံးပြုရင် ဘယ်လိုပြဿနာများဖြစ်နိုင်မလဲ?
`encodeURIComponent()` သည် URL အတွက် special characters များကို escape လုပ်သည့် function ဖြစ်သည်။ ဒီ function ကို မခေါ်ဘဲ `user` value ကို URL တွင်တိုက်ရိုက်အသုံးပြုပါက ဘယ်လိုပြဿနာများဖြစ်နိုင်မလဲ?
အခုတော့ `login` function ကို `getAccount` ကို အသုံးပြုဖို့ update လုပ်ပါမယ်:
အခုတော့ `login` function ကို update လုပ်ပြီး `getAccount` ကိုအသုံးပြုပါမည်-
```js
async function login() {
@ -93,50 +93,50 @@ async function login() {
}
```
ပထမဆုံး `getAccount` က asynchronous function ဖြစ်တဲ့အတွက် server result ကို စောင့်ဖို့ `await` keyword ကို အသုံးပြုရပါတယ်။ Server request တစ်ခုစီမှာ error ဖြစ်နိုင်မှုကို handle လုပ်ဖို့လိုအပ်ပါတယ်။ အခုတော့ error ကို log message အနေနဲ့သာ ပြသထားပြီး နောက်ပိုင်းမှာ ပြန်လည် handle လုပ်ပါမယ်။
ပထမဦးဆုံး `getAccount` သည် asynchronous function ဖြစ်သောကြောင့် server result ကိုစောင့်ရန် `await` keyword ကို အသုံးပြုရမည်။ Server request တစ်ခုစီတွင် error case များကို handle လုပ်ရန်လိုအပ်သည်။ အခုအချိန်မှာ log message တစ်ခုထည့်ပြီး error ကိုပြသရန်သာလုပ်ပါမည်။ နောက်ပိုင်းမှာ ပြန်လည်ဆန်းစစ်ပါမည်။
ထို့နောက် dashboard information ကို ပြသဖို့ data ကို တစ်နေရာမှာ သိမ်းဆည်းဖို့လိုအပ်ပါတယ်။ `account` variable မရှိသေးတဲ့အတွက် ဖိုင်ရဲ့ အပေါ်ဆုံးမှာ global variable တစ်ခုကို ဖန်တီးပါမယ်:
ထို့နောက် dashboard information ကို display လုပ်ရန် later တွင်အသုံးပြုနိုင်ရန် ဒေတာကို တစ်နေရာမှာ သိမ်းဆည်းရမည်။ `account` variable မရှိသေးသောကြောင့် ဖိုင်၏ထိပ်ဆုံးတွင် global variable တစ်ခုဖန်တီးပါမည်-
```js
let account = null;
```
အသုံးပြုသူ data ကို variable မှာ သိမ်းဆည်းပြီးနောက် *login* စာမျက်နှာမှ *dashboard* ကို `navigate()` function ကို အသုံးပြုပြီး ရွှေ့နိုင်ပါတယ်။
အသုံးပြုသူဒေတာကို variable တစ်ခုထဲသို့ သိမ်းဆည်းပြီးနောက် *login* စာမျက်နှာမှ *dashboard* သို့ `navigate()` function ကိုအသုံးပြု၍ ရွှေ့နိုင်သည်။
နောက်ဆုံးမှာ login form ကို submit လုပ်တဲ့အခါ `login` function ကို ခေါ်ဖို့ HTML ကို ပြောင်းလဲပါ:
နောက်ဆုံးတွင် login form ကို submit လုပ်သောအခါ `login` function ကိုခေါ်ရန် HTML ကိုပြောင်းလဲပါ-
```html
<form id="loginForm" action="javascript:login()">
```
အသစ် account တစ်ခုကို register လုပ်ပြီး အဲဒီ account ကို အသုံးပြုပြီး login လုပ်ကြည့်ကာ အားလုံးအလုပ်လုပ်နေမှုကို စမ်းသပ်ပါ။
အသစ် account တစ်ခု register လုပ်ပြီး အဲဒီ account ကိုအသုံးပြု၍ login လုပ်ရန် စမ်းသပ်ပါ။
နောက်ပိုင်းအပိုင်းကို ဆက်မလုပ်ခင် `register` function ကို အောက်ပါ code ကို function ရဲ့ အဆုံးမှာ ထည့်သွင်းပြီး ပြည့်စုံစေပါ:
နောက်ပိုင်းအပိုင်းသို့ ရွှေ့မတိုင်မီ `register` function ကို အောက်ပါ code ကို function ၏အဆုံးတွင်ထည့်သွင်းခြင်းဖြင့် ပြည့်စုံစေပါ-
```js
account = result;
navigate('/dashboard');
```
✅ သင်သိပါသလား? Default အနေဖြင့် server API များကို သင်ကြည့်နေတဲ့ web page ရဲ့ *same domain နှင့် port* မှသာ ခေါ်နိုင်ပါတယ်။ ဒါက browser များက အကောင်အထည်ဖော်ထားတဲ့ security mechanism ဖြစ်ပါတယ်။ ဒါပေမယ့် သင့် web app က `localhost:3000` မှာ run လုပ်နေပြီး server API က `localhost:5000` မှာ run လုပ်နေတဲ့အခါ ဘာကြောင့် အလုပ်လုပ်နေရတာလဲ? [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) ဆိုတဲ့နည်းလမ်းကို အသုံးပြုပြီး server response မှာ specific domains အတွက် exception ကို ခွင့်ပြုတဲ့ headers များကို ထည့်သွင်းခြင်းဖြင့် cross-origin HTTP requests ကို လုပ်ဆောင်နိုင်ပါတယ်။
✅ သင်သိပါသလား၊ default အနေဖြင့် server API များကို သင်ကြည့်နေသောဝက်ဘ်စာမျက်နှာ၏ *same domain နှင့် port* မှသာ call လုပ်နိုင်သည်။ ဒါဟာ browser များက အကောင်အထည်ဖော်ထားသော security mechanism ဖြစ်သည်။ ဒါပေမယ့် သင့်ဝက်ဘ်အက်ပ်သည် `localhost:3000` တွင် run လုပ်နေပြီး server API သည် `localhost:5000` တွင် run လုပ်နေသည်၊ ဒါဟာ ဘာကြောင့်အလုပ်လုပ်နေရသလဲ? [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) ဟုခေါ်သောနည်းလမ်းကို အသုံးပြု၍ server သည် response တွင် special headers များထည့်သွင်းခြင်းဖြင့် specific domains များအတွက် exception များကို ခွင့်ပြုနိုင်သည်။
> API များအကြောင်းပိုမိုလေ့လာရန် ဒီ [သင်ခန်းစာ](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon) ကို လေ့လာပါ။
> API များအကြောင်းပိုမိုလေ့လာရန် ဒီ [သင်ခန်းစာ](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon) ကိုယူပါ
## HTML ကို update လုပ်ပြီး ဒေတာကို ပြသခြင်း
## HTML ကို update လုပ်၍ ဒေတာကို display လုပ်ရန်
အခုတော့ အသုံးပြုသူ data ရရှိပြီးသားဖြစ်တဲ့အတွက် HTML ကို update လုပ်ပြီး ဒေတာကို ပြသဖို့လိုအပ်ပါတယ်။ DOM မှ element ကို ရယူဖို့ `document.getElementById()` ကို အသုံးပြုနည်းကို ရှိပြီးသားဖြစ်ပါတယ်။ Base element ရရှိပြီးနောက် အောက်ပါ API များကို အသုံးပြုကာ element ကို ပြောင်းလဲခြင်း သို့မဟုတ် child elements အသစ်များကို ထည့်သွင်းနိုင်ပါတယ်:
အခုတော့ အသုံးပြုသူဒေတာကို ရရှိပြီးဖြစ်သည်။ HTML ကို update လုပ်၍ display လုပ်ရန် လိုအပ်သည်။ `document.getElementById()` ကိုအသုံးပြု၍ DOM မှ element ကို retrieve လုပ်နည်းကို ကျွန်တော်တို့သိပြီးဖြစ်သည်။ base element ရရှိပြီးနောက် အောက်ပါ API များကို အသုံးပြု၍ element ကိုပြောင်းလဲခြင်း သို့မဟုတ် child elements များထည့်သွင်းနိုင်သည်-
- [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) property ကို အသုံးပြုကာ element ရဲ့ text ကို ပြောင်းလဲနိုင်ပါတယ်။ ဒီ value ကို ပြောင်းလဲတဲ့အခါ element ရဲ့ children များအားလုံးကို ဖျက်ပြီး ပေးထားသော text ဖြင့် အစားထိုးပေးပါတယ်။ အဲဒီအတွက် element ရဲ့ children များအားလုံးကို ဖျက်ဖို့ empty string `''` ကို assign လုပ်ခြင်းကလည်း အကျိုးရှိပါတယ်။
- [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) property ကိုအသုံးပြု၍ element ၏ text ကိုပြောင်းလဲနိုင်သည်။ ဒီ value ကိုပြောင်းလဲခြင်းသည် element ၏ children များအားလုံးကို (ရှိပါက) ဖယ်ရှားပြီး ပေးထားသော text ဖြင့်အစားထိုးသည်။ ထို့ကြောင့် empty string `''` ကို assign လုပ်ခြင်းဖြင့် element ၏ children များအားလုံးကို ဖယ်ရှားရန်လည်း အကျိုးရှိသောနည်းလမ်းဖြစ်သည်။
- [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) နှင့် [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) method ကို အသုံးပြုကာ child elements အသစ်များကို ဖန်တီးပြီး attach လုပ်နိုင်ပါတယ်။
- [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) နှင့် [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) method ကိုအသုံးပြု၍ အသစ်သော child elements များကို ဖန်တီးပြီး attach လုပ်နိုင်သည်။
✅ [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) property ကို အသုံးပြုကာ element ရဲ့ HTML contents ကို ပြောင်းလဲနိုင်ပေမယ့် [cross-site scripting (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) attacks အတွက် အန္တရာယ်ရှိတဲ့အတွက် ဒီ method ကို ရှောင်ရှားသင့်ပါတယ်။
✅ [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) property ကိုအသုံးပြု၍ element ၏ HTML contents ကိုလည်းပြောင်းလဲနိုင်သည်။ သို့သော် [cross-site scripting (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) တိုက်ခိုက်မှုများအတွက် အန္တရာယ်ရှိသောကြောင့် ဒီနည်းလမ်းကို ရှောင်ရှားသင့်သည်။
### လုပ်ဆောင်ရန်
*login* စာမျက်နှာမှာ dashboard screen ကို ရှေ့ဆက်မလုပ်ခင် တစ်ခုခုလုပ်ဆောင်ဖို့လိုအပ်ပါတယ်။ လက်ရှိမှာ username မရှိတဲ့အကောင့်ကို login လုပ်ကြည့်ရင် console မှာ message တစ်ခုပြသပေမယ့် အသုံးပြုသူအတွက် ဘာမှမပြောင်းလဲဘဲ ဘာဖြစ်နေလဲဆိုတာမသိနိုင်ပါဘူး
*login* စာမျက်နှာတွင် dashboard screen သို့ ရွှေ့မတိုင်မီ လုပ်ဆောင်ရန်အရာတစ်ခုရှိသည်။ လက်ရှိတွင် မရှိသော username ဖြင့် login လုပ်ရန်ကြိုးစားပါက console တွင် message တစ်ခုပြသသော်လည်း သာမန်အသုံးပြုသူအတွက် ဘာမှမပြောင်းလဲဘဲ ဘာဖြစ်နေလဲဆိုတာမသိနိုင်ပါ။
login `<button>` ရဲ့ အနီးမှာ error message ကို ပြသနိုင်ဖို့ placeholder element တစ်ခုကို ထည့်သွင်းပါမယ်:
login `<button>` မတိုင်မီ error message ကို display လုပ်ရန် placeholder element တစ်ခုထည့်ပါမည်-
```html
...
@ -145,9 +145,9 @@ login `<button>` ရဲ့ အနီးမှာ error message ကို ပြ
...
```
ဒီ `<div>` element က empty ဖြစ်တဲ့အတွက် content ထည့်သွင်းမချင်း screen ပေါ်မှာ ဘာမှမပြသပါဘူး။ JavaScript ဖြင့် retrieve လုပ်ဖို့ `id` ကိုလည်း ထည့်သွင်းထားပါတယ်။
ဒီ `<div>` element သည် empty ဖြစ်သည်။ screen ပေါ်တွင် content ထည့်သွင်းမချင်း ဘာမှမပြသပါ။ JavaScript ဖြင့် retrieve လုပ်ရန် `id` ကိုလည်းပေးထားသည်။
`app.js` ဖိုင်ကို ပြန်သွားပြီး `updateElement` ဆိုတဲ့ helper function အသစ်တစ်ခုကို ဖန်တီးပါ:
`app.js` ဖိုင်သို့ပြန်သွားပြီး `updateElement` ဟုခေါ်သော helper function အသစ်တစ်ခုဖန်တီးပါ-
```js
function updateElement(id, text) {
@ -156,7 +156,7 @@ function updateElement(id, text) {
}
```
ဒီ function က ရိုးရှင်းပါတယ်: element *id* နှင့် *text* ကိုပေးပြီး matching `id` ရဲ့ DOM element ရဲ့ text content ကို update လုပ်ပေးပါတယ်။ ဒီ method ကို `login` function ရဲ့ error message အစားအသုံးပြုပါမယ်:
ဒီ function သည် ရိုးရှင်းပြီး element *id* နှင့် *text* ကိုပေးထားသော DOM element ၏ text content ကို update လုပ်သည်။ `login` function တွင် error message အစား ဒီ method ကိုအသုံးပြုပါ-
```js
if (data.error) {
@ -164,23 +164,23 @@ if (data.error) {
}
```
အခုတော့ invalid account ကို login လုပ်ကြည့်ရင် အောက်ပါအတိုင်း message တစ်ခုကို မြင်ရပါမယ်:
အခုတော့ မမှန်သော account ဖြင့် login လုပ်ရန်ကြိုးစားပါက အောက်ပါအတိုင်း message တစ်ခုကိုတွေ့ရမည်-
![Login error message ပြသနေမှုကို ပြသထားသော screenshot](../../../../translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.my.png)
![Login အတွင်း error message ပြသထားသော screenshot](../../../../translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.my.png)
အခုတော့ error text ကို visually ပြသနိုင်ပါပြီ၊ ဒါပေမယ့် screen reader ဖြင့် စမ်းကြည့်ရင် ဘာမှမကြားရပါဘူး။ Screen reader များအတွက် dynamically ထည့်သွင်းထားသော text ကို announce လုပ်နိုင်ဖို့ [Live Region](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) ကို အသုံးပြုရပါမယ်။ ဒီမှာတော့ alert ဆိုတဲ့ live region အမျိုးအစားကို အသုံးပြုပါမယ်:
အခုတော့ error text ကို visually ပြသထားပြီး screen reader ဖြင့်စမ်းသပ်ပါက ဘာမှမကြားရပါ။ Screen reader များက dynamic text ကို page တွင်ထည့်သွင်းသောအခါ အကြောင်းကြားရန် [Live Region](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) ကိုအသုံးပြုရမည်။ ဒီမှာ alert ဟုခေါ်သော live region အမျိုးအစားကိုအသုံးပြုပါမည်-
```html
<div id="loginError" role="alert"></div>
```
`register` function errors အတွက်လည်း အတူတူအကျိုးသက်ရောက်မှုကို implement လုပ်ပါ (HTML ကို update လုပ်ဖို့မမေ့ပါနဲ့)။
`register` function errors အတွက်လည်း အတူတူသောအပြုအမူကို implement လုပ်ပါ (HTML ကို update လုပ်ရန်မမေ့ပါနှင့်)။
## Dashboard မှာ အချက်အလက်များကို ပြသခြင်း
## Dashboard တွင် အချက်အလက်ကို display လုပ်ရန်
အခုလို techniques များကို အသုံးပြုကာ dashboard စာမျက်နှာမှာ account information ကို ပြသပါမယ်။
ကျွန်တော်တို့လေ့လာခဲ့သောနည်းလမ်းများကိုအသုံးပြု၍ dashboard စာမျက်နှာတွင် account information ကို display လုပ်ပါမည်။
Server မှရရှိသော account object က အောက်ပါအတိုင်းဖြစ်ပါတယ်:
Server မှရရှိသော account object သည် အောက်ပါအတိုင်းဖြစ်သည်-
```json
{
@ -196,11 +196,11 @@ Server မှရရှိသော account object က အောက်ပါအ
}
```
> မှတ်ချက်: သင့်အလုပ်ကို ပိုမိုလွယ်ကူစေရန် data ဖြင့် ပြည့်စုံထားသော `test` account ကို အသုံးပြုနိုင်ပါတယ်။
> မှတ်ချက်- သင့်အလုပ်ကို ပိုမိုလွယ်ကူစေရန် data ဖြင့်ပြီးစီးထားသော `test` account ကိုအသုံးပြုနိုင်သည်။
### လုပ်ဆောင်ရန်
HTML မှာ "Balance" section ကို placeholder elements ထည့်သွင်းဖို့အတွက် အစားထိုးပါ:
HTML တွင် "Balance" အပိုင်းကို placeholder elements ထည့်သွင်းရန်အစားပြောင်းလဲပါ-
```html
<section>
@ -208,15 +208,15 @@ HTML မှာ "Balance" section ကို placeholder elements ထည့်သ
</section>
```
Account description ကို ပြသဖို့အတွက် အောက်မှာ section အသစ်တစ်ခုကို ထည့်သွင်းပါ:
Account description ကို display လုပ်ရန်အောက်တွင် section အသစ်တစ်ခုထည့်ပါ-
```html
<h2 id="description"></h2>
```
✅ Account description က content ရဲ့ title အဖြစ် လုပ်ဆောင်တာဖြစ်တဲ့အတွက် semantically heading အနေနဲ့ markup လုပ်ထားပါတယ်။ [Heading structure](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) ရဲ့ အရေးပါမှုကို လေ့လာပြီး စာမျက်နှာကို အနက်နက်ကြည့်ကာ heading အဖြစ်သင့်တော်သောအရာများကို သတ်မှတ်ပါ။
✅ Account description သည် content အောက်တွင် title အဖြစ်လုပ်ဆောင်သောကြောင့် semantically heading အဖြစ် mark up လုပ်ထားသည်။ Accessibility အတွက် [heading structure](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) အရေးပါမှုကိုပိုမိုလေ့လာပြီး page ကို critical အမြင်ဖြင့်ကြည့်ပါ။
နောက်ဆုံးမှာ `app.js` မှာ placeholder ကို ဖြည့်ဖို့ function အသစ်တစ်ခုကို ဖန်တီးပါ:
နောက်ဆုံးတွင် `app.js` တွင် placeholder ကိုဖြည့်ရန် function အသစ်တစ်ခုဖန်တီးပါ-
```js
function updateDashboard() {
@ -230,13 +230,13 @@ function updateDashboard() {
}
```
ပထမဆုံး account data ရှိမရှိစစ်ဆေးပြီးမှ ဆက်လုပ်ဆောင်ပါမယ်။ ထို့နောက် HTML ကို update လုပ်ဖို့ `updateElement()` function ကို အသုံးပြုပါတယ်။
ပထမဦးဆုံး account data ရှိမရှိစစ်ဆေးပြီးမှ ဆက်လုပ်ပါမည်။ ထို့နောက် HTML ကို update လုပ်ရန် ကျွန်တော်တို့ဖန်တီးထားသော `updateElement()` function ကိုအသုံးပြုပါမည်။
> Balance display ကို ပိုမိုလှပစေရန် [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) method ကို အသုံးပြုကာ ဒေသမပိုင်းအနေနဲ့ digit ၂ ခုကို အတိအကျပြသပေးပါတယ်။
> Balance display ကို ပိုမိုလှပစေရန် [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) method ကိုအသုံးပြု၍ ဒေသမအပိုင်း ၂ ခုဖြင့် value ကိုပြသသည်။
Dashboard page ကို load လုပ်တိုင်း `updateDashboard()` function ကို ခေါ်ဖို့လိုအပ်ပါတယ်။ [Lesson 1 assignment](../1-template-route/assignment.md) ကို ပြီးစီးထားပြီးသားဖြစ်ရင် ဒီအပိုင်းက ရိုးရှင်းပါတယ်၊ မဟုတ်ရင် အောက်ပါ implementation ကို အသုံးပြုနိုင်ပါတယ်။
Dashboard page ကို load လုပ်သောအခါတိုင်း `updateDashboard()` function ကိုခေါ်ရန်လိုအပ်သည်။ [Lesson 1 assignment](../1-template-route/assignment.md) ကိုပြီးစီးထားပါက ဒီအပိုင်းကို လွယ်ကူစွာလုပ်ဆောင်နိုင်သည်။ မဟုတ်ပါက အောက်ပါ implementation ကိုအသုံးပြုနိုင်သည်။
`updateRoute()` function ရဲ့ အဆုံးမှာ အောက်ပါ code ကို ထည့်သွင်းပါ:
`updateRoute()` function ၏အဆုံးတွင် အောက်ပါ code ကိုထည့်ပါ-
```js
if (typeof route.init === 'function') {
@ -244,7 +244,7 @@ if (typeof route.init === 'function') {
}
```
Routes definition ကို အောက်ပါအတိုင်း update လုပ်ပါ:
Routes definition ကို update လုပ်ပါ-
```js
const routes = {
@ -253,52 +253,36 @@ const routes = {
};
```
ဒီပြောင်းလဲမှုနဲ့ dashboard page ကို ပြသတိုင်း `updateDashboard()` function ကို ခေါ်ပါမယ်။ Login လုပ်ပြီးနောက် account balance, currency နှင့် description ကို မြင်ရပါမယ်။
ဒီပြောင်းလဲမှုဖြင့် dashboard page ကို display လုပ်သောအခါတိုင်း `updateDashboard()` function ကိုခေါ်သည်။ Login ပြုလုပ်ပြီးနောက် account balance, currency နှင့် description ကိုကြည့်နိုင်သည်။
## HTML templates ဖြင့် table rows ကို dynamically ဖန်တီးခြင်း
## HTML templates ဖြင့် table rows ကို dynamic ဖန်တီးခြင်း
[Lesson 1](../1-template-route/README.md) မှာ navigation ကို implement လုပ်ဖို့ HTML templates ကို [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) method နဲ့အတူ အသုံးပြုခဲ့ပါတယ်။ Templates များက ပိုမိုသေးငယ်ပြီး စာမျက်နှာရဲ့ ထပ်တလဲလဲဖြစ်သောအပိုင်းများကို dynamically populate လုပ်ဖို့ အသုံးပြုနိုင်ပါတယ်။
[Lesson 1](../1-template-route/README.md) တွင် navigation ကို implement လုပ်ရန် HTML templates နှင့် [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) method ကိုအသုံးပြုခဲ့သည်။ Templates သည် ပိုမိုသေးငယ်ပြီး page ၏ထပ်နေသောအပိုင်းများကို dynamic populate လုပ်ရန်အသုံးပြုနိုင်သည်။
ဒီနည်းလမ်းကို အသုံးပြုကာ HTML table မှာ transactions များကို ပြသပါမယ်။
ဒီနည်းလမ်းကိုအသုံးပြု၍ HTML table တွင် transactions list ကို display လုပ်ပါမည်။
### လုပ်ဆောင်ရန်
HTML `<body>` မှာ template အသစ်တစ်ခုကို ထည့်သွင်းပါ:
```html
<template id="transaction">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</template>
```
ဒီ template က table row တစ်ခုကို ကိုယ်စားပြုပြီး transactions ရဲ့ *date*, *object* နှင့် *amount* ဆိုတဲ့ column ၃ ခုကို populate လုပ်ဖို့ ရည်ရွယ်ပါတယ်။
Dashboard template ရဲ့ `<tbody>` element မှာ JavaScript ဖြင့် ရှာဖွေရန် အလွယ်ကူစေရန် `id` property ကို ထည့်သ
အကောင့် `test` ကို အသုံးပြုပြီး login လုပ်ကြည့်ပါက dashboard ပေါ်တွင် လုပ်ငန်းစာရင်းကို မြင်နိုင်ပါပြီ 🎉။
###
အကောင့် `test` ကို အသုံးပြုပြီး login လုပ်ကြည့်ပါက dashboard ပေါ်တွင် လုပ်ငန်းစာရင်းကို အခုမှ ကြည့်နိုင်ပါပြီ 🎉။
---
## 🚀 စိန်ခေါ်မှု
ဖွဲ့လိုက်လုပ်ပြီး dashboard စာမျက်နှာကို တကယ့်ဘဏ်အက်ပ်လိုပုံစံဖြစ်အောင် ပြင်ဆင်ပါ။ သင့်အက်ပ်ကို အလှဆင်ပြီးသားဖြစ်ပါက [media queries](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) ကို အသုံးပြုပြီး [responsive design](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) တစ်ခုကို ဖန်တီးပါ၊ desktop နှင့် mobile device နှစ်ခုစလုံးမှာ အဆင်ပြေစွာ အလုပ်လုပ်နိုင်အောင် ပြုလုပ်ပါ။
အတူတကွ လုပ်ဆောင်ပြီး dashboard စာမျက်နှာကို တကယ့်ဘဏ်အက်ပ်လိုပုံစံဖြစ်အောင် ပြင်ဆင်ပါ။ သင့်အက်ပ်ကို အရင်ကပုံစံပြင်ပြီးသားဖြစ်ပါက [media queries](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) ကို အသုံးပြု၍ [responsive design](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) တစ်ခုကို ဖန်တီးပါ၊ desktop နှင့် mobile device နှစ်ခုစလုံးမှာ အဆင်ပြေစွာ အလုပ်လုပ်နိုင်အောင် ပြင်ဆင်ပါ။
ဒီမှာ styled dashboard စာမျက်နှာရဲ့ ဥပမာတစ်ခုကို ဖော်ပြထားပါတယ်:
ဒီမှာ styled dashboard စာမျက်နှာရဲ့ ဥပမာတစ်ခုကို ကြည့်နိုင်ပါတယ်:
![Dashboard ကို အလှဆင်ပြီးနောက်ရလဒ်ရဲ့ ဥပမာ screenshot](../../../../translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.my.png)
![Dashboard ကိုပုံစံပြင်ပြီးနောက်ရလဒ်ရဲ့ ဥပမာ screenshot](../../../../translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.my.png)
## Post-Lecture Quiz
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/46)
## အိမ်စာ
## လုပ်ငန်းတာဝန်
[သင့် code ကို ပြန်လည်ပြင်ဆင်ပြီး မှတ်ချက်ထည့်ပါ](assignment.md)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှားမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူဘာသာစကားဖြင့် အာဏာတရ အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4fa20c513e367e9cdd401bf49ae16e33",
"translation_date": "2025-08-27T22:06:06+00:00",
"original_hash": "5d2efabbc8f94d89f4317ee8646c3ce9",
"translation_date": "2025-08-28T18:32:22+00:00",
"source_file": "7-bank-project/4-state-management/README.md",
"language_code": "my"
}
@ -15,15 +15,13 @@ CO_OP_TRANSLATOR_METADATA:
### အကျဉ်းချုပ်
ဝက်ဘ်အက်ပ်တစ်ခု ကြီးထွားလာသည်နှင့်အမျှ ဒေတာများကို စီမံခန့်ခွဲရန် အခက်အခဲများ ဖြစ်လာနိုင်သည်။ ဘယ်ကုဒ်က ဒေတာကို ရယူသလဲ၊ ဘယ်စာမျက်နှာက ဒေတာကို အသုံးပြုသလဲ၊ ဘယ်နေရာမှာ၊ ဘယ်အချိန်မှာ ဒေတာကို ပြန်လည်အပ်ဒိတ်လုပ်ရမလဲ... အလွယ်တကူ စီမံခန့်ခွဲရန် ခက်ခဲသော ကုဒ်များဖြစ်လာနိုင်သည်။ အထူးသဖြင့် သင့်အက်ပ်၏ စာမျက်နှာများအကြား ဒေတာများကို မျှဝေရန် လိုအပ်သောအခါတွင် ပိုမိုခက်ခဲလာနိုင်သည်။ *State Management* (အခြေအနေ စီမံခန့်ခွဲမှု) ဆိုသော အယူအဆသည် အစဉ်အမြဲ အမျိုးမျိုးသော ပရိုဂရမ်များတွင် ရှိနေခဲ့ပြီး ဝက်ဘ်အက်ပ်များ ကြီးထွားလာသည်နှင့်အမျှ အရေးပါသော အချက်တစ်ခုအဖြစ် ဖွံ့ဖြိုးလာခဲ့သည်။
ဝက်ဘ်အက်ပ်တစ်ခု ကြီးထွားလာသည့်အခါ၊ ဒေတာများကို စီမံခန့်ခွဲရန် အခက်အခဲများ ဖြစ်လာနိုင်သည်။ ဘယ်ကုဒ်က ဒေတာကို ရယူသလဲ၊ ဘယ်စာမျက်နှာက ဒေတာကို သုံးစွဲသလဲ၊ ဘယ်နေရာမှာ၊ ဘယ်အချိန်မှာ ဒေတာကို ပြန်လည် အပ်ဒိတ်လုပ်ရမလဲ... အလွယ်တကူ စီမံခန့်ခွဲရန် ခက်ခဲသော ကုဒ်များဖြစ်လာနိုင်သည်။ အထူးသဖြင့် သင့်အက်ပ်၏ စာမျက်နှာများအကြား ဒေတာများကို မျှဝေရန် လိုအပ်သောအခါ၊ ဥပမာအားဖြင့် အသုံးပြုသူ၏ ဒေတာကို မျှဝေလိုသောအခါ၊ *state management* (အခြေအနေ စီမံခန့်ခွဲမှု) ဆိုသည့် အယူအဆသည် အစဉ်အမြဲ ရှိနေခဲ့ပြီး ဝက်ဘ်အက်ပ်များ ကြီးထွားလာသည့်အခါ၊ အရေးပါသော အချက်တစ်ခုအဖြစ် ဖွံ့ဖြိုးတိုးတက်မှုအတွင်းတွင် စဉ်းစားရန် လိုအပ်လာသည်။
ဒီအပိုင်းနောက်ဆုံးတွင် ကျွန်ုပ်တို့ တည်ဆောက်ထားသော အက်ပ်ကို ပြန်လည်သုံးသပ်ပြီး အခြေအနေ စီမံခန့်ခွဲမှုကို ပြောင်းလဲစဉ်းစားမည်ဖြစ်ပြီး ဘရောက်ဆာကို မည်သည့်အချိန်တွင်မဆို ပြန်လည် Refresh လုပ်နိုင်ရန်နှင့် အသုံးပြုသူ၏ session များအတွင်း ဒေတာကို ထိန်းသိမ်းထားနိုင်ရန် အထောက်အပံ့ပေးမည်ဖြစ်သည်။
ဒီအပိုင်းနောက်ဆုံးတွင်၊ သင့်အက်ပ်ကို ပြန်လည်စဉ်းစားပြီး state ကို စီမံခန့်ခွဲပုံကို ပြောင်းလဲကြည့်မည်ဖြစ်ပြီး၊ ဘရောက်ဆာကို မည်သည့်အချိန်တွင်မဆို refresh လုပ်နိုင်ရန်နှင့် အသုံးပြုသူ session များအကြား ဒေတာကို ထိန်းသိမ်းထားနိုင်ရန် အထောက်အပံ့ပေးမည်ဖြစ်သည်။
### ကြိုတင်လိုအပ်ချက်
ဒီသင်ခန်းစာအတွက် [data fetching](../3-data/README.md) အပိုင်းကို ပြီးစီးထားရန် လိုအပ်သည်။ [Node.js](https://nodejs.org) ကို install လုပ်ပြီး [server API](../api/README.md) ကို locally run လုပ်ရန် လိုအပ်သည်။ ဒါမှ account data ကို စီမံခန့်ခွဲနိုင်မည်ဖြစ်သည်။
Server သေချာစွာ run လုပ်နေသည်ကို စစ်ဆေးရန် terminal တွင် အောက်ပါ command ကို run လုပ်ပါ။
ဒီသင်ခန်းစာအတွက် [data fetching](../3-data/README.md) အပိုင်းကို ပြီးစီးထားရန် လိုအပ်သည်။ [Node.js](https://nodejs.org) ကို install လုပ်ပြီး [server API](../api/README.md) ကို locally run လုပ်ရန် လိုအပ်သည်။ သင့်အကောင့်ဒေတာကို စီမံခန့်ခွဲနိုင်ရန် server ကို run လုပ်ထားသည်ကို terminal မှာ အောက်ပါ command ကို အသုံးပြု၍ စမ်းသပ်နိုင်သည်။
```sh
curl http://localhost:5000/api
@ -34,40 +32,40 @@ curl http://localhost:5000/api
## အခြေအနေ စီမံခန့်ခွဲမှုကို ပြန်လည်စဉ်းစားခြင်း
[ယခင်သင်ခန်းစာ](../3-data/README.md) တွင် ကျွန်ုပ်တို့ app ၏ အခြေအနေကို `account` variable ကို အသုံးပြု၍ အခြေခံအနေဖြင့် စတင်မိတ်ဆက်ခဲ့သည်။ သို့သော် ယခု implementation တွင် အချို့သော အခက်အခဲများ ရှိနေသည်။ Dashboard တွင်ရှိနေစဉ် Page ကို Refresh လုပ်ကြည့်ပါ။ ဘာဖြစ်သလဲ?
[ယခင်သင်ခန်းစာ](../3-data/README.md) တွင်၊ global `account` variable ကို အသုံးပြု၍ လက်ရှိ login လုပ်ထားသော အသုံးပြုသူ၏ ဘဏ်ဒေတာကို ထည့်သွင်းထားသော state အခြေခံအယူအဆကို မိတ်ဆက်ခဲ့သည်။ သို့သော်လည်း၊ လက်ရှိ implementation တွင် အချို့သော အားနည်းက်များ ရှိနေသည်။ Dashboard တွင် refresh လုပ်ကြည့်ပါ။ ဘာဖြစ်သလဲ?
ယခုကုဒ်တွင် အခက်အခဲ ၃ ခုရှိသည်-
လက်ရှိကုဒ်တွင် အခက်အခဲ ၃ ခု ရှိသည်-
- အခြေအနေကို မထိန်းသိမ်းထားသောကြောင့် Browser ကို Refresh လုပ်သည်နှင့် Login Page သို့ ပြန်သွားသည်။
- အခြေအနေကို ပြောင်းလဲသော Function များစွာရှိသည်။ App ကြီးထွားလာသည်နှင့်အမျှ ပြောင်းလဲမှုများကို စစ်ဆေးရန် ခက်ခဲလာပြီး တစ်ခုခုကို Update လုပ်ရန် မေ့လျော့နိုင်သည်။
- Logout ကို click လုပ်သည်နှင့် Login Page တွင်ရှိနေသော်လည်း Account data သေးသေးလျှက်ရှိနေသည်။
- state ကို ထိန်းသိမ်းထားခြင်းမရှိသဖြင့် browser refresh လုပ်လိုက်သည်နှင့် login စာမျက်နှာသို့ ပြန်သွားသည်။
- state ကို ပြောင်းလဲသည့် function များစွာ ရှိသည်။ အက်ပ်ကြီးလာသည်နှင့် အပြောင်းအလဲများကို စဉ်းစားရန် ခက်ခဲလာပြီး function တစ်ခုကို အပ်ဒိတ်လုပ်ရန် မေ့နိုင်သည်။
- state ကို သန့်ရှင်းမလုပ်သဖြင့် *Logout* ကို နှိပ်လိုက်သည်နှင့် login စာမျက်နှာတွင် ရောက်နေသော်လည်း account data သေးသေးလေး ရှိနေသည်။
ဒီအခက်အခဲများကို တစ်ခုချင်းစီ ဖြေရှင်းရန် ကုဒ်ကို Update လုပ်နိုင်သော်လည်း ဒါက ကုဒ်များကို ထပ်တူထပ်မျှဖြစ်စေပြီး App ကို ပိုမိုရှုပ်ထွေးစေမည်ဖြစ်သည်။ ဒါမှမဟုတ် အချိန်အနည်းငယ်ယူပြီး မိမိ၏ Strategy ကို ပြန်လည်စဉ်းစားနိုင်သည်။
ဒီအခက်အခဲများကို တစ်ခုချင်းစီ ဖြေရှင်းရန် ကုဒ်ကို update လုပ်နိုင်သော်လည်း၊ ကုဒ်များ ထပ်တူထပ်မျှဖြစ်လာပြီး အက်ပ်ကို စီမံခန့်ခွဲရန် ခက်ခဲလာနိုင်သည်။ ဒါမှမဟုတ်၊ အနည်းငယ် ခေတ္တရပ်ပြီး မိမိ၏ strategy ကို ပြန်လည်စဉ်းစားနိုင်သည်။
> ဒီအခက်အခဲများကို အမှန်တကယ် ဖြေရှင်းရန် ဘာတွေကို လိုအပ်နေလဲ?
> ဒီအခက်အခဲများကို အမှန်တကယ် ဖြေရှင်းရန် ဘာတွေကို စဉ်းစားရမလဲ?
[State Management](https://en.wikipedia.org/wiki/State_management) ဆိုတာ App တစ်ခု၏ အခြေအနေကို အောက်ပါ ၂ ချက်အတွက် အကောင်းဆုံးနည်းလမ်း ရှာဖွေခြင်းဖြစ်သည်-
[State management](https://en.wikipedia.org/wiki/State_management) ဆိုတာ အက်ပ်တစ်ခုတွင် အောက်ပါ ၂ ချက်ကို ဖြေရှင်းရန် အကောင်းဆုံးနည်းလမ်းကို ရှာဖွေခြင်းဖြစ်သည်-
- App တွင် ဒေတာများကို နားလည်ရန် လွယ်ကူစေရန် ဘယ်လိုလုပ်မလဲ?
- အခြေအနေ data ကို အသုံးပြုသူ interface နှင့် အမြဲတမ်း sync ဖြစ်နေစေရန် (နှင့် အပြန်အလှန်) ဘယ်လိုလုပ်မလဲ?
- အက်ပ်တွင် ဒေတာများကို နားလည်ရန် လွယ်ကူစေရန် ဘယ်လိုလုပ်မလဲ?
- state data ကို အသုံးပြုသူ interface နှင့် အမြဲအချိန်တိုင်အောင် (vice versa) ဘယ်လို sync လုပ်မလဲ?
ဒီအချက်များကို ပြုလုပ်ပြီးပါက အခြားသော အခက်အခဲများသည် အလွယ်တကူ ဖြေရှင်းနိုင်မည်ဖြစ်သည်။ ဒါကို ဖြေရှင်းရန် နည်းလမ်းများစွာ ရှိသော်လည်း ကျွန်ုပ်တို့ **ဒေတာနှင့် ဒေတာကို ပြောင်းလဲရန် နည်းလမ်းများကို အလယ်တွင် စုစည်းခြင်း** ကို အသုံးပြုမည်ဖြစ်သည်။ ဒေတာများ၏ လှုပ်ရှားမှုသည် အောက်ပါအတိုင်းဖြစ်မည်-
ဒီအချက်များကို ပြုလုပ်ပြီးပါက၊ သင်ရရှိနိုင်သော အခြားသော အခက်အခဲများသည် အတော်များများ ဖြေရှင်းပြီးဖြစ်နိုင်သည်။ ဒါမှမဟုတ်၊ ဖြေရှင်းရန် ပိုမိုလွယ်ကူလာနိုင်သည်။ ဒီအခက်အခဲများကို ဖြေရှင်းရန် နည်းလမ်းများစွာ ရှိသော်လည်း **ဒေတာနှင့် ဒေတာကို ပြောင်းလဲရန် နည်းလမ်းများကို အလယ်တွင် စုစည်းထားခြင်း** ဆိုသည့် နည်းလမ်းကို အသုံးပြုမည်ဖြစ်သည်။ ဒေတာများ၏ လှိုင်းများသည် အောက်ပါအတိုင်း ဖြစ်မည်-
![HTML, အသုံးပြုသူ၏ လှုပ်ရှားမှုများနှင့် အခြေအနေအကြား ဒေတာလှုပ်ရှားမှုများကို ပြသသော Schema](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.my.png)
![HTML, user actions နှင့် state အကြား ဒေတာလှိုင်းများကို ပြသသည့် schema](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.my.png)
> ဒီနေရာတွင် ဒေတာသည် အလိုအလျောက် view ကို update လုပ်ပေးသော အပိုင်းကို မဖော်ပြပါ၊ အဲဒါက [Reactive Programming](https://en.wikipedia.org/wiki/Reactive_programming) အဆင့်မြင့်အယူအဆများနှင့် ဆက်စပ်နေသောကြောင့် ဖြစ်သည်။ အနက်ရှိုင်းစွာ လေ့လာလိုပါက အကောင်းဆုံးအကြောင်းအရာတစ်ခုဖြစ်သည်။
> ဒီနေရာတွင် view update ကို အလိုအလျောက် trigger လုပ်သည့် အပိုင်းကို မဖော်ပြပါ၊ အကြောင်းမှာ [Reactive Programming](https://en.wikipedia.org/wiki/Reactive_programming) ဆိုသည့် အဆင့်မြင့်အယူအဆများနှင့် ဆက်စပ်နေသောကြောင့် ဖြစ်သည်။ အနက်ရှိုင်းစွာ လေ့လာလိုပါက အကောင်းဆုံးအကြောင်းအရာတစ်ခုဖြစ်သည်။
✅ State Management အတွက် နည်းလမ်းများစွာရှိပြီး [Redux](https://redux.js.org) သည် လူကြိုက်များသော library တစ်ခုဖြစ်သည်။ အကြီးမားသော ဝက်ဘ်အက်ပ်များတွင် ကြုံရနိုင်သော အခက်အခဲများနှင့် အဲဒါကို ဘယ်လိုဖြေရှင်းနိုင်သည်ကို သင်ယူရန် အကောင်းဆုံးနည်းလမ်းတစ်ခုဖြစ်သည်
✅ State management အတွက် library များစွာ ရှိပြီး၊ [Redux](https://redux.js.org) သည် လူကြိုက်များသော ရွေးချယ်မှုတစ်ခုဖြစ်သည်။ အကြီးမားသော ဝက်ဘ်အက်ပ်များတွင် ကြုံရနိုင်သော အခက်အခဲများနှင့် ဖြေရှင်းနိုင်သော နည်းလမ်းများကို သင်ယူရန် concept များနှင့် pattern များကို ကြည့်ရှုပါ
### လုပ်ငန်း
ရင်ဆုံး ကုဒ်ကို အနည်းငယ် ပြုပြင်မည်။ `account` ကို အောက်ပါအတိုင်း ပြောင်းလဲပါ-
နည်းငယ် refactoring ဖြင့် စတင်မည်။ `account` ကို အောက်ပါအတိုင်း ပြောင်းလဲပါ-
```js
let account = null;
```
အစား
အစား-
```js
let state = {
@ -75,9 +73,9 @@ let state = {
};
```
ဒီအကြောင်းအရာမှာ App ၏ ဒေတာအားလုံးကို တစ်ခုတည်းသော state object တွင် စုစည်းရန် ဖြစ်သည်။ ယခုအချိန်တွင် state တွင် `account` တစ်ခုတည်းသာ ရှိသဖြင့် များစွာ ပြောင်းလဲမှုမရှိသော်လည်း အနာဂတ်အတွက် လမ်းကြောင်းဖန်တီးပေးသည်။
ဒီအယူအဆမှာ *state object* တစ်ခုတွင် အက်ပ်၏ ဒေတာအားလုံးကို စုစည်းထားရန် ဖြစ်သည်။ လက်ရှိ state တွင် `account` သာ ရှိသည့်အတွက် အများကြီး မပြောင်းလဲသော်လည်း၊ အနာဂတ်အတွက် လမ်းကြောင်းတစ်ခု ဖန်တီးပေးသည်။
Function များကိုလည်း Update လုပ်ရန် လိုအပ်သည်။ `register()` နှင့် `login()` function များတွင် `account = ...` ကို `state.account = ...` ဖြင့် အစားထိုးပါ။
ဒါ့အပြင်၊ function များကို update လုပ်ရန် လိုအပ်သည်။ `register()` နှင့် `login()` function များတွင် `account = ...` ကို `state.account = ...` ဖြင့် အစားထိုးပါ။
`updateDashboard()` function ၏ အပေါ်တွင် အောက်ပါလိုင်းကို ထည့်ပါ-
@ -85,21 +83,21 @@ Function များကိုလည်း Update လုပ်ရန် လိ
const account = state.account;
```
ဒီ refactoring ကိုယ်တိုင်က များစွာသော တိုးတက်မှုများ မဖြစ်ပေါ်စေသော်လည်း နောက်ထပ် ပြောင်းလဲမှုများအတွက် အခြေခံအုတ်မြစ်ကို ဖန်တီးရန် ဖြစ်သည်။
ဒီ refactoring ကိုယ်တိုင်က အများကြီး တိုးတက်မှု မဖြစ်ပေမယ့်၊ နောက်ထပ် ပြောင်းလဲမှုများအတွက် အခြေခံအုတ်မြစ်ကို ဖန်တီးရန် ရည်ရွယ်သည်။
## ဒေတာပြောင်းလဲမှုများကို စစ်ဆေးခြင်း
## ဒေတာပြောင်းလဲမှုများကို စောင့်ကြည့်ခြင်း
`state` object ကို အသုံးပြု၍ ဒေတာကို သိမ်းဆည်းပြီးနောက် အဆင့်နောက်တစ်ခုမှာ ပြောင်းလဲမှုများကို စုစည်းရန် ဖြစ်သည်။ ပြောင်းလဲမှုများကို စစ်ဆေးရန် လွယ်ကူစေရန်နှင့် ဘယ်အချိန်တွင် ပြောင်းလဲမှုများ ဖြစ်ပေါ်သည်ကို သိရန် ဖြစ်သည်။
state object ကို ဒေတာသိမ်းဆည်းရန် အသုံးပြုပြီးနောက်၊ နောက်တစ်ဆင့်မှာ update များကို စုစည်းထားရန် ဖြစ်သည်။ အပြောင်းအလဲများနှင့် အချိန်ကို စောင့်ကြည့်ရန် ပိုမိုလွယ်ကူစေရန် ရည်ရွယ်သည်။
`state` object ကို ပြောင်းလဲမှုများ မဖြစ်ပေါ်စေရန် [*immutable*](https://en.wikipedia.org/wiki/Immutable_object) ဖြစ်စေရန် သတ်မှတ်ခြင်းသည်လည်း အကောင်းဆုံးနည်းလမ်းတစ်ခုဖြစ်သည်။ ဒါက object ကို ပြောင်းလဲမှုများ မဖြစ်ပေါ်စေရန် ကာကွယ်ပေးပြီး [side effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) မလိုအပ်သောအခါ ကာကွယ်ပေးသည်။ Undo/Redo feature များကို ထည့်သွင်းနိုင်ရန် လမ်းဖွင့်ပေးပြီး Debug လုပ်ရန်လည်း လွယ်ကူစေသည်။ ဥပမာအားဖြင့် state ပြောင်းလဲမှုများအားလုံးကို log လုပ်ပြီး Bug ရှာဖွေရန် ပြောင်းလဲမှုများ၏ သမိုင်းကို သိမ်းဆည်းနိုင်သည်။
state object ကို ပြောင်းလဲမှုများ မဖြစ်စေရန် [*immutable*](https://en.wikipedia.org/wiki/Immutable_object) အဖြစ် စဉ်းစားရန် သင့်တော်သည်။ ဒါက state object ကို ပြောင်းလဲလို့ မရဘဲ၊ state object အသစ်တစ်ခု ဖန်တီးရန် လိုအပ်သည်။ ဒီလိုလုပ်ခြင်းဖြင့် မလိုလားအပ်သော [side effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) များကို ကာကွယ်ပေးပြီး၊ undo/redo ကို အကောင်အထည်ဖော်ခြင်းကဲ့သို့သော feature အသစ်များကို အက်ပ်တွင် ထည့်သွင်းနိုင်သည်။ ထို့အပြင်၊ debug လုပ်ရန် ပိုမိုလွယ်ကူစေသည်။ ဥပမာအားဖြင့် state ပြောင်းလဲမှုများအားလုံးကို log လုပ်ပြီး၊ bug ရှိနေသော အရင်းအမြစ်ကို နားလည်ရန် ပြောင်းလဲမှုများ၏ သမိုင်းကို သိမ်းဆည်းနိုင်သည်။
JavaScript တွင် [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) ကို အသုံးပြု၍ object တစ်ခုကို immutable ဖြစ်စေရန် ဖန်တီးနိုင်သည်။ Immutable object ကို ပြောင်းလဲရန် ကြိုးစားပါက Exception တစ်ခု ဖြစ်ပေါ်မည်။
JavaScript တွင် [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) ကို အသုံးပြု၍ object တစ်ခု၏ immutable version ကို ဖန်တီးနိုင်သည်။ immutable object ကို ပြောင်းလဲရန် ကြိုးစားပါက exception တစ်ခု ထွက်လာမည်။
*shallow* immutable object နှင့် *deep* immutable object တစ်ခု၏ ကွာခြားချက်ကို သိပါသလား? [ဒီနေရာ](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze) တွင် ဖတ်ရှုနိုင်သည်။
### လုပ်ငန်း
အသစ်သော `updateState()` function တစ်ခု ဖန်တီးပါ-
`updateState()` function အသစ်တစ်ခု ဖန်တီးပါ-
```js
function updateState(property, newData) {
@ -110,9 +108,9 @@ function updateState(property, newData) {
}
```
ဒီ function တွင် ယခင် state မှ ဒေတာကို copy လုပ်ပြီး state object အသစ်တစ်ခုကို ဖန်တီးသည်။ ပြီးတော့ [bracket notation](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` ကို အသုံးပြု၍ state object ၏ property တစ်ခုကို override လုပ်သည်။ နောက်ဆုံးတွင် `Object.freeze()` ကို အသုံးပြု၍ object ကို lock လုပ်သည်။ ယခုအချိန်တွင် state တွင် `account` property တစ်ခုတည်းသာ ရှိသော်လည်း ဒီနည်းလမ်းဖြင့် state တွင် လိုအပ်သော property များစွာ ထည့်သွင်းနိုင်သည်။
ဒီ function တွင်၊ state object အသစ်တစ်ခု ဖန်တီးပြီး၊ [*spread (`...`) operator*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals) ကို အသုံးပြု၍ ယခင် state မှ ဒေတာကို ကူးယူသည်။ ထို့နောက်၊ [bracket notation](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` ကို အသုံးပြု၍ state object ၏ အထူး property တစ်ခုကို override လုပ်သည်။ နောက်ဆုံးတွင် `Object.freeze()` ကို အသုံးပြု၍ object ကို lock လုပ်သည်။ state တွင် လက်ရှိ `account` property သာ ရှိသော်လည်း ဒီနည်းလမ်းဖြင့် state တွင် လိုအပ်သည့် property များစွာ ထည့်သွင်းနိုင်သည်။
`state` initialization ကိုလည်း Update လုပ်ပြီး initial state ကိုလည်း freeze ဖြစ်စေရန် သေချာစေပါ-
state initialization ကို update လုပ်ပြီး၊ initial state ကိုလည်း freeze လုပ်ထားရန် သေချာပါ-
```js
let state = Object.freeze({
@ -120,21 +118,21 @@ let state = Object.freeze({
});
```
ထို့နောက် `register` function တွင် `state.account = result;` assignment ကို အောက်ပါအတိုင်း အစားထိုးပါ-
ထို့နောက် `register` function တွင် `state.account = result;` assignment ကို အစား-
```js
updateState('account', result);
```
`login` function တွင်လည်း `state.account = data;` ကို အောက်ပါအတိုင်း အစားထိုးပါ-
`login` function တွင်လည်း `state.account = data;` ကို အစား-
```js
updateState('account', data);
```
သုံးပြုသူ Logout ကို click လုပ်သောအခါ account data မရှင်းလင်းသော အခက်အခဲကို ပြုပြင်ရန် အခွင့်အရေးကို ယခုယူပါ
ခုတော့ *Logout* ကို နှိပ်လိုက်သည်နှင့် အသုံးပြုသူ၏ account data များကို ဖယ်ရှားရန် ပြဿနာကို ဖြေရှင်းရန် အခွင့်အရေးရရှိပါပြီ
အသစ်သော `logout()` function တစ်ခု ဖန်တီးပါ-
`logout()` function အသစ်တစ်ခု ဖန်တီးပါ-
```js
function logout() {
@ -145,33 +143,33 @@ function logout() {
`updateDashboard()` တွင် `return navigate('/login');` redirection ကို `return logout();` ဖြင့် အစားထိုးပါ။
သစ်သော account ကို register လုပ်ပြီး Logout နှင့် Login ပြန်လုပ်ပါ။ အားလုံး သေချာစွာ အလုပ်လုပ်နေသည်ကို စစ်ဆေးပါ။
ကောင့်အသစ်တစ်ခု register လုပ်ပြီး၊ logout နှင့် login ပြန်လုပ်ပါ။ အားလုံး အဆင်ပြေသလား စစ်ဆေးပါ။
> အကြံပြုချက်- `updateState()` ၏ အောက်ဆုံးတွင် `console.log(state)` ကို ထည့်သွင်းပြီး Browser ၏ Development Tools တွင် console ကို ဖွင့်ကာ state ပြောင်းလဲမှုအားလုံးကို ကြည့်ရှုနိုင်သည်။
> အကြံပြုချက်- `updateState()` ၏ အောက်ဆုံးတွင် `console.log(state)` ကို ထည့်ပြီး၊ browser development tools တွင် console ကို ဖွင့်ကာ state ပြောင်းလဲမှုအားလုံးကို ကြည့်ရှုနိုင်သည်။
## အခြေအနေကို ထိန်းသိမ်းခြင်း
## state ကို ထိန်းသိမ်းခြင်း
ဝက်ဘ်အက်ပ်များအများစုသည် သေချာစွာ အလုပ်လုပ်ရန် ဒေတာကို ထိန်းသိမ်းရန် လိုအပ်သည်။ အရေးကြီးသော ဒေတာအားလုံးကို database တွင် သိမ်းဆည်းပြီး server API မှတစ်ဆင့် access လုပ်သည်။ သို့သော် Browser တွင် client app တွင် ဒေတာတစ်ချို့ကို ထိန်းသိမ်းခြင်းသည် အသုံးပြုသူအတွေ့အကြုံကို ပိုမိုကောင်းမွန်စေခြင်း သို့မဟုတ် Loading performance ကို တိုးတက်စေခြင်းအတွက် စိတ်ဝင်စားစရာကောင်းသည်။
ဝက်ဘ်အက်ပ်များအများစုသည် data ကို ထိန်းသိမ်းရန် လိုအပ်သည်။ အရေးကြီးသော data အားလုံးကို database တွင် သိမ်းဆည်းပြီး server API မှတဆင့် access လုပ်သည်။ သို့သော်၊ browser တွင် client app တွင် data တစ်ချို့ကို သိမ်းဆည်းခြင်းသည် အသုံးပြုသူအတွေ့အကြုံကို ပိုမိုကောင်းမွန်စေခြင်း သို့မဟုတ် loading performance ကို တိုးတက်စေခြင်းအတွက် စိတ်ဝင်စားစရာကောင်းသည်။
Browser တွင် ဒေတာကို သိမ်းဆည်းလိုပါက အရေးကြီးသော မေးခွန်းများကို မေးရမည်-
browser တွင် data ကို သိမ်းဆည်းလိုပါက အရေးကြီးသော မေးခွန်းများကို မေးရမည်-
- *ဒေတာသည် အရေးကြီးသော ဒေတာလား?* အသုံးပြုသူ၏ password ကဲ့သို့ sensitive data များကို client တွင် သိမ်းဆည်းရန် ရှောင်ရှားသင့်သည်။
- *ဒီဒေတာကို ဘယ်လောက်ကြာအောင် သိမ်းဆည်းလိုပါသလဲ?* ဒီဒေတာကို current session အတွက်သာ အသုံးပြုလိုပါသလား၊ ဒေတာကို အမြဲတမ်း သိမ်းဆည်းလိုပါသလား?
- *ဒီ data သည် sensitive ဖြစ်ပါသလား?* အသုံးပြုသူ၏ password ကဲ့သို့သော sensitive data များကို client တွင် သိမ်းဆည်းရန် ရှောင်ရှားသင့်သည်။
- *ဒီ data ကို ဘယ်လောက်ကြာအောင် သိမ်းဆည်းလိုပါသလဲ?* ဒီ data ကို လက်ရှိ session အတွက်သာ အသုံးပြုလိုပါသလား၊ ဒါမှမဟုတ် အမြဲတမ်း သိမ်းဆည်းလိုပါသလား?
ဝက်ဘ်အက်ပ်တွင် ဒေတာကို သိမ်းဆည်းရန် နည်းလမ်းများစွာ ရှိပြီး သင့်ရည်ရွယ်ချက်အပေါ် မူတည်သည်။ ဥပမာအားဖြင့် URL တွင် search query ကို သိမ်းဆည်းပြီး အသုံးပြုသူများအကြား မျှဝေနိုင်သည်။ [Authentication](https://en.wikipedia.org/wiki/Authentication) အချက်အလက်ကဲ့သို့ server နှင့် မျှဝေရန် လိုအပ်သော ဒေတာများအတွက် [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies) ကို အသုံးပြုနိုင်သည်။
ဝက်ဘ်အက်ပ်တွင် data ကို သိမ်းဆည်းရန် နည်းလမ်းများစွာ ရှိသည်။ ဥပမာအားဖြင့်၊ search query ကို URL တွင် သိမ်းဆည်းပြီး၊ အသုံးပြုသူများအကြား မျှဝေနိုင်သည်။ [authentication](https://en.wikipedia.org/wiki/Authentication) အချက်အလက်ကဲ့သို့ server နှင့် data ကို မျှဝေလိုပါက [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies) ကို အသုံးပြုနိုင်သည်။
Browser API များစွာရှိပြီး ဒေတာကို သိမ်းဆည်းရန် အထူးစိတ်ဝင်စားစရာကောင်းသော API နှစ်ခုရှိသည်-
browser API များစွာ ရှိပြီး၊ data သိမ်းဆည်းရန် အထူးစိတ်ဝင်စားစရာကောင်းသော API နှစ်ခု ရှိသည်-
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) တစ်ခုဖြစ်ပြီး current website အတွက် session များအကြား ဒေတာကို ထိန်းသိမ်းနိုင်သည်။ သိမ်းဆည်းထားသော ဒေတာသည် မည်သည့်အချိန်တွင်မဆို မပျောက်ဆုံးပါ။
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): ဒီ API သည် `localStorage` နှင့် တူသည်။ သို့သော် session ပြီးဆုံးသည်နှင့် သိမ်းဆည်းထားသော ဒေတာကို ဖျက်ပစ်သည်။
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) တစ်ခုဖြစ်ပြီး၊ လက်ရှိ website-specific data ကို session များအကြား ထိန်းသိမ်းထားနိုင်သည်။ သိမ်းဆည်းထားသော data သည် expiration မရှိပါ။
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): ဒီ API သည် `localStorage` နှင့် တူသော်လည်း၊ session ပြီးဆုံးသည့်အခါ (browser ကို ပိတ်သည့်အခါ) data ကို ဖျက်သိမ်းသည်။
API နှစ်ခုလုံးသည် [strings](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) ကိုသာ သိမ်းဆည်းနိုင်သည်။ [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) format သို့ serialize လုပ်ရန် [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) ကို အသုံးပြုရန် လိုအပ်သည်။
API နှစ်ခုလုံးသည် [strings](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) ကိုသာ သိမ်းဆည်းနိုင်သည်။ complex object များကို သိမ်းဆည်းလိုပါက၊ [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) ကို အသုံးပြု၍ [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) format သို့ serialize လုပ်ရန် လိုအပ်သည်။
Server မပါသော ဝက်ဘ်အက်ပ်တစ်ခုကို ဖန်တီးလိုပါက [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API) ကို အသုံးပြု၍ client တွင် database တစ်ခု ဖန်တီးနိုင်သည်။ ဒါက အဆင့်မြင့်သော အသုံးပြုမှုများ သို့မဟုတ် ဒေတာအများအပြား သိမ်းဆည်းရန် Advanced use case များအတွက်သာ သင့်လျော်သည်။
server မရှိသော ဝက်ဘ်အက်ပ်တစ်ခု ဖန်တီးလိုပါက [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API) ကို အသုံးပြု၍ client တွင် database တစ်ခု ဖန်တီးနိုင်သည်။ ဒီ API သည် အဆင့်မြင့်အသုံးပြုမှုများ သို့မဟုတ် data အများကြီး သိမ်းဆည်းလိုပါက သင့်တော်သည်၊ အကြောင်းမှာ အသုံးပြုရန် ပိုမိုရှုပ်ထွေးသောကြောင့် ဖြစ်သည်။
### လုပ်ငန်း
အသုံးပြုသူ Logout ကို click မလုပ်မီ Login အခြေအနေကို ထိန်းသိမ်းထားရန် `localStorage` ကို အသုံးပြုမည်။ အရင်ဆုံး ဒေတာကို သိမ်းဆည်းရန် အသုံးပြုမည့် key ကို သတ်မှတ်ပါ။
အသုံးပြုသူများသည် *Logout* button ကို explicitly နှိပ်သည်အထိ login လုပ်ထားနိုင်ရန် `localStorage` ကို အသုံးပြု၍ account data ကို သိမ်းဆည်းမည်။ အရင်ဆုံး၊ data သိမ်းဆည်းရန် အသုံးပြုမည့် key ကို သတ်မှတ်ပါ။
```js
const storageKey = 'savedAccount';
@ -183,37 +181,16 @@ const storageKey = 'savedAccount';
localStorage.setItem(storageKey, JSON.stringify(state.account));
```
ဒီနည်းလမ်းဖြင့် အသုံးပြုသူ၏ account data ကို သိမ်းဆည်းပြီး ယခင် refactor များအားလုံးကြောင့် အမြဲတမ်း up-to-date ဖြစ်နေမည်။ ဒီနေရာတွင် ယခင် refactor များ၏ အကျိုးကျေးဇူးကို စတင်ခံစားရမည် 🙂။
ဒေတာကို သိမ်းဆည်းပြီးပါက App ကို load လုပ်သောအခါ ဒေတာကို ပြန်လည် Restore လုပ်ရန်လည်း လိုအပ်သည်။ Initialization code ပိုများလာသည်ကြောင့် `app.js` ၏ အောက်ဆုံးရှိ ယခင် code ကိုလည်း ထည့်သွင်းထားသော အသစ်သော `init` function တစ်ခု ဖန်တီးပါ-
```js
function init() {
const savedAccount = localStorage.getItem(storageKey);
if (savedAccount) {
updateState('account', JSON.parse(savedAccount));
}
// Our previous initialization code
window.onpopstate = () => updateRoute();
updateRoute();
}
init();
```
ဒီနေရာတွင် သိမ်းဆည်းထားသော ဒေတာကို ပြန်လည်ရ
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/48)
## အလုပ်ပေးချက်
ဒီနည်းလမ်းဖြင့်၊ အသုံးပြုသူ၏ account data ကို သိမ်းဆည်းပြီး၊ state update များအားလုံးကို centralized လုပ်ထားသည့်အတွက် အမြဲတမ်း up-to-date ဖြစ်နေမည်။ ဒီနေရာတွင် ယခင် refactor များ၏ အကျိုးကျေးဇူးကို စတင်ခံစားရမည် 🙂။
[“Add transaction” dialog ကို အကောင်အထည်ဖော်ပါ](assignment.md)
data ကို သိမ်းဆည်းထားသည့်အတွက်၊ app ကို load လုပ်သောအခါ data ကို ပြ
[လုပ်ဆောင်ရန် "ငွေသွင်းမှု ထည့်သွင်းရန်" ဆွေးနွေးမှုကို အကောင်အထည်ဖော်ပါ](assignment.md)
အလုပ်ပေးချက်ပြီးဆုံးပြီးနောက်ရရှိသော ဥပမာရလဒ်မှာ အောက်ပါအတိုင်းဖြစ်ပါသည် -
ဤလုပ်ငန်းကို ပြီးမြောက်ပြီးနောက်ရရှိသော နမူနာရလဒ်ဖြစ်သည် -
![“Add transaction” dialog ဥပမာကို ပြသထားသော Screenshot](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.my.png)
!["ငွေသွင်းမှု ထည့်သွင်းရန်" ဆွေးနွေးမှု၏ နမူနာ Screenshot](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.my.png)
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို ကျေးဇူးပြု၍ သိရှိထားပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွဲအချော်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
**ဝက်ဘ်ဆိုက်မှတ်ချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှန်ကန်မှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက်ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်ကြောင်း သတိပြုပါ။ မူလဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတည်သော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော နားလည်မှုမှားများ သို့မဟုတ် အဓိပ္ပာယ်မှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မရှိပါ။

@ -1,107 +1,138 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "7aa6e4f270d38d9cb17f2b5bd86b863d",
"translation_date": "2025-08-27T22:41:42+00:00",
"original_hash": "1ba61d96a11309a2a6ea507496dcf7e5",
"translation_date": "2025-08-28T18:46:26+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/README.md",
"language_code": "my"
}
-->
# ကုဒ်အယ်ဒီတာ အသုံးပြုခြင်း
# ကုဒ်အယ်ဒီတာအသုံးပြုခြင်း
ဒီသင်ခန်းစာမှာ [VSCode.dev](https://vscode.dev) ဆိုတဲ့ ဝဘ်အခြေပြုကုဒ်အယ်ဒီတာကို အသုံးပြုပြီး သင့်ရဲ့ကုဒ်ကို ပြင်ဆင်ခြင်းနှင့် ပရောဂျက်တွင် ပါဝင်ဆောင်ရွက်နိုင်ရန် အခြေခံအချက်များကို လေ့လာပါမည်။ ဒီအရာတွေကို သင့ကွန်ပျူတာမှာ ဘာမှ ထည့်သွင်းမထားဘဲ လုပ်ဆောင်နိုင်ပါတယ်။
ဒီသင်ခန်းစာမှာ [VSCode.dev](https://vscode.dev) ဆိုတဲ့ ဝဘ်အခြေပြုကုဒ်အယ်ဒီတာကို အသုံးပြုပြီး သင့်ကုဒ်ကို ပြင်ဆင်ခြင်းနှင့် ပရောဂျက်တစ်ခုမှာ ပါဝင်ဆောင်ရွက်နိုင်ဖို့ အခြေခံအချက်များကို လေ့လာပါမည်။ ဒီအရာတွေကို သင့ကွန်ပျူတာမှာ ဘာမှ ထည့်သွင်းမလိုဘဲ လုပ်ဆောင်နိုင်ပါတယ်။
## သင်ခန်းစာရည်မှန်းချက်များ
ဒီသင်ခန်းစာအပြီးမှာ သင်တတ်မြောက်မည့်အရာများမှာ -
- ကုဒ်ပရောဂျက်တစ်ခုအတွင်း ကုဒ်အယ်ဒီတာကို အသုံးပြုနိုင်ခြင်း
- ဗားရှင်းထိန်းချုပ်မှုဖြင့် ပြောင်းလဲမှုများကို စောင့်ကြည့်နိုင်ခြင်း
- ကုဒ်ပရောဂျက်တစ်ခုမှာ ကုဒ်အယ်ဒီတာကို အသုံးပြုနိုင်ခြင်း
- ဗားရှင်းထိန်းချုပ်မှုဖြင့် ပြောင်းလဲမှုများကို ထိန်းသိမ်းနိုင်ခြင်း
- ဖွံ့ဖြိုးတိုးတက်မှုအတွက် အယ်ဒီတာကို စိတ်ကြိုက်ပြင်ဆင်နိုင်ခြင်း
### ကြိုတင်လိုအပ်ချက်များ
စတင်မည်မီ သင့်မှာ [GitHub](https://github.com) အကောင့်တစ်ခု ရှိဖို့လိုအပ်ပါတယ်။ [GitHub](https://github.com/) ကိုသွားပြီး အကောင့်မရှိသေးပါက အသစ်တစ်ခု ဖန်တီးပါ။
စတင်မတိုင်မီ [GitHub](https://github.com) တွင် အကောင့်တစ်ခု ဖန်တီးထားရန် လိုအပ်ပါသည်။ [GitHub](https://github.com/) သို့ သွားပြီး အကောင့်မရှိသေးပါက ဖန်တီးပါ။
### နိဒါန်း
ကုဒ်အယ်ဒီတာသည် ပရိုဂရမ်ရေးသားခြင်းနှင့် ရှိပြီးသားကုဒ်ပရောဂျက်များတွင် ပူးပေါင်းဆောင်ရွက်ရန် အရေးကြီးသော ကိရိယာတစ်ခုဖြစ်သည်။ အယ်ဒီတာ၏ အခြေခံအချက်များနှင့် ၎င်း၏ အင်္ဂါရပ်များကို အသုံးချနည်းကို နားလည်ပြီးပါက သင့်ရဲ့ကုဒ်ရေးသားမှုတွင် အလွယ်တကူ အသုံးချနိုင်ပါမည်။
ကုဒ်အယ်ဒီတာသည် ပရိုဂရမ်ရေးသားခြင်းနှင့် ရှိပြီးသားကုဒ်ပရောဂျက်များတွင် ပူးပေါင်းဆောင်ရွက်ရန် အရေးကြီးသော ကိရိယာတစ်ခုဖြစ်သည်။ အယ်ဒီတာ၏ အခြေခံအချက်များနှင့် ၎င်း၏ လုပ်ဆောင်ချက်များကို နားလည်ပြီးပါက သင့်ကုဒ်ရေးသားမှုတွင် အသုံးချနိုင်ပါမည်။
## VSCode.dev ဖြင့် စတင်ခြင်း
[VSCode.dev](https://vscode.dev) သည် ဝဘ်အခြေပြု ကုဒ်အယ်ဒီတာတစ်ခုဖြစ်သည်။ ၎င်းကို အသုံးပြုရန် ဘာမှ ထည့်သွင်းရန် မလိုအပ်ပါဘူး၊ အခြားဝဘ်ဆိုဒ်တစ်ခု ဖွင့်သလိုပဲ ဖွင့်နိုင်ပါတယ်။ စတင်ရန် [https://vscode.dev](https://vscode.dev) ကို ဖွင့်ပါ။ သင် [GitHub](https://github.com/) တွင် လော့ဂ်အင်မလုပ်ထားပါက လိုအပ်သော လမ်းညွှန်ချက်များကို လိုက်နာပြီး လော့ဂ်အင်လုပ်ပါ။
[VSCode.dev](https://vscode.dev) သည် ဝဘ်ပေါ်တွင်ရှိသော ကုဒ်အယ်ဒီတာတစ်ခုဖြစ်သည်။ ၎င်းကို အသုံးပြုရန် ဘာမှ ထည့်သွင်းရန် မလိုအပ်ပါဘူး၊ အခြားဝဘ်ဆိုဒ်တစ်ခုဖွင့်သလိုပဲ ဖွင့်နိုင်ပါသည်။ စတင်ရန် [https://vscode.dev](https://vscode.dev) သို့ သွားပါ။ [GitHub](https://github.com/) တွင် လော့ဂ်အင်မလုပ်ထားပါက လော့ဂ်အင်လုပ်ရန် သို့မဟုတ် အကောင့်အသစ်ဖန်တီးရန် အဆင့်ဆင့်ညွှန်ကြားချက်များကို လိုက်နာပါ။
ဖွင့်ပြီးပါက အောက်ပါပုံနှင့် ဆင်တူသော အခြေအနေကို တွေ့ရပါမည် -
ဖွင့်ပြီးပါက အောက်ပါပုံနှင့် ဆင်တူသော အခြေအနေကို တွေ့ရမည်ဖြစ်သည် -
![Default VSCode.dev](../../../../translated_images/default-vscode-dev.5d06881d65c1b3234ce50cd9ed3b0028e6031ad5f5b441bcbed96bfa6311f6d0.my.png)
ဤအယ်ဒီတာတွင် အဓိကပိုင်းသုံးခုရှိသည် -
ဤအယ်ဒီတာတွင် အဓိကပိုင်းခုရှိသည် -
1. _Activity Bar_ - 🔎 မျှော်မှန်းမှန်၊ ⚙️ ဂီယာနှင့် အခြားအိုင်ကွန်များပါဝင်သည်။
2. _Side Bar_ - _Explorer_ အဖြစ် အဆင့်မြှင့်ထားသော Activity Bar ၏ အပိုင်း
3. _Code Area_ - ညာဘက်တွင်ရှိပြီး ကုဒ်ကို ပြင်ဆင်ရန် အသုံးပြုသည်
1. _Activity bar_ - 🔎 မျှော်စင်၊ ⚙️ ဂီယာနှင့် အခြားအိုင်ကွန်များပါဝင်သည်။
2. _Side bar_ - _Explorer_ အဖြစ် အမည်ပေးထားသော အက်တစ်ဗစ်တစ်ခုဖြစ်သည်
3. _Code area_ - ကုဒ်ရေးသားခြင်းနှင့် ပြင်ဆင်ရန် အဓိကနေရာ
အိုင်ကွန်တစ်ခုချင်းစီကို နှိပ်ပြီး မီနူးအသစ်များကို ကြည့်ပါ။ ပြီးလျှင် _Explorer_ ကို ပြန်နှိပ်ပါ။
အိုင်ကွန်တစ်ခုချင်းစီကို နှိပ်ပြီး မီနူးအသစ်များကို ဖွင့်ပါ။ ပြီးလျှင် _Explorer_ ကို ပြန်နှိပ်ပါ။
သင့်ရဲ့ကုဒ်ကို ဖန်တီးခြင်း သို့မဟုတ် ပြင်ဆင်ခြင်းကို ဤ Code Area တွင် ပြုလုပ်မည်ဖြစ်သည်။
သင့်ကုဒ်ကို ဖန်တီးခြင်း သို့မဟုတ် ပြင်ဆင်ခြင်းကို အညာပိုင်းအကြီးဆုံးနေရာတွင် ပြုလုပ်မည်ဖြစ်သည်။
## GitHub Repository ဖွင့်ခြင်း
GitHub Repository တစ်ခု ဖွင့်ရန် အမျိုးမျိုးသောနည်းလမ်းများရှိသည်။ ဒီအပိုင်းမှာ Repository ကို ဖွင့်နိုင်ရန် နည်းလမ်းနှစ်ခုကို လေ့လာပါမည်။
GitHub repository တစ်ခုဖွင့်ရန် အမျိုးမျိုးသောနည်းလမ်းများရှိသည်။ ဒီအပိုင်းမှာ repository ဖွင့်နိုင်သော နည်းလမ်း ၂ မျိုးကို လေ့လာပါမည်။
### ၁။ အယ်ဒီတာမှ ွင့်ခြင်
### ၁။ အယ်ဒီတာဖြင
အယ်ဒီတာကို အသုံးပြု၍ Remote Repository ကို ဖွင့်ပါ။ [VSCode.dev](https://vscode.dev) သို့ သွားပါ_"Open Remote Repository"_ ခလုတ်ကို တွေ့ရပါမည်။
အယ်ဒီတာကို အသုံးပြု၍ remote repository တစ်ခုဖွင့်ပါ။ [VSCode.dev](https://vscode.dev) သို့ သွားပါက _"Open Remote Repository"_ ခလုတ်ကို တွေ့ရမည် -
![Open remote repository](../../../../translated_images/open-remote-repository.bd9c2598b8949e7fc283cdfc8f4050c6205a7c7c6d3f78c4b135115d037d6fa2.my.png)
Command Palette ကိုလည်း အသုံးပြုနိုင်သည်။ Command Palette သည် အမိန့် သို့မဟုတ် လုပ်ဆောင်မှုတစ်ခုကို ရှာဖွေပြီး အမိန့်ကို အကောင်အထည်ဖော်ရန် အသုံးပြုသော အကွက်တစ်ခုဖြစ်သည်။ _View_ ကိုရွေးပြီး _Command Palette_ ကိုရွေးပါ၊ သို့မဟုတ် Ctrl-Shift-P (MacOS တွင် Command-Shift-P) ကို အသုံးပြုပါ။
သို့မဟုတ် Command Palette ကို အသုံးပြုပါ။ Command Palette သည် အမိန့် သို့မဟုတ် လုပ်ဆောင်ချက်တစ်ခုကို ရှာဖွေရန် input box တစ်ခုဖြစ်သည်။ _View_ ကိုရွေးပြီး _Command Palette_ ကို ရွေးပါ၊ သို့မဟုတ် Ctrl-Shift-P (MacOS တွင် Command-Shift-P) ကို အသုံးပြုပါ။
![Palette Menu](../../../../translated_images/palette-menu.4946174e07f426226afcdad707d19b8d5150e41591c751c45b5dee213affef91.my.png)
Command Palette ဖွင့်ပြီး _open remote repository_ ဟု ရိုက်ထည့်ပါ၊ ထို့နောက် ပထမဆုံးရွေးချယ်မှုကို ရွေးပါ။ သင်ပါဝင်သော Repository များ သို့မဟုတ် မကြာသေးမီက ဖွင့်ထားသော Repository များကို တွေ့ရပါမည်။ GitHub URL တစ်ခုကိုလည်း ရိုက်ထည့်နိုင်သည်။ အောက်ပါ URL ကို အသုံးပြုပါ -
Command Palette ဖွင့်ပြီးပါက _open remote repository_ ဟု ရိုက်ထည့်ပြီး ပထမဆုံးရွေးချယ်မှုကို ရွေးပါ။ သင့်အနီးရှိ repository များ သို့မဟုတ် သင့်ရဲ့ GitHub URL တစ်ခုကို ရိုက်ထည့်နိုင်ပါသည်။
```
https://github.com/microsoft/Web-Dev-For-Beginners
```
✅ အောင်မြင်ပါက Repository ၏ ဖိုင်အားလုံးကို အယ်ဒီတာတွင် တွေ့ရပါမည်။
✅ အောင်မြင်ပါက repository ရဲ့ ဖိုင်အားလုံးကို အယ်ဒီတာတွင် တွေ့ရမည်။
### ၂။ URL အသုံးပြုခြင်း
URL တစ်ခုကို တိုက်ရိုက်အသုံးပြု၍ Repository ကို ဖွင့်နိုင်သည်။ ဥပမာအားဖြင့် လက်ရှိ Repository ၏ URL သည် [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners) ဖြစ်သည်။ GitHub domain ကို `VSCode.dev/github` ဖြင့် အစားထိုးပြီး Repository ကို တိုက်ရိုက်ဖွင့်နိုင်သည်။ ရလဒ် URL သည် [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners) ဖြစ်ပါမည်။
URL တစ်ခုကို တိုက်ရိုက်အသုံးပြု၍ repository ကို ဖွင့်နိုင်ပါသည်။ ဥပမာအားဖြင့် [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners) သည် GitHub repository URL ဖြစ်သည်။ GitHub domain ကို `VSCode.dev/github` ဖြင့် အစားထိုးပြီး repository ကို တိုက်ရိုက်ဖွင့်နိုင်ပါသည်။ URL သည် [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners) ဖြစ်ပါမည်။
## ဖိုင်များကို ပြင်ဆင်ခြင်း
Repository ကို Browser/VSCode.dev တွင် ဖွင့်ပြီးပါက ပရောဂျက်ကို ပြင်ဆင်ရန် နောက်တစ်ဆင့်ကို ဆက်လုပ်ပါမည်။
repository ကို browser/vscode.dev တွင် ဖွင့်ပြီးပါက ပရောဂျက်ကို ပြင်ဆင်ရန် နောက်တစ်ဆင့်သို့ ရောက်ရှိပါမည်။
### ၁။ ဖိုင်အသစ်တစ်ခု ဖန်တီးခြင်း
ဖိုင်အသစ်တစ်ခုကို ရှိပြီးသားဖိုလ်ဒါအတွင်း သို့မဟုတ် Root Directory/Folder တွင် ဖန်တီးနိုင်သည်။ ဖိုင်အသစ်ဖန်တီးရန် ဖိုင်ကို သိမ်းဆည်းလိုသောနေရာ/Directory ကို ဖွင့်ပြီး _'New file ...'_ အိုင်ကွန်ကို နှိပ်ပါ၊ နာမည်ပေးပြီး Enter နှိပ်ပါ။
ဖိုင်အသစ်တစ်ခုကို ရှိပြီးသား folder အတွင်း သို့မဟုတ် root directory/folder တွင် ဖန်တီးနိုင်ပါသည်။ ဖိုင်ကို သိမ်းဆည်းလိုသည့်နေရာ/ဒိုင်ရက်ထရီကို ဖွင့်ပြီး _'New file ...'_ အိုင်ကွန်ကို နှိပ်ပါ၊ နာမည်ပေးပြီး Enter နှိပ်ပါ။
![Create a new file](../../../../translated_images/create-new-file.2814e609c2af9aeb6c6fd53156c503ac91c3d538f9cac63073b2dd4a7631f183.my.png)
### ၂။ Repository တွင် ဖိုင်ကို ပြင်ဆင်ပြီး သိမ်းဆည်းခြင်း
### ၂။ ဖိုင်တစ်ခုကို ပြင်ဆင်ပြီး သိမ်းဆည်းခြင်း
VSCode.dev ကို အသုံးပြုခြင်းသည် သင့်ပရောဂျက်ကို အလျင်အမြန် ပြင်ဆင်ရန် အထောက်အကူဖြစ်သည်။ သင့်ကုဒ်ကို ပြင်ဆင်ရန် _Explorer_ အိုင်ကွန်ကို နှိပ်ပြီး Repository အတွင်းရှိ ဖိုင်များနှင့် ဖိုလ်ဒါများကို ကြည့်ပါ။ ဖိုင်တစ်ခုကို ရွေးပြီး Code Area တွင် ဖွင့်ပါ၊ ပြင်ဆင်ပြီး သိမ်းဆည်းပါ။
vscode.dev ကို အသုံးပြုခြင်းသည် သင့်ပရောဂျက်ကို အလျင်အမြန် ပြင်ဆင်ရန် အထောက်အကူဖြစ်စေသည်။
'Explorer' အိုင်ကွန်ကို နှိပ်ပြီး repository ရဲ့ ဖိုင်များနှင့် folder များကို ကြည့်ပါ။ ဖိုင်တစ်ခုကို ရွေးပြီး code area တွင် ဖွင့်ပါ၊ ပြင်ဆင်ပြီး သိမ်းဆည်းပါ။
![Edit a file](../../../../translated_images/edit-a-file.52c0ee665ef19f08119d62d63f395dfefddc0a4deb9268d73bfe791f52c5807a.my.png)
ပြင်ဆင်မှုများပြီးပါက _`source control`_ အိုင်ကွန်ကို ရွေးပါ။
ပြောင်းလဲမှုများကို ကြည့်ရန် `Changes` folder ထဲမှ ဖိုင်(များ)ကို ရွေးပါ။ 'Working Tree' တွင် ပြောင်းလဲမှုများကို မြင်ရမည်။ အနီရောင်သည် ဖျက်ထားမှုကို ပြသပြီး အစိမ်းရောင်သည် ထည့်သွင်းမှုကို ပြသသည်။
![View changes](../../../../translated_images/working-tree.c58eec08e6335c79cc708c0c220c0b7fea61514bd3c7fb7471905a864aceac7c.my.png)
ပြောင်းလဲမှုများကို သဘောကျပါက `Changes` folder ကို hover လုပ်ပြီး `+` ခလုတ်ကို နှိပ်ပါ။
ပြောင်းလဲမှုများကို commit message ရိုက်ထည့်ပြီး `check icon` ကို နှိပ်ပါ။
GitHub.com သို့ ပြန်သွားရန် `hamburger menu icon` ကို နှိပ်ပါ။
![Stage & commit changes](../../../../8-code-editor/images/edit-vscode.dev.gif)
## Extension များ အသုံးပြုခြင်း
VSCode တွင် Extension များကို ထည့်သွင်းခြင်းဖြင့် သင့်ဖွံ့ဖြိုးတိုးတက်မှု လုပ်ငန်းစဉ်ကို တိုးတက်စေမည့် အင်္ဂါရပ်အသစ်များနှင့် စိတ်ကြိုက်ဖွဲ့စည်းမှုများကို ထည့်သွင်းနိုင်သည်။ Extension များသည် အများအားဖြင့် Generic Extension များ သို့မဟုတ် Programming Language အခြေပြု Extension များ ဖြစ်သည်။
VSCode တွင် extension များထည့်သွင်းခြင်းဖြင့် သင်ဖွံ့ဖြိုးတိုးတက်မှုအတွက် အသုံးဝင်သော features များကို ထည့်သွင်းနိုင်သည်။
---
### ၁။ Extension များ ထည့်သွင်းခြင်း
## လုပ်ငန်းတာဝန်
Search field တွင် extension ရဲ့ နာမည်ကို ရိုက်ထည့်ပြီး install ခလုတ်ကို နှိပ်ပါ။
![Install extensions](../../../../8-code-editor/images/install-extension.gif)
### ၂။ Extension များကို စိတ်ကြိုက်ပြင်ဆင်ခြင်း
Installed folder တွင် extension ကို ရွေးပြီး Gear icon > Extensions Setting ကို သွားပါ။
![Modify extension settings](../../../../translated_images/extension-settings.21c752ae4f4cdb78a867f140ccd0680e04619d0c44bb4afb26373e54b829d934.my.png)
### ၃။ Extension များကို စီမံခန့်ခွဲခြင်း
- **Disable:** Extension ကို ယာယီပိတ်ထားရန် Disable ကို ရွေးပါ။
- **Uninstall:** Extension ကို အပြီးဖျက်ရန် Uninstall ကို ရွေးပါ။
---
[VSCode.dev ကို အသုံးပြု၍ CV/Resume ဝဘ်ဆိုဒ်တစ်ခု ဖန်တီးပါ](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/8-code-editor/1-using-a-code-editor/assignment.md)
## လေ့ကျင့်ခန်း
[VSCode.dev ကို အသုံးပြု၍ CV ဝဘ်ဆိုဒ်တစ်ခု ဖန်တီးပါ](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/8-code-editor/1-using-a-code-editor/assignment.md)
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
[VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) နှင့် ၎င်း၏ အခြားအင်္ဂါရပ်များအကြောင်း ပိုမိုဖတ်ရှုပါ။
[VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) နှင့် ၎င်း၏ အခြား features များအကြောင်း ပိုမိုဖတ်ရှုပါ။
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် ရှုလေ့ရှိသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွဲအချော်အချော်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,21 +1,21 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2fcb983b8dbadadb1bc2e97f8c12dac5",
"translation_date": "2025-08-27T22:42:32+00:00",
"original_hash": "bd3aa6d2b879c30ea496c43aec1c49ed",
"translation_date": "2025-08-28T18:46:58+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/assignment.md",
"language_code": "my"
}
-->
# vscode.dev ကို အသုံးပြု၍ ရှုထောင့်ဝက်ဘ်ဆိုက် တစ်ခု ဖန်တီးပါ
# vscode.dev ကို အသုံးပြု၍ ရှင်းလင်းသော CV-Website တစ်ခု ဖန်တီးခြင်း
_သင့်ကို အလုပ်အကိုင်ရှာဖွေရေးအရာရှိက သင့်ရဲ့ ရှုထောင့်ကို တောင်းလိုက်တဲ့အခါ URL တစ်ခုပေးလိုက်တာ ဘယ်လောက်အေးမြလဲ?_ 😎
_အလုပ်ရှင်တစ်ဦးက သင့် CV ကို တောင်းလိုက်တဲ့အခါ URL တစ်ခုပေးလိုက်တာ ဘယ်လောက်အေးမြလဲ?_ 😎
## ရည်မှန်းချက်များ
ဒီအလုပ်ကို လုပ်ပြီးဆုံးတဲ့အခါ၊ သင်သည် အောက်ပါအရာများကို သင်ယူနိုင်ပါမည်-
ဒီအလုပ်ကိုပြီးစီးပြီးနောက်မှာ သင်တစ်ဦးတည်းဖြင့်:
- သင့်ရဲ့ ရှုထောင့်ကို ပြသနိုင်မည့် ဝက်ဘ်ဆိုက်တစ်ခု ဖန်တီးခြင်း
- သင့် CV ကို ပြသနိုင်မည့် website တစ်ခု ဖန်တီးနိုင်မည်
### လိုအပ်ချက်များ
@ -25,15 +25,15 @@ _သင့်ကို အလုပ်အကိုင်ရှာဖွေရေ
**အဆင့် ၁:** GitHub Repository အသစ်တစ်ခု ဖန်တီးပြီး `my-resume` ဟု အမည်ပေးပါ။
**အဆင့် ၂:** သင့် repository တွင် `index.html` ဖိုင်တစ်ခု ဖန်တီးပါ။ github.com တွင် အနည်းဆုံး ဖိုင်တစ်ခု ထည့်ရန်လိုအပ်သည်၊ အကြောင်းမူကား vscode.dev တွင် အလွတ် repository မဖွင့်နိုင်ပါ။
**အဆင့် ၂:** သင့် repository တွင် `index.html` ဖိုင်တစ်ခု ဖန်တီးပါ။ github.com တွင် ဖိုင်တစ်ခုထည့်ရန်လိုအပ်သည်၊ အကြောင်းမူမူဟာ vscode.dev တွင် အလွတ် repository မဖွင့်နိုင်ပါ။
`creating a new file` လင့်ခ်ကို နှိပ်ပြီး `index.html` ဟု အမည်ပေးပါ၊ ထို့နောက် `Commit new file` ခလုတ်ကို ရွေးပါ။
`creating a new file` လင့်ကို နှိပ်ပြီး `index.html` ဟု အမည်ပေးပါ၊ ထို့နောက် `Commit new file` ခလုတ်ကို နှိပ်ပါ။
![github.com တွင် ဖိုင်အသစ်တစ်ခု ဖန်တီးပါ](../../../../translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.my.png)
![github.com တွင် ဖိုင်အသစ်တစ်ခု ဖန်တီးခြင်း](../../../../translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.my.png)
**အဆင့် ၃:** [VSCode.dev](https://vscode.dev) ကို ဖွင့်ပြီး `Open Remote Repository` ခလုတ်ကို ရွေးပါ။
သင့်ရဲ့ ရှုထောင့်ဆိုက်အတွက် ဖန်တီးထားသော repository ၏ URL ကို ကူးယူပြီး input box တွင် ထည့်ပါ-
သင့် CV site အတွက် ဖန်တီးထားသော repository ၏ URL ကို ကူးယူပြီး input box တွင် ထည့်ပါ
_`your-username` ကို သင့် GitHub username ဖြင့် အစားထိုးပါ_
@ -41,14 +41,14 @@ _`your-username` ကို သင့် GitHub username ဖြင့် အစ
https://github.com/your-username/my-resume
```
✅ အောင်မြင်ပါက သင့် project နှင့် index.html ဖိုင်ကို browser တွင်ရှိသော text editor တွင် ဖွင့်ထားသည်ကို မြင်ရပါမည်။
✅ အောင်မြင်ပါက သင့် project နှင့် index.html ဖိုင်ကို browser တွင်ရှိသော text editor တွင် ဖွင့်ထားသည်ကို မြင်ရမည်။
![ဖိုင်အသစ်တစ်ခု ဖန်တီးပါ](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.my.png)
![ဖိုင်အသစ်တစ်ခု ဖန်တီးခြင်း](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.my.png)
**အဆင့် ၄:** `index.html` ဖိုင်ကို ဖွင့်ပြီး အောက်ပါ code ကို သင့် code area တွင် ကူးထည့်ပြီး သိမ်းဆည်းပါ။
**အဆင့် ၄:** `index.html` ဖိုင်ကို ဖွင့်ပြီး အောက်ပါ code ကို သင့် code အပိုင်းတွင် ကူးထည့်ပြီး သိမ်းပါ။
<details>
<summary><b>သင့်ရဲ့ ရှုထောင့်ဝက်ဘ်ဆိုက်၏ အကြောင်းအရာကို တာဝန်ယူသော HTML code</b></summary>
<summary><b>သင့် CV website အတွက် HTML code</b></summary>
<html>
@ -59,7 +59,7 @@ https://github.com/your-username/my-resume
</head>
<body>
<header id="header">
<!-- ရှုထောင့် header သင့်နာမည်နှင့် အလုပ်အကိုင် -->
<!-- CV header သင့်နာမည်နှင့် အလုပ်အကိုင် -->
<h1>သင့်နာမည်ကို ဒီမှာရေးပါ!</h1>
<hr>
သင့်အလုပ်အကိုင်!
@ -69,10 +69,10 @@ https://github.com/your-username/my-resume
<article id="mainLeft">
<section>
<h2>ဆက်သွယ်ရန်</h2>
<!-- ဆက်သွယ်ရန် အချက်အလက်များ -->
<!-- ဆက်သွယ်ရန်အချက်အလက်များ -->
<p>
<i class="fa fa-envelope" aria-hidden="true"></i>
<a href="mailto:username@domain.top-level domain">သင့်အီးမေးလ်ကို ဒီမှာရေးပါ</a>
<a href="mailto:username@domain.top-level domain">သင့် email ကို ဒီမှာရေးပါ</a>
</p>
<p>
<i class="fab fa-github" aria-hidden="true"></i>
@ -96,20 +96,20 @@ https://github.com/your-username/my-resume
<section>
<h2>ပညာရေး</h2>
<!-- သင့်ပညာရေး -->
<h3>သင်ယူခဲ့သော ဘာသာရပ်ကို ဒီမှာရေးပါ!</h3>
<h3>သင်ယူခဲ့သောဘာသာရပ်ကို ဒီမှာရေးပါ!</h3>
<p>
သင်ယူခဲ့သော သင်တန်းကျောင်းကို ဒီမှာရေးပါ!
သင်တက်ခဲ့သောကျောင်း/တက္ကသိုလ်ကို ဒီမှာရေးပါ!
</p>
<p>
စတင်နှစ် - ပြီးဆုံးနှစ်
စတင်နှင့်ပြီးဆုံးသည့်ရက်စွဲ
</p>
</section>
</article>
<article id="mainRight">
<section>
<h2>အကြောင်းအရာ</h2>
<h2>ကိုယ်ရေးအကျဉ်း</h2>
<!-- သင့်အကြောင်း -->
<p>သင့်အကြောင်းကို အတိုချုပ်ရေးပါ!</p>
<p>သင့်ကိုယ်ရေးအကျဉ်းကို ဒီမှာရေးပါ!</p>
</section>
<section>
<h2>အလုပ်အတွေ့အကြုံ</h2>
@ -121,7 +121,7 @@ https://github.com/your-username/my-resume
<ul>
<li>တာဝန် ၁ - သင်လုပ်ခဲ့တာရေးပါ!</li>
<li>တာဝန် ၂ - သင်လုပ်ခဲ့တာရေးပါ!</li>
<li>သင့်ရဲ့ အလုပ်အကျိုးသက်ရောက်မှုကိုရေးပါ</li>
<li>သင့်လုပ်ဆောင်မှု၏ရလဒ်/သက်ရောက်မှုကိုရေးပါ</li>
</ul>
<h3>အလုပ်အမည် ၂</h3>
@ -131,7 +131,7 @@ https://github.com/your-username/my-resume
<ul>
<li>တာဝန် ၁ - သင်လုပ်ခဲ့တာရေးပါ!</li>
<li>တာဝန် ၂ - သင်လုပ်ခဲ့တာရေးပါ!</li>
<li>သင့်ရဲ့ အလုပ်အကျိုးသက်ရောက်မှုကိုရေးပါ</li>
<li>သင့်လုပ်ဆောင်မှု၏ရလဒ်/သက်ရောက်မှုကိုရေးပါ</li>
</ul>
</section>
@ -141,14 +141,14 @@ https://github.com/your-username/my-resume
</html>
</details>
HTML code တွင် _placeholder text_ များကို သင့်ရဲ့ ရှုထောင့်အချက်အလက်များဖြင့် အစားထိုးပါ။
HTML code တွင် _placeholder text_ များကို သင့် CV အချက်အလက်များဖြင့် အစားထိုးပါ။
**အဆင့် ၅:** My-Resume folder တွင် `New File ...` icon ကို နှိပ်ပြီး သင့် project တွင် `style.css` နှင့် `codeswing.json` ဖိုင် ၂ ခု ဖန်တီးပါ။
**အဆင့် ၅:** My-Resume folder တွင် `New File ...` icon ကို နှိပ်ပြီး `style.css` နှင့် `codeswing.json` ဖိုင် ၂ ခု ဖန်တီးပါ။
**အဆင့် ၆:** `style.css` ဖိုင်ကို ဖွင့်ပြီး အောက်ပါ code ကို ကူးထည့်ပြီး သိမ်းဆည်းပါ။
**အဆင့် ၆:** `style.css` ဖိုင်ကို ဖွင့်ပြီး အောက်ပါ code ကို ကူးထည့်ပြီး သိမ်းပါ။
<details>
<summary><b>ဝက်ဘ်ဆိုက် layout ကို ဖော်ပြရန် CSS code</b></summary>
<summary><b>Website layout အတွက် CSS code</b></summary>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
@ -210,32 +210,28 @@ HTML code တွင် _placeholder text_ များကို သင့်ရ
</details>
**အဆင့် :** `codeswing.json` ဖိုင်ကို ဖွင့်ပြီး အောက်ပါ code ကို ကူးထည့်ပြီး သိမ်းဆည်းပါ။
**အဆင့် :** `codeswing.json` ဖိုင်ကို ဖွင့်ပြီး အောက်ပါ code ကို ကူးထည့်ပြီး သိမ်းပါ။
{
"scripts": [],
"styles": []
}
**အဆင့် ၇:** `Codeswing extension` ကို install လုပ်ပြီး code area တွင် ရှုထောင့်ဝက်ဘ်ဆိုက်ကို ကြည့်ရှုပါ။
**အဆင့် ၈:** `Codeswing extension` ကို install လုပ်ပြီး resume website ကို preview လုပ်ပါ။
Activity bar တွင် _`Extensions`_ icon ကို နှိပ်ပြီး Codeswing ဟု ရိုက်ထည့်ပါ။ Expanded activity bar တွင် _blue install button_ ကို နှိပ်၍ install လုပ်ပါ၊ သို့မဟုတ် extension ကို ရွေးပြီး install button ကို အသုံးပြုပါ။ Extension install ပြီးချိန်တွင် သင့် project တွင် ပြောင်းလဲမှုများကို ကြည့်ရှုနိုင်ပါမည် 😃
`Extensions` icon ကို နှိပ်ပြီး Codeswing ဟု ရိုက်ထည့်ပါ။ Install ခလုတ်ကို နှိပ်ပြီး extension ကို install လုပ်ပါ။ Install ပြီးပါက သင့် project တွင် ပြောင်းလဲမှုများကို မြင်ရမည် 😃
![Extensions install](../../../../8-code-editor/images/install-extension.gif)
Extension install ပြီးနောက် သင့် screen တွင် အောက်ပါအတိုင်း မြင်ရပါမည်
သင့် project တွင် ပြောင်းလဲမှုများကို စိတ်ကျေနပ်ပါက `Changes` folder တွင် `+` ခလုတ်ကို နှိပ်ပြီး ပြောင်းလဲမှုများကို stage လုပ်ပါ
![Codeswing extension in action](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.my.png)
ပြောင်းလဲမှုအတွက် commit message ရိုက်ထည့်ပြီး `check` ခလုတ်ကို နှိပ်ပါ။ Project အလုပ်ပြီးပါက GitHub repository သို့ ပြန်သွားရန် အပေါ်ဘက်လက်ဝဲရှိ hamburger menu icon ကို နှိပ်ပါ။
ပြောင်းလဲမှုများကို စိတ်ကျေနပ်ပါက `Changes` folder တွင် `+` button ကို နှိပ်ပြီး ပြောင်းလဲမှုများကို stage လုပ်ပါ။
ပြောင်းလဲမှုအကြောင်းဖော်ပြသော commit message ရိုက်ထည့်ပြီး `check` ကို နှိပ်ပါ။ Project အလုပ်ပြီးဆုံးပါက GitHub repository သို့ ပြန်သွားရန် အပေါ်ဘက် ဘယ်ဖက်ရှိ hamburger menu icon ကို ရွေးပါ။
ဂုဏ်ယူပါတယ် 🎉 သင်သည် vscode.dev ကို အသုံးပြု၍ ရှုထောင့်ဝက်ဘ်ဆိုက်တစ်ခုကို အဆင့်အနည်းငယ်ဖြင့် ဖန်တီးပြီးပါပြီ။
ဂုဏ်ယူပါတယ် 🎉 သင်သည် vscode.dev ကို အသုံးပြု၍ သင့် CV website ကို အဆင့်အဆင့် ဖန်တီးပြီးပါပြီ။
## 🚀 စိန်ခေါ်မှု
သင့်တွင် ပြောင်းလဲမှုများလုပ်ခွင့်ရှိသော remote repository တစ်ခု ဖွင့်ပြီး ဖိုင်များကို update လုပ်ပါ။ ထို့နောက် သင့်ပြောင်းလဲမှုများနှင့်အတူ branch အသစ်တစ်ခု ဖန်တီးပြီး Pull Request တင်ကြည့်ပါ။
သင့်တွင် ပြင်ဆင်ခွင့်ရှိသော remote repository တစ်ခု ဖွင့်ပြီး ဖိုင်များကို update လုပ်ပါ။ ထို့နောက် သင့်ပြောင်းလဲမှုများနှင့် branch အသစ်တစ်ခု ဖန်တီးပြီး Pull Request တင်ပါ။
## ပြန်လည်သုံးသပ်ခြင်းနှင့် ကိုယ်တိုင်လေ့လာခြင်း
@ -244,4 +240,4 @@ Extension install ပြီးနောက် သင့် screen တွင်
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရားရှိသော ရင်းမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူက ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွဲအချော်များ သို့မဟုတ် အနားယူမှားမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရ အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များကို အသုံးပြု၍ ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -0,0 +1,389 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "cf15ff7770c5a484349383bb27d1131f",
"translation_date": "2025-08-28T18:55:31+00:00",
"source_file": "9-chat-project/README.md",
"language_code": "my"
}
-->
# Chat project
ဒီ chat project က GitHub Models ကို အသုံးပြုပြီး Chat Assistant တစ်ခုကို ဘယ်လိုတည်ဆောက်ရမလဲဆိုတာ ပြသပေးပါတယ်။
အဆုံးသတ်ပြီးတဲ့ project ရဲ့ ရုပ်ပုံက ဒီလိုပဲဖြစ်ပါတယ်:
<div>
<img src="./assets/screenshot.png" alt="Chat app" width="600">
</div>
အနည်းငယ် context ပေးရမယ်ဆိုရင်၊ generative AI ကို အသုံးပြုပြီး Chat assistants တစ်ခုကို တည်ဆောက်တာက AI ကို စတင်လေ့လာဖို့အတွက် အကောင်းဆုံးနည်းလမ်းတစ်ခုဖြစ်ပါတယ်။ ဒီသင်ခန်းစာတစ်ခုလုံးအတွင်းမှာ generative AI ကို web app တစ်ခုထဲမှာ ပေါင်းစပ်အသုံးပြုဖို့ကို သင်လေ့လာရမှာဖြစ်ပါတယ်။ စတင်လိုက်ကြစို့။
## Generative AI ကို ချိတ်ဆက်ခြင်း
Backend အတွက် GitHub Models ကို အသုံးပြုထားပါတယ်။ AI ကို အခမဲ့အသုံးပြုနိုင်တဲ့ အကောင်းဆုံးဝန်ဆောင်မှုတစ်ခုဖြစ်ပါတယ်။ သူ့ရဲ့ playground ကို သွားပြီး သင့်ရဲ့ backend language ရွေးချယ်မှုနဲ့ ကိုက်ညီတဲ့ code ကို ရယူပါ။ GitHub Models Playground မှာ ဒီလိုပုံစံနဲ့ တွေ့ရပါမယ် [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground)
<div>
<img src="./assets/playground.png" alt="GitHub Models AI Playground" with="600">
</div>
အဆိုပါ "Code" tab ကို ရွေးချယ်ပြီး သင့်ရဲ့ runtime ကို ရွေးပါ။
<div>
<img src="./assets/playground-choice.png" alt="playground choice" with="600">
</div>
ဒီအခါမှာ Python ကို ရွေးချယ်လိုက်မယ်ဆိုရင် ဒီ code ကို ရွေးချယ်ရပါမယ်:
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
# Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "",
},
{
"role": "user",
"content": "What is the capital of France?",
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
print(response.choices[0].message.content)
```
ဒီ code ကို အသုံးပြုနိုင်ဖို့အတွက် နည်းနည်းသန့်စင်လိုက်ရအောင်:
```python
def call_llm(prompt: str, system_message: str):
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": system_message,
},
{
"role": "user",
"content": prompt,
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
return response.choices[0].message.content
```
ဒီ `call_llm` function နဲ့ prompt တစ်ခုနဲ့ system prompt တစ်ခုကို ထည့်ပြီး function က အဖြေကို ပြန်ပေးပါမယ်။
### AI Assistant ကို Customize လုပ်ခြင်း
AI assistant ကို သင့်လိုအပ်ချက်အတိုင်း ပြင်ဆင်ချင်ရင် system prompt ကို ဒီလိုပုံစံနဲ့ ပြည့်စွက်နိုင်ပါတယ်:
```python
call_llm("Tell me about you", "You're Albert Einstein, you only know of things in the time you were alive")
```
## Web API မှတစ်ဆင့် ထုတ်ဖော်ခြင်း
အကောင်းပါပဲ၊ AI အပိုင်းကို ပြီးမြောက်သွားပြီ၊ အခု Web API ထဲမှာ ပေါင်းစပ်ပေးရအောင်။ Web API အတွက် Flask ကို ရွေးချယ်ထားပါတယ်၊ ဒါပေမယ့် ဘယ် web framework မဆို အသုံးပြုနိုင်ပါတယ်။ ဒီ code ကို ကြည့်လိုက်ရအောင်:
```python
# api.py
from flask import Flask, request, jsonify
from llm import call_llm
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
@app.route("/", methods=["GET"])
def index():
return "Welcome to this API. Call POST /hello with 'message': 'my message' as JSON payload"
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
```
ဒီမှာ Flask API တစ်ခုကို ဖန်တီးပြီး "/" နဲ့ "/chat" ဆိုတဲ့ default route တွေကို သတ်မှတ်ထားပါတယ်။ "/chat" က frontend ကနေ backend ကို မေးခွန်းတွေ ပေးပို့ဖို့အတွက် ရည်ရွယ်ထားတာပါ။
*llm.py* ကို ပေါင်းစပ်ဖို့ ဒီလိုလုပ်ရပါမယ်:
- `call_llm` function ကို Import လုပ်ပါ:
```python
from llm import call_llm
from flask import Flask, request
```
- "/chat" route မှာ function ကို ခေါ်ပါ:
```python
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
```
ဒီမှာ request ကို parse လုပ်ပြီး JSON body ထဲက `message` property ကို ရယူပါတယ်။ ထို့နောက် LLM ကို ဒီလိုခေါ်ပါတယ်:
```python
response = call_llm(message, "You are a helpful assistant")
# return the response as JSON
return jsonify({
"response": response
})
```
အကောင်းပါပဲ၊ လိုအပ်တာတွေ ပြီးမြောက်သွားပါပြီ။
### Cors ကို Configure လုပ်ခြင်း
Backend နဲ့ frontend က အခြားအခြား port တွေမှာ run ဖြစ်နေတဲ့အတွက် frontend က backend ကို ခေါ်နိုင်ဖို့ CORS (cross-origin resource sharing) ကို သတ်မှတ်ပေးရပါမယ်။ *api.py* ထဲမှာ ဒီလို code ရှိပါတယ်:
```python
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
```
အခု "*" ဆိုပြီး အားလုံးကို ခွင့်ပြုထားပါတယ်၊ ဒါက production မှာ သုံးရင် အန္တရာယ်ရှိနိုင်ပါတယ်၊ ထို့ကြောင့် production သို့ ရောက်တဲ့အခါမှာ restriction ပေးဖို့လိုပါတယ်။
## Project ကို Run လုပ်ခြင်း
အခု *llm.py* နဲ့ *api.py* ရှိပြီ၊ backend နဲ့အတူ run လုပ်ဖို့ ဘယ်လိုလုပ်ရမလဲ? အခုလိုလုပ်ရပါမယ်:
- Dependencies တွေ Install လုပ်ပါ:
```sh
cd backend
python -m venv venv
source ./venv/bin/activate
pip install openai flask flask-cors openai
```
- API ကို Start လုပ်ပါ:
```sh
python api.py
```
Codespaces မှာ run လုပ်ရင် editor ရဲ့ အောက်ပိုင်းမှာ Ports ကို သွားပြီး right-click လုပ်ပါ၊ "Port Visibility" ကို click လုပ်ပြီး "Public" ကို ရွေးပါ။
### Frontend အပေါ်မှာ အလုပ်လုပ်ခြင်း
API ကို run လုပ်ပြီးပြီဆိုရင် frontend တစ်ခုကို ဖန်တီးရပါမယ်။ အနည်းဆုံး frontend ကို စတင်ပြီး အဆင့်ဆင့် တိုးတက်အောင်လုပ်ရပါမယ်။ *frontend* folder ထဲမှာ ဒီလိုဖိုင်တွေ ဖန်တီးပါ:
```text
backend/
frontend/
index.html
app.js
styles.css
```
**index.html** ကို စတင်ကြည့်လိုက်ရအောင်:
```html
<html>
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<form>
<textarea id="messages"></textarea>
<input id="input" type="text" />
<button type="submit" id="sendBtn">Send</button>
</form>
<script src="app.js" />
</body>
</html>
```
အထက်မှာ chat window ကို support လုပ်ဖို့အတွက် အနည်းဆုံးလိုအပ်တဲ့အရာတွေပါ။ textarea တစ်ခုမှာ message တွေကို ပြသပေးပြီး၊ input တစ်ခုမှာ message ကို ရိုက်ထည့်နိုင်ပါတယ်၊ button တစ်ခုက message ကို backend ကို ပေးပို့ဖို့အတွက် အသုံးပြုပါတယ်။ *app.js* ထဲမှာ JavaScript ကို ကြည့်လိုက်ရအောင်:
**app.js**
```js
// app.js
(function(){
// 1. set up elements
const messages = document.getElementById("messages");
const form = document.getElementById("form");
const input = document.getElementById("input");
const BASE_URL = "change this";
const API_ENDPOINT = `${BASE_URL}/hello`;
// 2. create a function that talks to our backend
async function callApi(text) {
const response = await fetch(API_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: text })
});
let json = await response.json();
return json.response;
}
// 3. add response to our textarea
function appendMessage(text, role) {
const el = document.createElement("div");
el.className = `message ${role}`;
el.innerHTML = text;
messages.appendChild(el);
}
// 4. listen to submit events
form.addEventListener("submit", async(e) => {
e.preventDefault();
// someone clicked the button in the form
// get input
const text = input.value.trim();
appendMessage(text, "user")
// reset it
input.value = '';
const reply = await callApi(text);
// add to messages
appendMessage(reply, "assistant");
})
})();
```
Code ကို အပိုင်းလိုက် ရှင်းပြလိုက်ရအောင်:
- 1) Element တွေကို reference လုပ်ပြီး နောက် code မှာ အသုံးပြုဖို့အတွက် ရယူထားပါတယ်။
- 2) Backend ကို ခေါ်ဖို့ built-in `fetch` method ကို အသုံးပြုတဲ့ function တစ်ခုကို ဖန်တီးထားပါတယ်။
- 3) `appendMessage` က user ရဲ့ message နဲ့ assistant ရဲ့ response ကို textarea ထဲမှာ ထည့်ပေးပါတယ်။
- 4) Submit event ကို နားထောင်ပြီး input field ကို ဖတ်ယူပြီး၊ user ရဲ့ message ကို textarea ထဲမှာ ထည့်ပေးပြီး API ကို ခေါ်ပြီး response ကို textarea ထဲမှာ ပြသပေးပါတယ်။
Styling ကို ကြည့်လိုက်ရအောင်၊ ဒီမှာ သင့်စိတ်ကြိုက် ပြင်ဆင်နိုင်ပါတယ်၊ ဒါပေမယ့် အောက်ပါအတိုင်း အကြံပေးလိုက်ပါတယ်:
**styles.css**
```
.message {
background: #222;
box-shadow: 0 0 0 10px orange;
padding: 10px:
margin: 5px;
}
.message.user {
background: blue;
}
.message.assistant {
background: grey;
}
```
ဒီ three classes တွေက message တွေကို assistant ကနေလာတာလား၊ user ကနေလာတာလားဆိုတာကို ခွဲခြားပြီး style ပေးပါတယ်။ အခြား design အတွက် `solution/frontend/styles.css` folder ကို ကြည့်ပါ။
### Base Url ကို ပြောင်းလဲခြင်း
ဒီမှာ `BASE_URL` ကို မသတ်မှတ်ထားသေးပါဘူး၊ backend ကို start လုပ်မှ သိနိုင်ပါတယ်။ သတ်မှတ်ဖို့:
- API ကို locally run လုပ်ရင် `http://localhost:5000` လို့ သတ်မှတ်ပါ။
- Codespaces မှာ run လုပ်ရင် "[name]app.github.dev" လို့ ဖြစ်နိုင်ပါတယ်။
## Assignment
*project* folder ကို ဖန်တီးပြီး အောက်ပါအတိုင်း content ထည့်ပါ:
```text
project/
frontend/
index.html
app.js
styles.css
backend/
api.py
llm.py
```
အထက်မှာ ပြောထားတဲ့အတိုင်း content ကို copy လုပ်ပြီး သင့်စိတ်ကြိုက် ပြင်ဆင်နိုင်ပါတယ်။
## Solution
[Solution](./solution/README.md)
## Bonus
AI assistant ရဲ့ personality ကို ပြောင်းလဲကြည့်ပါ။ *api.py* ထဲမှာ `call_llm` ကို ခေါ်တဲ့အခါမှာ ဒုတိယ argument ကို သင့်လိုအပ်ချက်အတိုင်း ပြောင်းလဲနိုင်ပါတယ်၊ ဥပမာ:
```python
call_llm(message, "You are Captain Picard")
```
CSS နဲ့ text ကိုလည်း သင့်စိတ်ကြိုက် ပြောင်းလဲနိုင်ပါတယ်၊ *index.html* နဲ့ *styles.css* ထဲမှာ ပြင်ဆင်ပါ။
## Summary
အကောင်းပါပဲ၊ AI ကို အသုံးပြုပြီး personal assistant တစ်ခုကို ဘယ်လိုတည်ဆောက်ရမလဲဆိုတာ အခြေခံကနေ သင်ယူနိုင်ခဲ့ပါပြီ။ GitHub Models ကို အသုံးပြုပြီး Python backend နဲ့ HTML, CSS, JavaScript frontend ကို အသုံးပြုပြီး တည်ဆောက်ခဲ့ပါတယ်။
## Set up with Codespaces
- သွားပါ: [Web Dev For Beginners repo](https://github.com/microsoft/Web-Dev-For-Beginners)
- Template မှာ ဖန်တီးပါ (GitHub မှာ login လုပ်ထားတာ သေချာပါစေ) အပေါ်ညာဘက်မှာ:
![Create from template](../../../translated_images/template.67ad477109d29a2b04599a83c964c87fcde041256d4f04d3589cbb00c696f76c.my.png)
- သင့် repo ထဲမှာ Codespace တစ်ခု ဖန်တီးပါ:
![Create codespace](../../../translated_images/codespace.bcecbdf5d2747d3d17da67a78ad911c8853d68102e34748ec372cde1e9236e1d.my.png)
ဒီဟာ environment တစ်ခုကို စတင်ပေးပါမယ်၊ အခု သင့်အနေနဲ့ အလုပ်လုပ်နိုင်ပါပြီ။
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရ အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -0,0 +1,55 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "a7b7f54b13f9e6683a844d173ffdd766",
"translation_date": "2025-08-28T18:56:09+00:00",
"source_file": "9-chat-project/solution/README.md",
"language_code": "my"
}
-->
# ကုဒ်ကို အလုပ်လုပ်စေပါ
## အဆင့်ဆင့် ပြင်ဆင်ခြင်း
Virtual environment တစ်ခု ဖန်တီးပါ
```sh
cd backend
python -m venv venv
source ./venv/bin/activate
```
## လိုအပ်သော dependencies များ ထည့်သွင်းပါ
```sh
pip install openai flask flask-cors
```
## API ကို အလုပ်လုပ်စေပါ
```sh
python api.py
```
## Frontend ကို အလုပ်လုပ်စေပါ
Frontend folder အတွင်းမှာ ရှိနေကြောင်း သေချာပါ
*app.js* ကို ရှာဖွေပြီး `BASE_URL` ကို backend URL သို့ ပြောင်းပါ
အလုပ်လုပ်စေပါ
```
npx http-server -p 8000
```
Chat မှာ စာသားတစ်ခု ရိုက်ထည့်ကြည့်ပါ၊ Codespace မှာ အလုပ်လုပ်နေသည်ဟု သေချာပါက သို့မဟုတ် access token ကို ပြင်ဆင်ပြီးသားဖြစ်ပါက တုံ့ပြန်မှုကို မြင်ရပါမည်။
## Access token ကို ပြင်ဆင်ပါ (Codespace မှာ မလုပ်ဆောင်ပါက)
[Set up PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) ကို ကြည့်ပါ
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရ အရင်းအမြစ်အဖြစ် ရှုလေ့လာသင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားယူမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "efa251c5fc089367f0a81c572874afca",
"translation_date": "2025-08-28T10:50:31+00:00",
"original_hash": "687c62646ad5595f1ba733edc294cdae",
"translation_date": "2025-08-28T18:26:44+00:00",
"source_file": "README.md",
"language_code": "my"
}
@ -23,177 +23,178 @@ CO_OP_TRANSLATOR_METADATA:
[![Microsoft Azure AI Foundry Discord](https://dcbadge.limes.pink/api/server/ByRwuEEgH4)](https://discord.com/invite/ByRwuEEgH4)
ဤအရင်းအမြစ်များကို စတင်အသုံးပြုရန် အောက်ပါအဆင့်များကို လိုက်နာပါ-
ဤအရင်းအမြစ်များကို အသုံးပြုရန်အဆင့်များကို လိုက်နာပါ-
1. **Repository ကို Fork လုပ်ပါ**: [![GitHub forks](https://img.shields.io/github/forks/microsoft/Web-Dev-For-beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/fork) ကိုနှိပ်ပါ
2. **Repository ကို Clone လုပ်ပါ**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
3. [**Azure AI Foundry Discord ကို Join လုပ်ပြီး ကျွမ်းကျင်သူများနှင့် Developer များနှင့်တွေ့ဆုံပါ**](https://discord.com/invite/ByRwuEEgH4)
3. [**Azure AI Foundry Discord ကို Join လုပ်ပြီး ကျွမ်းကျင်သူများနှင့် Developer မိတ်ဆွေများနှင့် တွေ့ဆုံပါ**](https://discord.com/invite/ByRwuEEgH4)
# စတင်သူများအတွက် Web Development - သင်ရိုး
Microsoft Cloud Advocates မှ 12 ပတ်ကြာ သင်ရိုးတစ်ခုဖြင့် Web Development အခြေခံများကို သင်ယူပါ။ JavaScript, CSS, HTML တို့ကို terrariums, browser extensions, space games စသည့် လက်တွေ့လုပ်ငန်းများဖြင့် သင်ကြားပေးပါသည်။ Quiz များ၊ ဆွေးနွေးပွဲများနှင့် လက်တွေ့အလုပ်များဖြင့် ပါဝင်ဆောင်ရွက်ပါ။ သင်၏ကျွမ်းကျင်မှုများကို တိုးတက်စေပြီး သင်ယူမှုကို ပိုမိုထိရောက်စေမည့် Project-based သင်ကြားမှုနည်းလမ်းဖြင့် သင်တန်းကို စတင်လိုက်ပါ။
# Beginner များအတွက် Web Development - သင်ခန်းစာများ
#### 🧑‍🎓 _ကျောင်းသားလား?_
[**Student Hub page**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon) ကို သွားရောက်ကြည့်ရှုပါ။ အခြေခံအရင်းအမြစ်များ၊ ကျောင်းသားအထုပ်များနှင့် အခမဲ့လက်မှတ်ရယူနိုင်မည့် နည်းလမ်းများကို တွေ့နိုင်ပါသည်။ ဤစာမျက်နှာကို Bookmark လုပ်ထားပြီး လစဉ်အကြောင်းအရာများပြောင်းလဲသည့်အခါ ပြန်လည်ကြည့်ရှုပါ။
Microsoft Cloud Advocates မှ 12-ပတ်ကြာ သင်ခန်းစာများဖြင့် Web Development အခြေခံများကို လေ့လာပါ။ 24 သင်ခန်းစာများတွင် JavaScript, CSS, HTML ကို terrariums, browser extensions, space games စသည်တို့ကဲ့သို့သော လက်တွေ့လုပ်ငန်းများမှတစ်ဆင့် လေ့လာနိုင်ပါသည်။ Quiz များ၊ ဆွေးနွေးမှုများနှင့် လက်တွေ့အလုပ်များကို ပါဝင်စေပြီး သင်၏ကျွမ်းကျင်မှုများကို တိုးတက်စေပါသည်။ Project-based သင်ကြားမှုနည်းလမ်းများဖြင့် သင်၏ အသိပညာကို အထူးပြုစေပါ။ Coding ခရီးစဉ်ကို ယနေ့စတင်လိုက်ပါ!
### 📣 ကြေညာချက် - _Generative AI သင်ရိုး_ အသစ်ကို မကြာသေးမီက ထုတ်ပြန်ခဲ့သည်
Generative AI သင်ရိုးအသစ်ကို လက်မလွှတ်ပါနှင့်!
### 🌐 Multi-Language Support
[https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) သို့ သွားရောက်ပြီး စတင်လိုက်ပါ!
#### GitHub Action မှတစ်ဆင့် အလိုအလျောက် အမြဲ Update ဖြစ်နေသော ဘာသာစကားများ
![Background](../../translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.my.png)
- အခြေခံမှ RAG အထိ သင်ခန်းစာများ
- GenAI နှင့် အပလီကေးရှင်းကို အသုံးပြု၍ သမိုင်းဆိုင်ရာ ဇာတ်ကောင်များနှင့် အပြန်အလှန်ဆွေးနွေးပါ
- စိတ်ဝင်စားဖွယ် ဇာတ်လမ်းတစ်ခုဖြင့် အချိန်ခရီးသွားပါ!
![character](../../translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.my.png)
သင်ခန်းစာတိုင်းတွင် အလုပ်ပေးစာ, သိမှတ်စရာများနှင့် စိန်ခေါ်မှုများ ပါဝင်ပြီး အောက်ပါအကြောင်းအရာများကို သင်ယူနိုင်ပါသည်-
- Prompting နှင့် Prompt Engineering
- Text နှင့် Image App ဖန်တီးခြင်း
- Search Apps
[https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) သို့ သွားရောက်ပြီး စတင်လိုက်ပါ!
[French](../fr/README.md) | [Spanish](../es/README.md) | [German](../de/README.md) | [Russian](../ru/README.md) | [Arabic](../ar/README.md) | [Persian (Farsi)](../fa/README.md) | [Urdu](../ur/README.md) | [Chinese (Simplified)](../zh/README.md) | [Chinese (Traditional, Macau)](../mo/README.md) | [Chinese (Traditional, Hong Kong)](../hk/README.md) | [Chinese (Traditional, Taiwan)](../tw/README.md) | [Japanese](../ja/README.md) | [Korean](../ko/README.md) | [Hindi](../hi/README.md) | [Bengali](../bn/README.md) | [Marathi](../mr/README.md) | [Nepali](../ne/README.md) | [Punjabi (Gurmukhi)](../pa/README.md) | [Portuguese (Portugal)](../pt/README.md) | [Portuguese (Brazil)](../br/README.md) | [Italian](../it/README.md) | [Polish](../pl/README.md) | [Turkish](../tr/README.md) | [Greek](../el/README.md) | [Thai](../th/README.md) | [Swedish](../sv/README.md) | [Danish](../da/README.md) | [Norwegian](../no/README.md) | [Finnish](../fi/README.md) | [Dutch](../nl/README.md) | [Hebrew](../he/README.md) | [Vietnamese](../vi/README.md) | [Indonesian](../id/README.md) | [Malay](../ms/README.md) | [Tagalog (Filipino)](../tl/README.md) | [Swahili](../sw/README.md) | [Hungarian](../hu/README.md) | [Czech](../cs/README.md) | [Slovak](../sk/README.md) | [Romanian](../ro/README.md) | [Bulgarian](../bg/README.md) | [Serbian (Cyrillic)](../sr/README.md) | [Croatian](../hr/README.md) | [Slovenian](../sl/README.md) | [Ukrainian](../uk/README.md) | [Burmese (Myanmar)](./README.md)
## 🌱 စတင်ရန်
> **ဆရာများ**, ဤသင်ရိုးကို အသုံးပြုရန် အကြံပြုချက်များကို [ဒီမှာ](for-teachers.md) ထည့်သွင်းထားပါသည်။ သင်၏အကြံပြုချက်များကို [ဆွေးနွေးပွဲဖိုရမ်](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner) တွင် မျှဝေပါ။
**[သင်ယူသူများ](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**, သင်ခန်းစာတိုင်းအတွက် Pre-lecture Quiz ဖြင့် စတင်ပြီး သင်ခန်းစာအကြောင်းအရာကို ဖတ်ရှုပါ။ လှုပ်ရှားမှုများကို ပြီးမြောက်စေပြီး Post-lecture Quiz ဖြင့် သင်၏နားလည်မှုကို စစ်ဆေးပါ။
သင်ယူမှုအတွေ့အကြုံကို ပိုမိုကောင်းမွန်စေရန် သင်၏အတန်းဖော်များနှင့် ပူးပေါင်းဆောင်ရွက်ပါ! [ဆွေးနွေးပွဲဖိုရမ်](https://github.com/microsoft/Web-Dev-For-Beginners/discussions) တွင် ဆွေးနွေးမှုများကို လှုံ့ဆော်ပြီး သင်၏မေးခွန်းများကို ဖြေကြားပေးမည့် Moderator များရှိပါသည်။
သင်၏ပညာရေးကို ပိုမိုတိုးတက်စေရန် [Microsoft Learn](https://learn.microsoft.com/users/wirelesslife/collections/p1ddcy5jwy0jkm?WT.mc_id=academic-77807-sagibbon) တွင် ထပ်မံလေ့လာရန် အကြံပြုပါသည်။
### 📋 သင့်ပတ်ဝန်းကျင်ကို ပြင်ဆင်ခြင်း
ဤသင်ရိုးသည် ဖွံ့ဖြိုးရေးပတ်ဝန်းကျင်ကို အသင့်ဖြစ်စေပါသည်! သင်စတင်လိုက်သောအခါ [Codespace](https://github.com/features/codespaces/) (_Browser-based, Install မလိုအပ်သော ပတ်န်းကျင်_) သို့မဟုတ် သင်၏ကွန်ပျူတာတွင် [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) ကဲ့သို့သော Text Editor ကို အသုံးပြု၍ လုပ်ဆောင်နိုင်ပါသည်။
#### သင်၏ Repository ကို ဖန်တီးပါ
သင်၏အလုပ်ကို လွယ်ကူစွာ သိမ်းဆည်းနိုင်ရန် သင်၏ Repository ကို ဖန်တီးရန် အကြံပြုပါသည်။ ဤသင်ရိုး၏ မိတ္တူတစ်ခုကို သင်၏ GitHub အကောင့်တွင် ဖန်တီးရန် **Use this template** ခလုတ်ကို နှိပ်ပါ။
အဆင့်များကို လိုက်နာပါ-
1. **Repository ကို Fork လုပ်ပါ**: ဤစာမျက်နှာ၏ အပေါ်ညာဘက်ထောင့်ရှိ "Fork" ခလုတ်ကို နှိပ်ပါ။
2. **Repository ကို Clone လုပ်ပါ**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
**အပိုဘာသာစကားများကို ထည့်သွင်းလိုပါက [ဒီနေရာ](https://github.com/Azure/co-op-translator/blob/main/getting_started/supported-languages.md) တွင် ရှာဖွေပါ**
#### Codespace တွင် သင်ရိုးကို လည်ပတ်ခြင်း
သင်ဖန်တီးထားသော Repository တွင် **Code** ခလုတ်ကို နှိပ်ပြီး **Open with Codespaces** ကို ရွေးချယ်ပါ။ ဤသည် သင်အလုပ်လုပ်ရန် Codespace အသစ်တစ်ခုကို ဖန်တီးပေးပါမည်။
#### 🧑‍🎓 _ကျောင်းသားများအတွက်_
[!Codespace](./images/createcodespace.png)
[**Student Hub page**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon) ကို သွားရောက်လေ့လာပါ။ အစပြုသူများအတွက် အရင်းအမြစ်များ၊ Student packs များနှင့် အခမဲ့လက်မှတ် voucher ရယူနိုင်သော နည်းလမ်းများကို တွေ့နိုင်ပါသည်။ ဤစာမျက်နှာကို Bookmark လုပ်ထားပြီး လစဉ်အကြောင်းအရာများ ပြောင်းလဲသည့်အခါ ပြန်လည်ကြည့်ရှုပါ။
#### သင်၏ကွန်ပျူတာတွင် သင်ရိုးကို လည်ပတ်ခြင်း
သင်၏ကွန်ပျူတာတွင် သင်ရိုးကို လည်ပတ်ရန် Text Editor, Browser နှင့် Command Line Tool တို့လိုအပ်ပါမည်။ ကျွန်ုပ်တို့၏ ပထမဆုံးသင်ခန်းစာ [Programming Languages နှင့် Tools of the Trade အကြောင်းအရာ](../../1-getting-started-lessons/1-intro-to-programming-languages) တွင် သင့်အတွက် အကောင်းဆုံးဖြစ်မည့် Tools များကို ရွေးချယ်ရန် လမ်းညွှန်ထားပါသည်။
### 📣 ကြေညာချက် - _Generative AI အသုံးပြု၍ Project အသစ်တည်ဆောက်ရန်_
ကျွန်ုပ်တို့၏ အကြံပြုချက်မှာ [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) ကို Editor အဖြစ် အသုံးပြုရန် ဖြစ်ပြီး၊ ဤသည်တွင် [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) ပါဝင်သည်။ Visual Studio Code ကို [ဤနေရာတွင်](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) ဒေါင်းလုပ်လုပ်ပါ။
AI Assistant Project အသစ်ကို ထည့်သွင်းထားပြီး [project](./09-chat-project/README.md) တွင် ကြည့်ရှုပါ။
1. သင်၏ Repository ကို သင်၏ကွန်ပျူတာသို့ Clone လုပ်ပါ။ **Code** ခလုတ်ကို နှိပ်ပြီး URL ကို ကူးယူပါ-
### 📣 ကြေညာချက် - _Generative AI Curriculum_ အသစ်ကို JavaScript အတွက် ထုတ်ဝေထားပါသည်
[!CodeSpace](./images/createcodespace.png)
Generative AI Curriculum အသစ်ကို လက်မလွှတ်ပါနှင့်!
ထို့နောက်, [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) တွင် [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) ကို ဖွင့်ပြီး အောက်ပါ Command ကို လုပ်ဆောင်ပါ-
[https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) သို့ သွားရောက်ပြီး စတင်ပါ!
```bash
git clone <your-repository-url>
```
![Background](../../translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.my.png)
2. Visual Studio Code တွင် Folder ကို ဖွင့်ပါ။ **File** > **Open Folder** ကို နှိပ်ပြီး သင် Clone လုပ်ထားသော Folder ကို ရွေးချယ်ပါ။
- အခြေခံမှ RAG အထိ သင်ခန်းစာများ
- GenAI နှင့် အကူအညီ App ကို အသုံးပြု၍ သမိုင်းဆိုင်ရာ လူပုဂ္ဂိုလ်များနှင့် အပြန်အလှန် ဆွေးနွေးပါ
- စိတ်ဝင်စားဖွယ် ဇာတ်လမ်းတစ်ပုဒ်ဖြင့် အချိန်ခရီးသွားပါ!
> Visual Studio Code အတွက် အကြံပြု Extension များ-
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - HTML စာမျက်နှာများကို Visual Studio Code တွင် ကြည့်ရှုရန်
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - Code ကို ပိုမိုမြန်ဆန်စွာ ရေးရန်
![character](../../translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.my.png)
## 📂 သင်ခန်းစာတိုင်းတွင် ပါဝင်သည်-
- စိတ်ကြိုက် Sketchnote
- အပို Supplemental Video
- Pre-lesson Warmup Quiz
- ရေးသားထားသော သင်ခန်းစာ
- Project-based သင်ခန်းစာများအတွက် လုပ်ငန်းဆောင်ရွက်ရန် လမ်းညွှန်ချက်များ
- သိမှတ်စရာများ
- စိန်ခေါ်မှု
- အပိုစာဖတ်ရန်
- အလုပ်ပေးစာ
- [Post-lesson Quiz](https://ff-quizzes.netlify.app/web/)
သင်ခန်းစာတိုင်းတွင် လုပ်ငန်းတာဝန်များ၊ အသိပညာစစ်ဆေးမှုများနှင့် အခန်းကဏ္ဍများ ပါဝင်ပြီး အောက်ပါအကြောင်းအရာများကို လေ့လာရန် လမ်းညွှန်ပါသည်-
- Prompting နှင့် Prompt Engineering
- Text နှင့် Image App တည်ဆောက်ခြင်း
- Search Apps
> **Quiz များအကြောင်းမှတ်ချက်**: Quiz များအားလုံးကို Quiz-app Folder တွင် ထည့်သွင်းထားပြီး၊ 48 ခုရှိသည်။ Quiz တစ်ခုစီတွင် 3 မေးခွန်းပါဝင်သည်။ [ဤနေရာတွင်](https://ff-quizzes.netlify.app/web/) ရရှိနိုင်ပြီး၊ Quiz App ကို Local တွင် သို့မဟုတ် Azure တွင် တင်နိုင်ပါသည်။ `quiz-app` Folder တွင် လမ်းညွှန်ချက်များကို လိုက်နာပါ။
[https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) သို့ သွားရောက်ပြီး စတင်ပါ!
## 🗃️ သင်ခန်းစာမျာ
## 🌱 စတင်အသုံးပြုခြင်း
| | Project Name | Concepts Taught | Learning Objectives | Linked Lesson | Author |
| :-: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :---------------------: |
| 01 | Getting Started | Programming နှင့် Tools of the Trade အကြောင်းအရာများ | Programming Language များနှင့် Professional Developer များအလုပ်လုပ်ရန် အသုံးပြုသော Software များအကြောင်းကို သင်ယူပါ | [Intro to Programming Languages and Tools of the Trade](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | Getting Started | GitHub အခြေခံများ၊ အဖွဲ့နှင့်အတူ အလုပ်လုပ်ခြင်း | GitHub ကို သင်၏ Project တွင် အသုံးပြုနည်း၊ အခြားသူများနှင့် Code Base တွင် ပူးပေါင်းဆောင်ရွက်နည်း | [Intro to GitHub](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | Getting Started | Accessibility | Web Accessibility အခြေခံများကို သင်ယူပါ | [Accessibility Fundamentals](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | JS Basics | JavaScript Data Types | JavaScript Data Types အခြေခံများ | [Data Types](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | JS Basics | Functions and Methods | Application Logic Flow ကို စီမံရန် Functions နှင့် Methods အကြောင်းကို သင်ယူပါ | [Functions and Methods](./2-js-basics/2-functions-methods/README.md) | Jasmine and Christopher |
| 06 | JS Basics | Making Decisions with JS | Decision-making နည်းလမ်းများကို အသုံးပြု၍ သင်၏ Code တွင် Conditions ဖန်တီးနည်း | [Making Decisions](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | JS Basics | Arrays and Loops | JavaScript တွင် Arrays နှင့် Loops ကို အသုံးပြု၍ Data ကို စီမံပါ | [Arrays and Loops](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [Terrarium](./3-terrarium/solution/README.md) | HTML in Practice | Online Terrarium တစ်ခု ဖန်တီးရန် HTML ကို အသုံးပြု၍ Layout တစ်ခုကို ဖန်တီးပါ | [Introduction to HTML](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [Terrarium](./3-terrarium/solution/README.md) | CSS in Practice | Online Terrarium ကို Style ပြုလုပ်ရန် CSS ကို အသုံးပြုပါ၊ CSS အခြေခံများနှင့် Page ကို Responsive ဖြစ်စေရန် အခြေခံများကို သင်ယူပါ | [Introduction to CSS](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [Terrarium](./3-terrarium/solution/README.md) | JavaScript Closures, DOM manipulation | JavaScript ကို အသုံးပြု၍ terrarium ကို drag/drop အင်တာဖေ့စ်အဖြစ် လုပ်ဆောင်နိုင်ရန် closures နှင့် DOM ကိုင်တွယ်မှုကို အာရုံစိုက်ပါ။ | [JavaScript Closures, DOM manipulation](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [Typing Game](./4-typing-game/solution/README.md) | Build a Typing Game | JavaScript app ၏ logic ကို keyboard events အသုံးပြု၍ လေ့လာပါ။ | [Event-Driven Programming](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Working with Browsers | Browser များအလုပ်လုပ်ပုံ၊ ၎င်းတို့၏ သမိုင်းကြောင်းနှင့် browser extension ၏ ပထမဆုံး အစိတ်အပိုင်းများကို စတင်ဖွဲ့စည်းပုံကို လေ့လာပါ။ | [About Browsers](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Building a form, calling an API and storing variables in local storage | Browser extension ၏ JavaScript အစိတ်အပိုင်းများကို API ကို local storage တွင် သိမ်းဆည်းထားသော variable များ အသုံးပြု၍ ဖန်တီးပါ။ | [APIs, Forms, and Local Storage](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Background processes in the browser, web performance | Browser ၏ background processes ကို အသုံးပြု၍ extension ၏ icon ကို စီမံခန့်ခွဲပါ၊ web performance နှင့် အချို့သော optimization များကို လေ့လာပါ။ | [Background Tasks and Performance](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [Space Game](./6-space-game/solution/README.md) | More Advanced Game Development with JavaScript | Class နှင့် Composition နှစ်မျိုးစလုံးကို အသုံးပြု၍ Inheritance ကို လေ့လာပြီး Pub/Sub pattern ကို သင်ယူပါ။ | [Introduction to Advanced Game Development](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [Space Game](./6-space-game/solution/README.md) | Drawing to canvas | Canvas API ကို အသုံးပြု၍ screen ပေါ်တွင် element များကို ရေးဆွဲပုံကို လေ့လာပါ။ | [Drawing to Canvas](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [Space Game](./6-space-game/solution/README.md) | Moving elements around the screen | Cartesian coordinates နှင့် Canvas API ကို အသုံးပြု၍ element များကို ရွေ့လျားပုံကို ရှာဖွေပါ။ | [Moving Elements Around](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [Space Game](./6-space-game/solution/README.md) | Collision detection | Keypress များကို အသုံးပြု၍ element များကို တိုက်ဆိုင်စေပြီး game ၏ performance ကို အာရုံစိုက်ရန် cooldown function ကို ပံ့ပိုးပါ။ | [Collision Detection](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [Space Game](./6-space-game/solution/README.md) | Keeping score | Game ၏ အခြေအနေနှင့် performance အပေါ် မူတည်၍ သင်္ချာတွက်ချက်မှုများကို လုပ်ဆောင်ပါ။ | [Keeping Score](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [Space Game](./6-space-game/solution/README.md) | Ending and restarting the game | Game ကို အဆုံးသတ်ခြင်းနှင့် ပြန်လည်စတင်ခြင်းအကြောင်း၊ asset များကို ရှင်းလင်းခြင်းနှင့် variable တန်ဖိုးများကို ပြန်လည်သတ်မှတ်ခြင်းကို လေ့လာပါ။ | [The Ending Condition](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [Banking App](./7-bank-project/solution/README.md) | HTML Templates and Routes in a Web App | Routing နှင့် HTML templates ကို အသုံးပြု၍ multipage website architecture ၏ scaffold ကို ဖန်တီးပုံကို လေ့လာပါ။ | [HTML Templates and Routes](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [Banking App](./7-bank-project/solution/README.md) | Build a Login and Registration Form | Form များကို ဖန်တီးခြင်းနှင့် validation routine များကို ကိုင်တွယ်ပုံကို လေ့လာပါ။ | [Forms](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [Banking App](./7-bank-project/solution/README.md) | Methods of Fetching and Using Data | App ၏ data များကို ဘယ်လို ရယူ၊ သိမ်းဆည်း၊ နှင့် ဖယ်ရှားရမည်ကို လေ့လာပါ။ | [Data](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [Banking App](./7-bank-project/solution/README.md) | Concepts of State Management | App ၏ state ကို ဘယ်လို သိမ်းဆည်းပြီး programmatically စီမံခန့်ခွဲရမည်ကို လေ့လာပါ။ | [State Management](./7-bank-project/4-state-management/README.md) | Yohan |
> **ဆရာများ**၊ ဤသင်ခန်းစာများကို အသုံးပြုရန် အကြံပြုချက်များကို [ဒီနေရာ](for-teachers.md) တွင် ထည့်သွင်းထားပါသည်။ [ဆရာများအတွက် ဆွေးနွေးမှုဖိုရမ်](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner) တွင် သင့်အကြံပြုချက်များကို မျှဝေပါ!
**[သင်ယူသူများ](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**၊ သင်ခန်းစာတိုင်းအတွက် Pre-lecture Quiz ဖြင့် စတင်ပြီး သင်ခန်းစာအကြောင်းအရာများကို ဖတ်ရှုပါ၊ လုပ်ငန်းများကို ပြီးမြောက်စေပြီး Post-lecture Quiz ဖြင့် သင်၏နားလည်မှုကို စစ်ဆေးပါ။
## 🏫 သင်ကြားမှုနည်းလမ်း
သင်ယူမှုအတွေ့အကြုံကို မြှင့်တင်ရန် မိတ်ဆွေများနှင့် ပူးပေါင်းပြီး Project များကို အတူတူလုပ်ဆောင်ပါ! [ဆွေးနွေးမှုဖိုရမ်](https://github.com/microsoft/Web-Dev-For-Beginners/discussions) တွင် ဆွေးနွေးမှုများကို လှုံ့ဆော်ပြီး ကျွန်ုပ်တို့၏ Moderator အဖွဲ့သည် သင့်မေးခွန်းများကို ဖြေကြားပေးပါမည်။
ကျွန်ုပ်တို့၏ သင်ရိုးညွှန်းတန်းကို အဓိက သင်ကြားမှုနည်းလမ်းနှစ်ခုအပေါ် အခြေခံထားပါသည်။
* စီမံကိန်းအခြေပြု သင်ကြားမှု
* မကြာခဏ စစ်ဆေးမှုများ
သင်၏ပညာရေးကို တိုးတက်စေရန် [Microsoft Learn](https://learn.microsoft.com/users/wirelesslife/collections/p1ddcy5jwy0jkm?WT.mc_id=academic-77807-sagibbon) ကို လေ့လာရန် အထူးအကြံပြုပါသည်။
ဒီအစီအစဉ်က JavaScript, HTML, CSS ၏ အခြေခံများနှင့် ယနေ့၏ web developer များ အသုံးပြုနေသော နောက်ဆုံးပေါ် ကိရိယာများနှင့် နည်းလမ်းများကို သင်ကြားပေးပါသည်။ ကျောင်းသားများသည် typing game, virtual terrarium, သဘာဝပတ်ဝန်းကျင်နှင့် သင့်တော်သော browser extension, space-invader ပုံစံ game, နှင့် စီးပွားရေးလုပ်ငန်းများအတွက် banking app တို့ကို ဖန်တီးခြင်းအားဖြင့် လက်တွေ့အတွေ့အကြုံ ရရှိမည်ဖြစ်သည်။ သင်ရိုးညွှန်းတန်း၏ အဆုံးတွင် ကျောင်းသားများသည် web development အပေါ် အခြေခံအားကောင်းသော နားလည်မှု ရရှိမည်ဖြစ်သည်။
### 📋 သင့်ပတ်ဝန်းကျင်ကို စတင်တပ်ဆင်ခြင်း
> 🎓 ဒီသင်ရိုးညွှန်းတန်း၏ ပထမဆုံး သင်ခန်းစာအချို့ကို Microsoft Learn တွင် [Learn Path](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) အဖြစ် လေ့လာနိုင်ပါသည်။
ဤသင်ခန်းစာများတွင် Development Environment ကို အသင့်ရှိပြီး သင်စတင်နိုင်ပါသည်! Curriculum ကို [Codespace](https://github.com/features/codespaces/) (_Browser-based, Install မလိုအပ်သော Environment_) သို့မဟုတ် သင်၏ Computer တွင် Local အနေဖြင့် Text Editor တစ်ခုဖြင့် အသုံးပြုနိုင်ပါသည်။ [Programming Languages နှင့် Tools of the Trade](../../1-getting-started-lessons/1-intro-to-programming-languages) သင်ခန်းစာတွင် သင်၏လိုအပ်ချက်များအတွက် အကောင်းဆုံး Tool များကို ရွေးချယ်ရန် လမ်းညွှန်ပါမည်။
စီမံကိန်းများနှင့် အညီ အကြောင်းအရာများကို ကိုက်ညီစေရန် သေချာစွာ စီစဉ်ထားသောကြောင့် ကျောင်းသားများအတွက် ပိုမိုစိတ်ဝင်စားစေပြီး အကြောင်းအရာများကို ပိုမိုမှတ်မိစေပါသည်။ JavaScript အခြေခံများကို မိတ်ဆက်ပေးသည့် starter lesson အချို့ကိုလည်း ရေးသားထားပြီး "[Beginners Series to: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)" ဗီဒီယို tutorial စီးရီးမှ ဗီဒီယိုတစ်ခုနှင့် တွဲဖက်ထားပါသည်။ ဤ tutorial များ၏ အချို့သောရေးသားသူများကလည်း ဒီသင်ရိုးညွှန်းတန်းတွင် ပါဝင်ရေးသားထားကြသည်။
#### သင်၏ Repository ကို ဖန်တီးပါ
သင်၏အလုပ်များကို လွယ်ကူစွာ သိမ်းဆည်းရန် သင်၏ Repository ကို ဖန်တီးရန် အကြံပြုပါသည်။ ဤသင်ခန်းစာများကို သင်၏ GitHub Account တွင် Copy လုပ်ထားသော Repository အသစ်တစ်ခုကို ဖန်တီးရန် **Use this template** ခလုတ်ကို နှိပ်ပါ။
ထို့အပြင်၊ သင်တန်းမစတင်မီ စိတ်ဖိစီးမှုမရှိသော စစ်ဆေးမှုတစ်ခုက ကျောင်းသား၏ အာရုံစိုက်မှုကို သင်ခန်းစာအပေါ် ဦးတည်စေပြီး သင်တန်းပြီးဆုံးချိန်တွင် စစ်ဆေးမှုတစ်ခုက အကြောင်းအရာများကို ပိုမိုမှတ်မိစေပါသည်။ ဒီသင်ရိုးညွှန်းတန်းကို ပြီးစီးရန် အချိန် ၁၂ ပတ်ကြာမည်ဖြစ်ပြီး စီမံကိန်းများသည် အစပိုင်းတွင် သေးငယ်ပြီး နောက်ပိုင်းတွင် အဆင့်မြင့်လာမည်ဖြစ်သည်။
အဆင့်များကို လိုက်နာပါ-
1. **Repository ကို Fork လုပ်ပါ**: ဤစာမျက်နှာ၏ အပေါ်ယံညာဘက်တွင်ရှိသော "Fork" ခလုတ်ကို နှိပ်ပါ။
2. **Repository ကို Clone လုပ်ပါ**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
JavaScript frameworks များကို မိတ်ဆက်ခြင်းကို ရှောင်ရှားထားပြီး framework များကို သုံးစွဲရန်မတိုင်မီ web developer အဖြစ် လိုအပ်သော အခြေခံကျသော ကျွမ်းကျင်မှုများကို အာရုံစိုက်ထားပါသည်။ ဒီသင်ရိုးညွှန်းတန်းကို ပြီးစီးပြီးနောက် Node.js အကြောင်းကို "[Beginner Series to: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)" ဗီဒီယို စီးရီးမှတစ်ဆင့် လေ့လာရန် သင့်တော်ပါသည်။
#### Curriculum ကို Codespace တွင် Run လုပ်ခြင်း
> ကျွန်ုပ်တို့၏ [Code of Conduct](CODE_OF_CONDUCT.md) နှင့် [Contributing](CONTRIBUTING.md) လမ်းညွှန်ချက်များကို ကြည့်ပါ။ သင့်၏ အဆောက်အအုံဆန်းစစ်ချက်များကို ကြိုဆိုပါသည်။
သင်ဖန်တီးထားသော Repository တွင် **Code** ခလုတ်ကို နှိပ်ပြီး **Open with Codespaces** ကို ရွေးပါ။ ဤသည် သင်အလုပ်လုပ်ရန် Codespace အသစ်တစ်ခုကို ဖန်တီးပေးပါမည်။
## 🧭 အော့ဖ်လိုင်း အသုံးပြုမှု
[!Codespace](../..)./images/createcodespace.png)
ဤစာတမ်းများကို [Docsify](https://docsify.js.org/#/) အသုံးပြု၍ အော့ဖ်လိုင်းတွင် လည်ပတ်နိုင်ပါသည်။ ဤ repo ကို fork လုပ်ပြီး [Docsify](https://docsify.js.org/#/quickstart) ကို သင့် local စက်တွင် install လုပ်ပါ၊ ထို့နောက် repo ၏ root folder တွင် `docsify serve` ဟု ရိုက်ထည့်ပါ။ website ကို သင့် localhost ၏ port 3000 တွင် လည်ပတ်မည်ဖြစ်သည်။ `localhost:3000`
#### Curriculum ကို သင်၏ Computer တွင် Local အနေဖြင့် Run လုပ်ခြင်း
## 📘 PDF
Curriculum ကို သင်၏ Computer တွင် Local အနေဖြင့် Run လုပ်ရန် Text Editor, Browser နှင့် Command Line Tool တစ်ခုလိုအပ်ပါသည်။ [Programming Languages နှင့် Tools of the Trade](../../1-getting-started-lessons/1-intro-to-programming-languages) သင်ခန်းစာတွင် Tool များကို ရွေးချယ်ရန် လမ်းညွှန်ပါမည်။
သင်ခန်းစာများအားလုံး၏ PDF ကို [ဒီမှာ](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf) ရနိုင်ပါသည်။
ကျွန်ုပ်တို့၏ အကြံပြုချက်မှာ [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) ကို Editor အဖြစ် အသုံးပြုရန်ဖြစ်ပြီး [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) ကို Built-in အနေဖြင့် ပါဝင်သည်။ [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) ကို [ဒီနေရာ](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) မှ Download လုပ်ပါ။
## 🎒 အခြားသင်တန်းများ
1. သင်၏ Repository ကို Computer သို့ Clone လုပ်ပါ။ **Code** ခလုတ်ကို နှိပ်ပြီး URL ကို Copy လုပ်ပါ-
ကျွန်ုပ်တို့၏ အဖွဲ့သည် အခြားသင်တန်းများကိုလည်း ထုတ်လုပ်ပါသည်! ကြည့်ပါ:
[!CodeSpace](./images/createcodespace.png)
- [Generative AI for Beginners](https://aka.ms/genai-beginners)
- [Generative AI for Beginners .NET](https://github.com/microsoft/Generative-AI-for-beginners-dotnet)
- [Generative AI with JavaScript](https://github.com/microsoft/generative-ai-with-javascript)
- [Generative AI with Java](https://github.com/microsoft/Generative-AI-for-beginners-java)
- [AI for Beginners](https://aka.ms/ai-beginners)
- [Data Science for Beginners](https://aka.ms/datascience-beginners)
- [ML for Beginners](https://aka.ms/ml-beginners)
- [Cybersecurity for Beginners](https://github.com/microsoft/Security-101)
- [Web Dev for Beginners](https://aka.ms/webdev-beginners)
- [IoT for Beginners](https://aka.ms/iot-beginners)
- [XR Development for Beginners](https://github.com/microsoft/xr-development-for-beginners)
- [Mastering GitHub Copilot for Agentic use](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
- [Mastering GitHub Copilot for C#/.NET Developers](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
- [Choose Your Own Copilot Adventure](https://github.com/microsoft/CopilotAdventures)
ထို့နောက် [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) တွင် [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) ကို ဖွင့်ပြီး သင် Copy လုပ်ထားသော URL ကို `<your-repository-url>` အစားထိုး၍ အောက်ပါ Command ကို Run လုပ်ပါ-
## License
```bash
git clone <your-repository-url>
```
ဤ repository သည် MIT လိုင်စင်အောက်တွင် လိုင်စင်ရရှိထားပါသည်။ ပိုမိုသိရှိရန် [LICENSE](../../LICENSE) ဖိုင်ကို ကြည့်ပါ။
2. Visual Studio Code တွင် Folder ကို ဖွင့်ပါ။ **File** ကို နှိပ်ပြီး...
> **ဖိုလ်ဒါဖွင့်**ပြီးတော့ သင်မကြာသေးမီက ကလုန်းလုပ်ထားတဲ့ ဖိုလ်ဒါကို ရွေးချယ်ပါ။
> Visual Studio Code အတွက် အကြံပြုထားသော Extension များ:
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - Visual Studio Code အတွင်း HTML စာမျက်နှာများကို ကြည့်ရှုရန်
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - ကုဒ်ရေးသားမှုကို ပိုမိုလျင်မြန်စေရန်
## 📂 သင်ခန်းစာတစ်ခုစီတွင် ပါဝင်သည်များ:
- စိတ်ကြိုက် sketchnote
- စိတ်ကြိုက် ထပ်ဆောင်းဗီဒီယို
- သင်ခန်းစာမတိုင်မီ အပူတက်မေးခွန်း
- ရေးသားထားသော သင်ခန်းစာ
- ပရောဂျက်အခြေပြု သင်ခန်းစာများအတွက် ပရောဂျက်တည်ဆောက်နည်း လမ်းညွှန်ချက်များ
- အသိပညာစစ်ဆေးမှုများ
- စိန်ခေါ်မှု
- ထပ်ဆောင်းဖတ်ရှုရန်
- အိမ်စာ
- [သင်ခန်းစာပြီးဆုံးပြီးနောက် မေးခွန်း](https://ff-quizzes.netlify.app/web/)
> **မေးခွန်းများအကြောင်း မှတ်ချက်**: မေးခွန်းအားလုံးကို Quiz-app ဖိုလ်ဒါတွင် ထည့်သွင်းထားပြီး၊ မေးခွန်း ၃ ခုပါဝင်သော စုစုပေါင်း ၄၈ ခုရှိသည်။ [ဒီမှာ](https://ff-quizzes.netlify.app/web/) ရနိုင်ပြီး၊ quiz app ကို ဒေသတွင်းတွင် အလုပ်လုပ်စေခြင်း သို့မဟုတ် Azure တွင် တင်နိုင်သည်။ `quiz-app` ဖိုလ်ဒါအတွင်းရှိ လမ်းညွှန်ချက်များကို လိုက်နာပါ။
## 🗃️ သင်ခန်းစာများ
| | ပရောဂျက်အမည် | သင်ကြားမည့်အကြောင်းအရာများ | သင်ယူရမည့်ရည်မှန်းချက်များ | သင်ခန်းစာချိတ်ဆက် | စာရေးသူ |
| :-: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :---------------------: |
| 01 | စတင်ခြင်း | Programming နှင့် Tools of the Trade အကြောင်းမိတ်ဆက် | Programming ဘာသာစကားများ၏ အခြေခံအကြောင်းအရာများနှင့် ပရော်ဖက်ရှင်နယ် Developer များအလုပ်လုပ်ရာတွင် အသုံးပြုသော ဆော့ဖ်ဝဲများကို လေ့လာပါ | [Programming ဘာသာစကားများနှင့် Tools of the Trade အကြောင်းမိတ်ဆက်](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | စတင်ခြင်း | GitHub အခြေခံများ၊ အဖွဲ့လိုက်အလုပ်လုပ်ခြင်းအပါအဝင် | GitHub ကို သင်၏ပရောဂျက်တွင် အသုံးပြုနည်း၊ အခြားသူများနှင့် ကုဒ်အခြေခံပေါ်တွင် ပူးပေါင်းဆောင်ရွက်နည်း | [GitHub အခြေခံများ](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | စတင်ခြင်း | ဝက်ဘ်လက်လှမ်းမီမှု | ဝက်ဘ်လက်လှမ်းမီမှု၏ အခြေခံအကြောင်းအရာများကို လေ့လာပါ | [ဝက်ဘ်လက်လှမ်းမီမှုအခြေခံ](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | JS အခြေခံ | JavaScript Data Types | JavaScript Data Types အခြေခံအကြောင်းအရာများ | [Data Types](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | JS အခြေခံ | Functions နှင့် Methods | Application ၏ logic flow ကို စီမံရန် Functions နှင့် Methods အကြောင်းကို လေ့လာပါ | [Functions နှင့် Methods](./2-js-basics/2-functions-methods/README.md) | Jasmine and Christopher |
| 06 | JS အခြေခံ | JS ဖြင့် ဆုံးဖြတ်ချက်များချခြင်း | Decision-making နည်းလမ်းများကို အသုံးပြု၍ သင်၏ကုဒ်တွင် အခြေအနေများ ဖန်တီးနည်းကို လေ့လာပါ | [ဆုံးဖြတ်ချက်များချခြင်း](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | JS အခြေခံ | Arrays နှင့် Loops | JavaScript တွင် Arrays နှင့် Loops ကို အသုံးပြု၍ ဒေတာများကို စီမံပါ | [Arrays နှင့် Loops](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [Terrarium](./3-terrarium/solution/README.md) | HTML ကို လက်တွေ့အသုံးပြုခြင်း | Layout တစ်ခုတည်ဆောက်ရန် အွန်လိုင်း Terrarium တစ်ခုကို HTML ဖြင့် တည်ဆောက်ပါ | [HTML အကြောင်းမိတ်ဆက်](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [Terrarium](./3-terrarium/solution/README.md) | CSS ကို လက်တွေ့အသုံးပြုခြင်း | CSS ကို အသုံးပြု၍ အွန်လိုင်း Terrarium ကို အလှဆင်ပါ၊ CSS အခြေခံအကြောင်းအရာများနှင့် စာမျက်နှာကို responsive ဖြစ်စေရန် အခြေခံများကို အာရုံစိုက်ပါ | [CSS အကြောင်းမိတ်ဆက်](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [Terrarium](./3-terrarium/solution/README.md) | JavaScript Closures, DOM ကို စီမံခြင်း | Drag/drop interface အဖြစ် Terrarium ကို လုပ်ဆောင်စေရန် JavaScript ကို တည်ဆောက်ပါ၊ Closures နှင့် DOM ကို စီမံခြင်းအပေါ် အာရုံစိုက်ပါ | [JavaScript Closures, DOM ကို စီမံခြင်း](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [Typing Game](./4-typing-game/solution/README.md) | Typing Game တစ်ခု တည်ဆောက်ခြင်း | JavaScript app ၏ logic ကို keyboard events အသုံးပြု၍ စီမံနည်းကို လေ့လာပါ | [Event-Driven Programming](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Browser များနှင့် အလုပ်လုပ်ခြင်း | Browser များအလုပ်လုပ်ပုံ၊ ၎င်းတို့၏ သမိုင်းကြောင်းနှင့် Browser Extension ၏ ပထမဆုံး elements များကို scaffold တည်ဆောက်နည်းကို လေ့လာပါ | [Browser များအကြောင်း](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Form တစ်ခုတည်ဆောက်ခြင်း၊ API တစ်ခုကို ခေါ်သုံးခြင်းနှင့် local storage တွင် variable များသိမ်းခြင်း | Local storage တွင် သိမ်းထားသော variable များကို အသုံးပြု၍ API တစ်ခုကို ခေါ်သုံးရန် Browser Extension ၏ JavaScript elements များကို တည်ဆောက်ပါ | [APIs, Forms, နှင့် Local Storage](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Browser ၏ Background Processes, Web Performance | Extension ၏ icon ကို စီမံရန် Browser ၏ Background Processes ကို အသုံးပြုပါ၊ Web Performance နှင့် အချို့သော Optimization များကို လေ့လာပါ | [Background Tasks နှင့် Performance](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [Space Game](./6-space-game/solution/README.md) | JavaScript ဖြင့် အဆင့်မြင့် Game Development | Game တစ်ခုတည်ဆောက်ရန် Class နှင့် Composition နှင့် Pub/Sub pattern ကို အသုံးပြု၍ Inheritance အကြောင်းကို လေ့လာပါ | [အဆင့်မြင့် Game Development အကြောင်းမိတ်ဆက်](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [Space Game](./6-space-game/solution/README.md) | Canvas ပေါ်တွင် ရေးဆွဲခြင်း | Canvas API အကြောင်းကို လေ့လာပါ၊ ၎င်းကို အသုံးပြု၍ Screen ပေါ်တွင် Element များကို ရေးဆွဲပါ | [Canvas ပေါ်တွင် ရေးဆွဲခြင်း](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [Space Game](./6-space-game/solution/README.md) | Screen ပေါ်တွင် Element များကို ရွှေ့ခြင်း | Cartesian Coordinates နှင့် Canvas API ကို အသုံးပြု၍ Element များကို ရွှေ့လျားစေခြင်းအကြောင်းကို ရှာဖွေပါ | [Element များကို ရွှေ့ခြင်း](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [Space Game](./6-space-game/solution/README.md) | Collision Detection | Element များကို တိုက်ဆိုင်စေပြီး၊ keypress များကို အသုံးပြု၍ တုံ့ပြန်မှုများကို ဖန်တီးပါ၊ Game ၏ Performance ကို အာရုံစိုက်ရန် Cooldown Function တစ်ခု ထည့်သွင်းပါ | [Collision Detection](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [Space Game](./6-space-game/solution/README.md) | အမှတ်တွက်ခြင်း | Game ၏ Status နှင့် Performance အပေါ်မူတည်၍ သင်္ချာတွက်ချက်မှုများကို ဆောင်ရွက်ပါ | [အမှတ်တွက်ခြင်း](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [Space Game](./6-space-game/solution/README.md) | Game ကို အဆုံးသတ်ခြင်းနှင့် ပြန်စခြင်း | Game ကို အဆုံးသတ်ခြင်းနှင့် ပြန်စခြင်းအကြောင်းကို လေ့လာပါ၊ Asset များကို ရှင်းလင်းခြင်းနှင့် Variable တန်ဖိုးများကို ပြန်လည်သတ်မှတ်ခြင်းအပါအဝင် | [အဆုံးသတ်အခြေအနေ](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [Banking App](./7-bank-project/solution/README.md) | Web App တစ်ခုတွင် HTML Templates နှင့် Routes | Multipage Website Architecture တစ်ခု၏ Scaffold ကို Routing နှင့် HTML Templates အသုံးပြု၍ တည်ဆောက်နည်းကို လေ့လာပါ | [HTML Templates နှင့် Routes](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [Banking App](./7-bank-project/solution/README.md) | Login နှင့် Registration Form တစ်ခု တည်ဆောက်ခြင်း | Form တစ်ခုတည်ဆောက်ခြင်းနှင့် Validation Routines ကို ကိုင်တွယ်နည်း | [Forms](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [Banking App](./7-bank-project/solution/README.md) | Data ကို ရယူခြင်းနှင့် အသုံးပြုခြင်းနည်းလမ်းများ | သင်၏ App အတွင်း Data များ စီးဆင်းပုံ၊ ၎င်းကို ရယူနည်း၊ သိမ်းဆည်းနည်းနှင့် ဖယ်ရှားနည်း | [Data](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [Banking App](./7-bank-project/solution/README.md) | State Management ၏ အကြောင်းအရာများ | သင်၏ App ၏ State ကို ဘယ်လိုထိန်းသိမ်းရမည်နှင့် Programmatically အကောင်အထည်ဖော်နည်းကို လေ့လာပါ | [State Management](./7-bank-project/4-state-management/README.md) | Yohan |
| 25 | [Browser/VScode Code](../../8-code-editor) | VScode နှင့် အလုပ်လုပ်ခြင်း | Code Editor အသုံးပြုနည်းကို လေ့လာပါ | [VScode Code Editor အသုံးပြုခြင်း](./8-code-editor/1-using-a-code-editor/README.md) | Chris |
| 26 | [AI Assistants](./9-chat-project/README.md) | AI နှင့် အလုပ်လုပ်ခြင်း | သင်၏ကိုယ်ပိုင် AI Assistant တစ်ခု တည်ဆောက်နည်းကို လေ့လာပါ | [AI Assistant Project](./9-chat-project/README.md) | Chris |
## 🏫 သင်ကြားမှုနည်းပညာ
ကျွန်ုပ်တို့၏ သင်ရိုးညွှန်းတမ်းကို အဓိက သင်ကြားမှုနည်းပညာနှစ်ခုကို အခြေခံ၍ ဒီဇိုင်းဆွဲထားပါသည်:
* ပရောဂျက်အခြေပြု သင်ကြားမှု
* မကြာခဏ မေးခွန်းများ
ဒီအစီအစဉ်သည် JavaScript, HTML, CSS ၏ အခြေခံအကြောင်းအရာများနှင့် ယနေ့ Web Developer များအသုံးပြုနေသော နောက်ဆုံးပေါ် Tools နှင့် နည်းလမ်းများကို သင်ကြားပေးပါသည်။ ကျောင်းသားများသည် Typing Game, Virtual Terrarium, Eco-Friendly Browser Extension, Space-Invader-Style Game, နှင့် စီးပွားရေးလုပ်ငန်းများအတွက် Banking App တို့ကို တည်ဆောက်ခြင်းဖြင့် လက်တွေ့အတွေ့အကြုံရရှိမည်ဖြစ်သည်။ သင်ရိုးညွှန်းတန်း၏ အဆုံးတွင် ကျောင်းသားများသည် Web Development အကြောင်းကို ခိုင်မာစွာ နားလည်သွားမည်ဖြစ်သည်။
> 🎓 သင်ဤသင်ရိုးညွှန်းတန်း၏ ပထမဆုံး သင်ခန်းစာအချို့ကို Microsoft Learn တွင် [Learn Path](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) အဖြစ် လေ့လာနိုင်ပါသည်။
ပရောဂျက်များနှင့် အကြောင်းအရာများကို ကိုက်ညီစေရန် သေချာစွာ စီစဉ်ထားသောကြောင့် ကျောင်းသားများအတွက် ပိုမိုစိတ်ဝင်စားစေပြီး အကြောင်းအရာများကို ပိုမိုမှတ်မိစေပါသည်။ JavaScript အခြေခံများကို မိတ်ဆက်သည့် သင်ခန်းစာအချို့ကို "[Beginners Series to: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)" ဗီဒီယို Tutorial စုစည်းမှုမှ ဗီဒီယိုတစ်ခုနှင့် တွဲဖက်ရေးသားထားပါသည်။ ဤသင်ရိုးညွှန်းတန်းကို ရေးသားရာတွင် အချို့သောစာရေးသူများလည်း ပါဝင်ခဲ့ပါသည်။
ထို့အပြင်၊ သင်ခန်းစာမတိုင်မီ မေးခွန်းတစ်ခုသည် ကျောင်းသား၏ အာရုံစိုက်မှုကို သင်ခန်းစာအကြောင်းသို့ ဦးတည်စေပြီး၊ သင်ခန်းစာပြီးနောက် မေးခွန်းတစ်ခုသည် အကြောင်းအရာများကို ပိုမိုမှတ်မိစေပါသည်။ ဤသင်ရိုးညွှန်းတန်းကို တစ်ခုလုံး သို့မဟုတ် အစိတ်အပိုင်းအချို့သာ လေ့လာနိုင်ပြီး၊ Flexible နှင့် ပျော်ရွှင်စေရန် ဒီဇိုင်းဆွဲထားပါသည်။ ပရောဂျက်များသည် သေးငယ်သောအဆင့်မှ စတင်ပြီး ၁၂ ပတ်အတွင်း အဆင့်မြင့်ဖြစ်လာမည်ဖြစ်သည်။
JavaScript Framework များကို မိတ်ဆက်ခြင်းကို ရှောင်ကြဉ်ထားပြီး Framework တစ်ခုကို လေ့လာမီ Web Developer အဖြစ် လ
- [Data Science for Beginners](https://aka.ms/datascience-beginners)
- [ML for Beginners](https://aka.ms/ml-beginners)
- [Cybersecurity for Beginners](https://github.com/microsoft/Security-101)
- [Web Dev for Beginners](https://aka.ms/webdev-beginners)
- [IoT for Beginners](https://aka.ms/iot-beginners)
- [XR Development for Beginners](https://github.com/microsoft/xr-development-for-beginners)
- [Mastering GitHub Copilot for Agentic use](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
- [Mastering GitHub Copilot for C#/.NET Developers](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
- [Choose Your Own Copilot Adventure](https://github.com/microsoft/CopilotAdventures)
## လိုင်စင်
ဤ repository သည် MIT လိုင်စင်အောက်တွင် လိုင်စင်ရရှိထားပါသည်။ ပိုမိုသိရှိလိုပါက [LICENSE](../../LICENSE) ဖိုင်ကို ကြည့်ပါ။
---
**အကြောင်းကြားချက်**:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မမှန်ကန်မှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူရင်းဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်မှုများတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းစာရွက်စာတမ်းကို ၎င်း၏ မူဘာသာစကားဖြင့် အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်မှုကို အကြံပြုပါသည်။ ဤဘာသာပြန်မှုကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွတ်များ သို့မဟုတ် အနားယူမှုမှားများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။

@ -1,18 +1,18 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "c63675cfaf1d223b37bb9fecbfe7c252",
"translation_date": "2025-08-27T22:46:19+00:00",
"original_hash": "2dcbb9259dee4f20a4f08d9a1aa2bd4c",
"translation_date": "2025-08-28T18:22:31+00:00",
"source_file": "1-getting-started-lessons/1-intro-to-programming-languages/README.md",
"language_code": "uk"
}
-->
# Вступ до мов програмування та інструментів розробника
У цьому уроці розглядаються основи мов програмування. Теми, які тут висвітлюються, застосовуються до більшості сучасних мов програмування. У розділі "Інструменти розробника" ви дізнаєтеся про корисне програмне забезпечення, яке допомагає вам як розробнику.
Цей урок охоплює основи мов програмування. Теми, розглянуті тут, застосовуються до більшості сучасних мов програмування. У розділі "Інструменти розробника" ви дізнаєтеся про корисне програмне забезпечення, яке допомагає вам як розробнику.
![Intro Programming](../../../../translated_images/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.uk.png)
> Скетчнот від [Tomomi Imura](https://twitter.com/girlie_mac)
> Скетчноут від [Tomomi Imura](https://twitter.com/girlie_mac)
## Тест перед лекцією
[Тест перед лекцією](https://forms.office.com/r/dru4TE0U9n?origin=lprLink)
@ -30,21 +30,21 @@ CO_OP_TRANSLATOR_METADATA:
## Що таке програмування?
Програмування (також відоме як кодування) — це процес написання інструкцій для пристрою, такого як комп'ютер або мобільний пристрій. Ми пишемо ці інструкції за допомогою мови програмування, яку потім інтерпретує пристрій. Ці набори інструкцій можуть називатися різними іменами, але *програма*, *комп'ютерна програма*, *додаток (app)* і *виконуваний файл* — це кілька популярних назв.
Програмування (також відоме як кодування) — це процес написання інструкцій для пристрою, такого як комп'ютер або мобільний пристрій. Ми пишемо ці інструкції за допомогою мови програмування, яка потім інтерпретується пристроєм. Ці набори інструкцій можуть називатися різними термінами, але *програма*, *комп'ютерна програма*, *додаток (app)* і *виконуваний файл* — це кілька популярних назв.
*Програма* може бути будь-чим, що написано за допомогою коду: вебсайти, ігри та мобільні додатки — це програми. Хоча можливо створити програму без написання коду, основна логіка інтерпретується пристроєм, і ця логіка, найімовірніше, була написана за допомогою коду. Програма, яка *виконує* або *запускає* код, виконує інструкції. Пристрій, на якому ви читаєте цей урок, виконує програму, щоб відобразити його на вашому екрані.
*Програма* може бути будь-чим, що написано за допомогою коду: вебсайти, ігри та додатки для телефонів — це програми. Хоча можливо створити програму без написання коду, основна логіка інтерпретується пристроєм, і ця логіка, найімовірніше, була написана за допомогою коду. Програма, яка *виконує* або *запускає* код, виконує інструкції. Пристрій, на якому ви читаєте цей урок, запускає програму, щоб відобразити його на вашому екрані.
✅ Проведіть невелике дослідження: хто вважається першим у світі програмістом?
✅ Проведіть невелике дослідження: хто вважається першим програмістом у світі?
## Мови програмування
Мови програмування дозволяють розробникам писати інструкції для пристрою. Пристрої можуть розуміти лише двійковий код (1 і 0), і для *більшості* розробників це не дуже ефективний спосіб спілкування. Мови програмування є засобом комунікації між людьми та комп'ютерами.
Мови програмування мають різні формати та можуть служити різним цілям. Наприклад, JavaScript в основному використовується для вебдодатків, тоді як Bash в основному використовується для операційних систем.
Мови програмування мають різні формати та можуть служити різним цілям. Наприклад, JavaScript переважно використовується для веб-додатків, тоді як Bash — для операційних систем.
*Мови низького рівня* зазвичай вимагають менше кроків для інтерпретації інструкцій пристроєм, ніж *мови високого рівня*. Однак те, що робить мови високого рівня популярними, — це їхня читабельність і підтримка. JavaScript вважається мовою високого рівня.
*Мови низького рівня* зазвичай потребують менше кроків для інтерпретації інструкцій пристроєм, ніж *мови високого рівня*. Однак те, що робить мови високого рівня популярними, — це їх читабельність і підтримка. JavaScript вважається мовою високого рівня.
Наступний код ілюструє різницю між мовою високого рівня (JavaScript) і мовою низького рівня (ARM assembly code).
Наступний код ілюструє різницю між мовою високого рівня (JavaScript) і мовою низького рівня (ARM Assembly).
```javascript
let number = 10
@ -83,23 +83,23 @@ back add r0,r1
end
```
Вірите чи ні, *вони обидва роблять одне й те саме*: виводять послідовність Фібоначчі до 10.
Повірте чи ні, *вони обидва роблять те саме*: виводять послідовність Фібоначчі до 10.
✅ Послідовність Фібоначчі [визначається](https://en.wikipedia.org/wiki/Fibonacci_number) як набір чисел, де кожне число є сумою двох попередніх, починаючи з 0 і 1. Перші 10 чисел у послідовності Фібоначчі: 0, 1, 1, 2, 3, 5, 8, 13, 21 і 34.
✅ Послідовність Фібоначчі [визначається](https://en.wikipedia.org/wiki/Fibonacci_number) як набір чисел, де кожне число є сумою двох попередніх, починаючи з 0 і 1. Перші 10 чисел послідовності Фібоначчі: 0, 1, 1, 2, 3, 5, 8, 13, 21 і 34.
## Елементи програми
Одна інструкція в програмі називається *оператором* і зазвичай має символ або пробіл, який позначає, де інструкція закінчується, або *завершується*. Як програма завершується, залежить від мови.
Одна інструкція в програмі називається *оператором* і зазвичай має символ або пробіл, який позначає, де інструкція закінчується, або *завершується*. Як програма завершується, залежить від кожної мови.
Оператори в програмі можуть залежати від даних, наданих користувачем або з інших джерел, для виконання інструкцій. Дані можуть змінювати поведінку програми, тому мови програмування мають спосіб тимчасового зберігання даних для подальшого використання. Це називається *змінними*. Змінні — це оператори, які інструктують пристрій зберігати дані в пам'яті. Змінні в програмах схожі на змінні в алгебрі, де вони мають унікальне ім'я, а їхнє значення може змінюватися з часом.
Оператори в програмі можуть залежати від даних, наданих користувачем або отриманих з іншого джерела, для виконання інструкцій. Дані можуть змінювати поведінку програми, тому мови програмування мають спосіб тимчасового зберігання даних, щоб їх можна було використовувати пізніше. Це називається *змінними*. Змінні — це оператори, які інструктують пристрій зберігати дані в пам'яті. Змінні в програмах схожі на змінні в алгебрі, де вони мають унікальне ім'я, а їх значення може змінюватися з часом.
Існує ймовірність, що деякі оператори не будуть виконані пристроєм. Це зазвичай відбувається за задумом розробника або випадково, коли виникає неочікувана помилка. Такий контроль над додатком робить його більш надійним і підтримуваним. Зазвичай ці зміни в управлінні відбуваються, коли виконуються певні умови. Поширеним оператором, який використовується в сучасному програмуванні для управління виконанням програми, є оператор `if..else`.
Існує ймовірність, що деякі оператори не будуть виконані пристроєм. Це зазвичай відбувається за задумом розробника або випадково, коли виникає несподівана помилка. Такий контроль над додатком робить його більш надійним і підтримуваним. Зазвичай ці зміни в управлінні відбуваються, коли виконуються певні умови. Поширений оператор, який використовується в сучасному програмуванні для контролю роботи програми, — це оператор `if..else`.
✅ Ви дізнаєтеся більше про цей тип операторів у наступних уроках.
## Інструменти розробника
[![Інструменти розробника](https://img.youtube.com/vi/69WJeXGBdxg/0.jpg)](https://youtube.com/watch?v=69WJeXGBdxg "Інструменти розробника")
[![Tools of the Trade](https://img.youtube.com/vi/69WJeXGBdxg/0.jpg)](https://youtube.com/watch?v=69WJeXGBdxg "Tools of the Trade")
> 🎥 Натисніть на зображення вище, щоб переглянути відео про інструменти
@ -109,16 +109,16 @@ back add r0,r1
### Редактори
Одним із найважливіших інструментів для розробки програмного забезпечення є редактор. У редакторах ви пишете свій код, а іноді й запускаєте його.
Одним із найважливіших інструментів для розробки програмного забезпечення є редактор. Редактори — це місце, де ви пишете код, а іноді й запускаєте його.
Розробники покладаються на редактори з кількох додаткових причин:
- *Налагодження* допомагає виявляти помилки, крок за кроком проходячи код. Деякі редактори мають функції налагодження, які можна налаштувати та додати для конкретних мов програмування.
- *Налагодження* допомагає виявляти помилки, проходячи код рядок за рядком. Деякі редактори мають функції налагодження; їх можна налаштувати та додати для конкретних мов програмування.
- *Підсвічування синтаксису* додає кольори та форматування тексту до коду, що робить його легшим для читання. Більшість редакторів дозволяють налаштовувати підсвічування синтаксису.
- *Розширення та інтеграції* — це спеціалізовані інструменти для розробників, створені розробниками. Наприклад, багато розробників документують свій код, щоб пояснити, як він працює. Вони можуть встановити розширення для перевірки орфографії, щоб знаходити помилки в документації. Більшість розширень призначені для використання в конкретному редакторі, і більшість редакторів мають спосіб пошуку доступних розширень.
- *Налаштування* дозволяє розробникам створювати унікальне середовище розробки відповідно до своїх потреб. Більшість редакторів надзвичайно налаштовувані та можуть дозволяти розробникам створювати власні розширення.
- *Розширення та інтеграції* — це спеціалізовані інструменти для розробників, створені розробниками. Ці інструменти не були вбудовані в базовий редактор. Наприклад, багато розробників документують свій код, щоб пояснити, як він працює. Вони можуть встановити розширення для перевірки орфографії, щоб знайти помилки в документації. Більшість розширень призначені для використання в конкретному редакторі, і більшість редакторів мають спосіб пошуку доступних розширень.
- *Налаштування* дозволяє розробникам створювати унікальне середовище розробки відповідно до своїх потреб. Більшість редакторів надзвичайно налаштовувані та можуть також дозволяти розробникам створювати власні розширення.
#### Популярні редактори та розширення для веброзробки
#### Популярні редактори та розширення для веб-розробки
- [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)
- [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
@ -135,9 +135,9 @@ back add r0,r1
### Браузери
Ще одним важливим інструментом є браузер. Веброзробники покладаються на браузер, щоб побачити, як їхній код працює в Інтернеті. Він також використовується для відображення візуальних елементів вебсторінки, написаних у редакторі, таких як HTML.
Ще одним важливим інструментом є браузер. Веб-розробники покладаються на браузер, щоб побачити, як їхній код працює в Інтернеті. Він також використовується для відображення візуальних елементів вебсторінки, написаних у редакторі, таких як HTML.
Багато браузерів мають *інструменти розробника* (DevTools), які містять набір корисних функцій та інформації, що допомагають розробникам збирати та фіксувати важливу інформацію про їхній додаток. Наприклад, якщо на вебсторінці є помилки, іноді корисно знати, коли вони виникли. DevTools у браузері можна налаштувати для збору цієї інформації.
Багато браузерів мають *інструменти розробника* (DevTools), які містять набір корисних функцій та інформації, щоб допомогти розробникам збирати та захоплювати важливу інформацію про їхній додаток. Наприклад: якщо на вебсторінці є помилки, іноді корисно знати, коли вони виникли. DevTools у браузері можна налаштувати для збору цієї інформації.
#### Популярні браузери та DevTools
@ -147,11 +147,11 @@ back add r0,r1
### Інструменти командного рядка
Деякі розробники віддають перевагу менш графічному вигляду для своїх щоденних завдань і покладаються на командний рядок. Написання коду вимагає значної кількості друку, і деякі розробники воліють не переривати свій потік роботи на клавіатурі. Вони використовують комбінації клавіш для перемикання між вікнами, роботи з різними файлами та використання інструментів. Більшість завдань можна виконати за допомогою миші, але одна з переваг командного рядка полягає в тому, що багато чого можна зробити за допомогою інструментів командного рядка без необхідності перемикатися між мишею та клавіатурою. Ще одна перевага командного рядка — це можливість налаштування, збереження конфігурацій, їх зміни та імпорту на інші машини для розробки. Оскільки середовища розробки настільки унікальні для кожного розробника, деякі уникають використання командного рядка, деякі покладаються на нього повністю, а деякі віддають перевагу змішаному підходу.
Деякі розробники віддають перевагу менш графічному вигляду для своїх щоденних завдань і покладаються на командний рядок для їх виконання. Написання коду вимагає значної кількості друкування, і деякі розробники воліють не переривати свій потік роботи на клавіатурі. Вони використовують комбінації клавіш для перемикання між вікнами робочого столу, роботи з різними файлами та використання інструментів. Більшість завдань можна виконати за допомогою миші, але однією з переваг використання командного рядка є те, що багато чого можна зробити за допомогою інструментів командного рядка без необхідності перемикання між мишею та клавіатурою. Ще однією перевагою командного рядка є те, що його можна налаштувати, зберегти власну конфігурацію, змінити її пізніше та імпортувати на інші машини для розробки. Оскільки середовища розробки настільки унікальні для кожного розробника, деякі уникають використання командного рядка, деякі покладаються на нього повністю, а деякі віддають перевагу змішаному підходу.
### Популярні опції командного рядка
### Популярні варіанти командного рядка
Опції командного рядка відрізняються залежно від операційної системи, яку ви використовуєте.
Варіанти командного рядка відрізнятимуться залежно від операційної системи, яку ви використовуєте.
*💻 = попередньо встановлено в операційній системі.*
@ -182,30 +182,30 @@ back add r0,r1
### Документація
Коли розробник хоче дізнатися щось нове, він, найімовірніше, звернеться до документації, щоб дізнатися, як це використовувати. Розробники часто покладаються на документацію, щоб зрозуміти, як правильно використовувати інструменти та мови, а також щоб отримати глибше розуміння їхньої роботи.
Коли розробник хоче дізнатися щось нове, він, найімовірніше, звернеться до документації, щоб дізнатися, як це використовувати. Розробники часто покладаються на документацію, щоб отримати інструкції щодо правильного використання інструментів і мов, а також щоб отримати глибше розуміння їх роботи.
#### Популярна документація з веброзробки
#### Популярна документація з веб-розробки
- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web), від Mozilla, видавців браузера [Firefox](https://www.mozilla.org/firefox/)
- [Frontend Masters](https://frontendmasters.com/learn/)
- [Web.dev](https://web.dev), від Google, видавців [Chrome](https://www.google.com/chrome/)
- [Документація Microsoft](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers), для [Microsoft Edge](https://www.microsoft.com/edge)
- [Документація Microsoft для розробників](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers), для [Microsoft Edge](https://www.microsoft.com/edge)
- [W3 Schools](https://www.w3schools.com/where_to_start.asp)
✅ Проведіть дослідження: Тепер, коли ви знаєте основи середовища веброзробника, порівняйте його з середовищем вебдизайнера.
✅ Проведіть дослідження: тепер, коли ви знаєте основи середовища веб-розробника, порівняйте його з середовищем веб-дизайнера.
---
## 🚀 Виклик
Порівняйте деякі мови програмування. Які унікальні риси JavaScript у порівнянні з Java? А як щодо COBOL і Go?
Порівняйте деякі мови програмування. Які унікальні особливості JavaScript порівняно з Java? А як щодо COBOL порівняно з Go?
## Тест після лекції
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/2)
[Тест після лекції](https://ff-quizzes.netlify.app/web/)
## Огляд і самостійне навчання
Вивчіть трохи про різні мови, доступні програмісту. Спробуйте написати рядок на одній мові, а потім перепишіть його на двох інших. Що ви дізналися?
Вивчіть трохи про різні мови, доступні програмісту. Спробуйте написати один рядок на одній мові, а потім перепишіть його на двох інших. Що ви дізналися?
## Завдання
@ -214,4 +214,4 @@ back add r0,r1
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають у результаті використання цього перекладу.

@ -1,59 +1,59 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "05666cecb8983a72cf0ce1d18932b5b7",
"translation_date": "2025-08-27T22:51:41+00:00",
"original_hash": "361249da70432ddfd4741c917d1a6f50",
"translation_date": "2025-08-28T18:25:34+00:00",
"source_file": "1-getting-started-lessons/2-github-basics/README.md",
"language_code": "uk"
}
-->
# Вступ до GitHub
Цей урок охоплює основи GitHub — платформи для розміщення та управління змінами у вашому коді.
Цей урок охоплює основи GitHub — платформи для хостингу та управління змінами у вашому коді.
![Вступ до GitHub](../../../../translated_images/webdev101-github.8846d7971abef6f947909b4f9d343e2a23778aa716ca6b9d71df7174ee5009ac.uk.png)
![Intro to GitHub](../../../../translated_images/webdev101-github.8846d7971abef6f947909b4f9d343e2a23778aa716ca6b9d71df7174ee5009ac.uk.png)
> Скетчноут від [Tomomi Imura](https://twitter.com/girlie_mac)
## Тест перед лекцією
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/3)
## Передлекційна вікторина
[Передлекційна вікторина](https://ff-quizzes.netlify.app)
## Вступ
У цьому уроці ми розглянемо:
- відстеження роботи, яку ви виконуєте на своєму комп'ютері
- роботу над проєктами разом з іншими
- як робити внесок у програмне забезпечення з відкритим кодом
- як відстежувати роботу, яку ви виконуєте на своєму комп'ютері
- як працювати над проєктами разом з іншими
- як робити внески у програмне забезпечення з відкритим кодом
### Попередні вимоги
Перед початком перевірте, чи встановлено у вас Git. У терміналі введіть:
Перед початком перевірте, чи встановлений у вас Git. У терміналі введіть:
`git --version`
Якщо Git не встановлено, [завантажте Git](https://git-scm.com/downloads). Потім налаштуйте свій локальний профіль Git у терміналі:
* `git config --global user.name "ваше-ім'я"`
* `git config --global user.email "ваш-email"`
Якщо Git не встановлений, [завантажте Git](https://git-scm.com/downloads). Потім налаштуйте свій локальний профіль Git у терміналі:
* `git config --global user.name "your-name"`
* `git config --global user.email "your-email"`
Щоб перевірити, чи вже налаштовано Git, введіть:
Щоб перевірити, чи вже налаштований Git, введіть:
`git config --list`
Вам також знадобиться обліковий запис GitHub, текстовий редактор (наприклад, Visual Studio Code) і доступ до терміналу (або командного рядка).
Вам також знадобиться обліковий запис GitHub, редактор коду (наприклад, Visual Studio Code) і доступ до терміналу (або командного рядка).
Перейдіть на [github.com](https://github.com/) і створіть обліковий запис, якщо у вас його ще немає, або увійдіть і заповніть свій профіль.
✅ GitHub — це не єдине сховище коду у світі; є й інші, але GitHub є найвідомішим.
✅ GitHub — це не єдиний репозиторій коду у світі; є й інші, але GitHub є найвідомішим.
### Підготовка
Вам знадобиться папка з кодом проєкту на вашому локальному комп'ютері (ноутбуці або ПК) і публічне сховище на GitHub, яке слугуватиме прикладом для того, як робити внески в проєкти інших.
Вам знадобиться папка з проєктом коду на вашому локальному комп'ютері (ноутбуці або ПК) і публічний репозиторій на GitHub, який слугуватиме прикладом того, як робити внески в проєкти інших.
---
## Управління кодом
Припустимо, у вас є папка з кодом проєкту на вашому комп'ютері, і ви хочете почати відстежувати свій прогрес за допомогою git — системи контролю версій. Дехто порівнює використання git із написанням любовного листа до свого майбутнього "я". Читаючи свої повідомлення про коміти через дні, тижні чи місяці, ви зможете згадати, чому прийняли те чи інше рішення, або "відкотити" зміни — за умови, що ви пишете хороші повідомлення про коміти.
Припустимо, у вас є локальна папка з якимось проєктом коду, і ви хочете почати відстежувати свій прогрес за допомогою git — системи контролю версій. Деякі люди порівнюють використання git із написанням любовного листа до свого майбутнього "я". Читаючи свої повідомлення про коміти через дні, тижні чи місяці, ви зможете згадати, чому прийняли те чи інше рішення, або "відкотити" зміни — за умови, що ви пишете хороші повідомлення про коміти.
### Завдання: Створіть репозиторій і закомітьте код
### Завдання: Створіть репозиторій і зафіксуйте код
> Перегляньте відео
>
@ -61,10 +61,10 @@ CO_OP_TRANSLATOR_METADATA:
1. **Створіть репозиторій на GitHub**. На GitHub.com, у вкладці репозиторіїв або у верхньому правому куті навігаційної панелі, знайдіть кнопку **new repo**.
1. Дайте своєму репозиторію (папці) назву.
1. Виберіть **create repository**.
1. Дайте вашому репозиторію (папці) назву.
1. Натисніть **create repository**.
1. **Перейдіть до робочої папки**. У терміналі перейдіть до папки (також відомої як директорія), яку ви хочете почати відстежувати. Введіть:
1. **Перейдіть до вашої робочої папки**. У терміналі перейдіть до папки (також відомої як директорія), яку ви хочете почати відстежувати. Введіть:
```bash
cd [name of your folder]
@ -93,10 +93,10 @@ CO_OP_TRANSLATOR_METADATA:
modified: file2.txt
```
Зазвичай команда `git status` повідомляє вам, які файли готові до береження_ у репозиторії або мають зміни, які ви, можливо, захочете зберегти.
Зазвичай команда `git status` повідомляє вам, які файли готові до береження_ у репозиторії або мають зміни, які ви, можливо, хочете зафіксувати.
1. **Додайте всі файли для відстеження**
Це також називається стадіюванням файлів/додаванням файлів до області підготовки.
Це також називається підготовкою файлів/додаванням файлів до області підготовки.
```bash
git add .
@ -112,41 +112,41 @@ CO_OP_TRANSLATOR_METADATA:
Це дозволяє додати лише вибрані файли до області підготовки, якщо ви не хочете комітити всі файли одразу.
1. **Відмініть стадіювання всіх файлів**
1. **Зніміть підготовку з усіх файлів**
```bash
git reset
```
Ця команда дозволяє відмінити стадіювання всіх файлів одразу.
Ця команда дозволяє зняти підготовку з усіх файлів одразу.
1. **Відмініть стадіювання конкретного файлу**
1. **Зніміть підготовку з конкретного файлу**
```bash
git reset [file or folder name]
```
Ця команда дозволяє відмінити стадіювання лише конкретного файлу, який ви не хочете включати до наступного коміту.
Ця команда дозволяє зняти підготовку лише з конкретного файлу, який ви не хочете включати до наступного коміту.
1. **Збережіть свою роботу**. На цьому етапі ви додали файли до так званої _області підготовки_. Це місце, де Git відстежує ваші файли. Щоб зробити зміни постійними, вам потрібно акомітити_ файли. Для цього створіть оміт_ за допомогою команди `git commit`. Коміт представляє точку збереження в історії вашого репозиторію. Введіть наступне, щоб створити _коміт_:
1. **Збережіть свою роботу**. На цьому етапі ви додали файли до так званої _області підготовки_. Це місце, де Git відстежує ваші файли. Щоб зробити зміни постійними, вам потрібно афіксувати_ файли. Для цього створіть оміт_ за допомогою команди `git commit`. Коміт представляє точку збереження в історії вашого репозиторію. Введіть наступне, щоб створити коміт:
```bash
git commit -m "first commit"
```
Це закомітить усі ваші файли, додавши повідомлення "first commit". У майбутніх повідомленнях про коміти вам слід бути більш описовими, щоб передати, які саме зміни ви зробили.
Ця команда фіксує всі ваші файли, додаючи повідомлення "first commit". Для майбутніх повідомлень про коміти варто бути більш описовими, щоб передати, які саме зміни ви зробили.
1. **Підключіть локальний Git-репозиторій до GitHub**. Git-репозиторій корисний на вашому комп'ютері, але в якийсь момент ви захочете створити резервну копію своїх файлів десь і запросити інших людей працювати з вами над вашим репозиторієм. Одне з чудових місць для цього — GitHub. Пам'ятайте, що ми вже створили репозиторій на GitHub, тому єдине, що нам потрібно зробити, це підключити наш локальний Git-репозиторій до GitHub. Команда `git remote add` зробить це. Введіть наступну команду:
1. **Підключіть ваш локальний репозиторій Git до GitHub**. Репозиторій Git корисний на вашому комп'ютері, але в якийсь момент ви захочете створити резервну копію своїх файлів десь і запросити інших людей працювати з вами над вашим репозиторієм. Одне з чудових місць для цього — GitHub. Пам'ятайте, що ми вже створили репозиторій на GitHub, тому єдине, що потрібно зробити, це підключити ваш локальний репозиторій Git до GitHub. Команда `git remote add` зробить це. Введіть наступну команду:
> Зверніть увагу, перед введенням команди перейдіть на сторінку вашого репозиторію на GitHub, щоб знайти URL репозиторію. Ви використаєте його в команді нижче. Замініть ```https://github.com/username/repository_name.git``` на ваш URL GitHub.
> Зверніть увагу, перед тим як вводити команду, перейдіть на сторінку вашого репозиторію на GitHub, щоб знайти URL репозиторію. Ви використаєте його в команді нижче. Замініть ```https://github.com/username/repository_name.git``` на ваш URL GitHub.
```bash
git remote add origin https://github.com/username/repository_name.git
```
Це створює іддалене підключення_, назване "origin", яке вказує на репозиторій GitHub, створений раніше.
Це створює іддалене підключення_ (remote), назване "origin", яке вказує на репозиторій GitHub, створений раніше.
1. **Відправте локальні файли на GitHub**. Досі ви створили _підключення_ між локальним репозиторієм і репозиторієм GitHub. Відправимо ці файли на GitHub за допомогою команди `git push`, ось так:
1. **Відправте локальні файли на GitHub**. До цього моменту ви створили _підключення_ між локальним репозиторієм і репозиторієм GitHub. Відправимо ці файли на GitHub за допомогою команди `git push`, ось так:
> Зверніть увагу, ваша назва гілки за замовчуванням може відрізнятися від ```main```.
@ -154,9 +154,9 @@ CO_OP_TRANSLATOR_METADATA:
git push -u origin main
```
Це відправляє ваші коміти у вашу гілку "main" на GitHub.
Це відправляє ваші коміти у гілку "main" на GitHub.
2. **Додайте більше змін**. Якщо ви хочете продовжити вносити зміни та відправляти їх на GitHub, вам потрібно буде використовувати наступні три команди:
2. **Щоб додати більше змін**. Якщо ви хочете продовжити вносити зміни та відправляти їх на GitHub, вам потрібно буде використовувати наступні три команди:
```bash
git add .
@ -164,23 +164,23 @@ CO_OP_TRANSLATOR_METADATA:
git push
```
> Порада: Можливо, вам також захочеться створити файл `.gitignore`, щоб запобігти відстеженню файлів, які ви не хочете бачити на GitHub, наприклад, нотаток, які ви зберігаєте в тій самій папці, але які не мають місця в публічному репозиторії. Ви можете знайти шаблони для файлів `.gitignore` на сторінці [.gitignore templates](https://github.com/github/gitignore).
> Порада: Можливо, ви також захочете додати файл `.gitignore`, щоб запобігти відстеженню файлів, які ви не хочете бачити на GitHub — наприклад, файлу з нотатками, який ви зберігаєте в тій самій папці, але який не має бути у публічному репозиторії. Ви можете знайти шаблони для файлів `.gitignore` на сторінці [.gitignore templates](https://github.com/github/gitignore).
#### Повідомлення про коміти
Чудовий заголовок повідомлення про коміт завершує наступне речення:
Якщо застосувати, цей коміт <ваш заголовок тут>.
Для заголовка використовуйте наказовий, теперішній час: "змінити", а не "змінив" чи "зміни".
Як і в заголовку, у тілі (за бажанням) також використовуйте наказовий, теперішній час. Тіло має включати мотивацію для зміни та порівняння з попередньою поведінкою. Ви пояснюєте `чому`, а не `як`.
Для заголовка використовуйте наказовий теперішній час: "змінити", а не "змінив" чи "зміни".
Як і в заголовку, у тілі (необов'язково) також використовуйте наказовий теперішній час. Тіло має включати мотивацію для зміни та порівняння з попередньою поведінкою. Ви пояснюєте `чому`, а не `як`.
✅ Приділіть кілька хвилин, щоб переглянути GitHub. Чи можете ви знайти дійсно чудове повідомлення про коміт? А мінімальне? Яка інформація, на вашу думку, є найважливішою та найкориснішою для передачі в повідомленні про коміт?
✅ Приділіть кілька хвилин, щоб переглянути GitHub. Чи можете ви знайти справді чудове повідомлення про коміт? А мінімальне? Яка інформація, на вашу думку, є найважливішою та найкориснішою для передачі у повідомленні про коміт?
### Завдання: Співпраця
Основна причина розміщення проєктів на GitHub — це можливість співпрацювати з іншими розробниками.
## Робота над проєктами разом з іншими
## Робота над проєктами з іншими
> Перегляньте відео
>
@ -189,30 +189,30 @@ CO_OP_TRANSLATOR_METADATA:
У вашому репозиторії перейдіть до `Insights > Community`, щоб побачити, як ваш проєкт відповідає рекомендованим стандартам спільноти.
Ось кілька речей, які можуть покращити ваш репозиторій на GitHub:
- **Опис**. Чи додали ви опис до свого проєкту?
- **Опис**. Чи додали ви опис вашого проєкту?
- **README**. Чи додали ви README? GitHub надає рекомендації щодо написання [README](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon).
- **Керівництво для внесків**. Чи має ваш проєкт [керівництво для внесків](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon)?
- **Кодекс поведінки**. Чи додали ви [Кодекс поведінки](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/)?
- **Ліцензія**. Можливо, найважливіше — [ліцензію](https://docs.github.com/articles/adding-a-license-to-a-repository/)?
- **Ліцензія**. Можливо, найважливіше — [ліцензія](https://docs.github.com/articles/adding-a-license-to-a-repository/)?
Усі ці ресурси допоможуть новим учасникам швидше адаптуватися. Зазвичай це ті речі, на які нові учасники звертають увагу перед тим, як переглядати ваш код, щоб зрозуміти, чи є ваш проєкт правильним місцем для їхнього часу.
Усі ці ресурси допоможуть новим членам команди швидше адаптуватися. Це зазвичай ті речі, які нові учасники переглядають перед тим, як ознайомитися з вашим кодом, щоб зрозуміти, чи варто їм витрачати час на ваш проєкт.
✅ README-файли, хоча їх підготовка займає час, часто ігноруються зайнятими підтримувачами. Чи можете ви знайти приклад особливо описового README? Примітка: існують [інструменти для створення хороших README](https://www.makeareadme.com/), які вам можуть сподобатися.
Файли README, хоча їх підготовка займає час, часто ігноруються зайнятими підтримувачами. Чи можете ви знайти приклад особливо описового README? Примітка: існують [інструменти для створення хороших README](https://www.makeareadme.com/), які вам можуть сподобатися.
### Завдання: Об'єднайте код
Документація для внесків допомагає людям робити внески в проєкт. Вона пояснює, які типи внесків ви шукаєте і як працює процес. Учасники повинні пройти серію кроків, щоб мати змогу зробити внесок у ваш репозиторій на GitHub:
Документація для внесків допомагає людям робити внески у проєкт. Вона пояснює, які типи внесків ви шукаєте і як працює процес. Учасники повинні пройти серію кроків, щоб мати змогу зробити внесок у ваш репозиторій на GitHub:
1. **Форк вашого репозиторію**. Ви, ймовірно, захочете, щоб люди оркали_ ваш проєкт. Форкінг означає створення копії вашого репозиторію у їхньому профілі GitHub.
1. **Форк вашого репозиторію**. Ви, ймовірно, захочете, щоб люди оркали_ ваш проєкт. Форк означає створення копії вашого репозиторію у їхньому профілі GitHub.
1. **Клонування**. Після цього вони клонують проєкт на свій локальний комп'ютер.
1. **Створення гілки**. Ви захочете попросити їх створити _гілку_ для своєї роботи.
1. **Зосередження змін на одній області**. Попросіть учасників зосередити свої внески на одній речі за раз — таким чином шанси, що ви зможете _об'єднати_ їхню роботу, будуть вищими. Уявіть, що вони виправляють помилку, додають нову функцію та оновлюють кілька тестів — що, якщо ви хочете або можете реалізувати лише 2 із 3, або 1 із 3 змін?
1. **Фокусування змін на одній області**. Попросіть учасників зосередити свої внески на чомусь одному за раз — таким чином шанси, що ви зможете _об'єднати_ їхню роботу, будуть вищими. Уявіть, що вони виправляють помилку, додають нову функцію та оновлюють кілька тестів — що, якщо ви хочете або можете реалізувати лише 2 із 3, або 1 із 3 змін?
✅ Уявіть ситуацію, коли гілки є особливо важливими для написання та впровадження якісного коду. Які випадки використання ви можете придумати?
✅ Уявіть ситуацію, коли гілки є особливо важливими для написання та випуску хорошого коду. Які випадки використання ви можете придумати?
> Примітка: будьте зміною, яку хочете бачити у світі, і створюйте гілки для своєї роботи також. Усі коміти, які ви робите, будуть зроблені у гілці, до якої ви зараз "перемкнуті". Використовуйте `git status`, щоб побачити, у якій гілці ви перебуваєте.
Розглянемо робочий процес учасника. Припустимо, учасник вже оркнув_ і _клонував_ репозиторій, тому у нього є готовий Git-репозиторій на локальному комп'ютері:
Давайте розглянемо робочий процес учасника. Припустимо, учасник вже оркнув_ і _клонував_ репозиторій, тому у нього є готовий Git-репозиторій на локальному комп'ютері:
1. **Створіть гілку**. Використовуйте команду `git branch`, щоб створити гілку, яка міститиме зміни, які вони планують внести:
@ -233,7 +233,7 @@ CO_OP_TRANSLATOR_METADATA:
git commit -m "my changes"
```
Переконайтеся, що ви дали своєму коміту гарну назву, для вашого ж блага, а також для підтримувача репозиторію, якому ви допомагаєте.
Переконайтеся, що ви дали своєму коміту гарну назву — для себе, а також для підтримувача репозиторію, якому ви допомагаєте.
1. **Об'єднайте свою роботу з гілкою `main`**. У якийсь момент ви закінчите роботу і захочете об'єднати її з гілкою `main`. Гілка `main` могла змінитися за цей час, тому переконайтеся, що ви спочатку оновили її до останньої версії за допомогою наступних команд:
@ -249,49 +249,49 @@ CO_OP_TRANSLATOR_METADATA:
git merge main
```
Це принесе всі зміни з `main` у вашу гілку, і, сподіваємося, ви зможете продовжити. Якщо ні, VS Code покаже вам, де Git аплутався_, і ви просто зміните відповідні файли, щоб вказати, який вміст є найбільш точним.
Це принесе всі зміни з `main` у вашу гілку, і, сподіваємося, ви зможете просто продовжити. Якщо ні, VS Code покаже вам, де Git аплутався_, і ви просто зміните відповідні файли, щоб вказати, який вміст є найбільш точним.
1. **Відправте свою роботу на GitHub**. Відправка вашої роботи на GitHub означає дві речі: відправку вашої гілки у ваш форкований репозиторій і відкриття PR (Pull Request).
1. **Відправте свою роботу на GitHub**. Відправка вашої роботи на GitHub означає дві речі: відправку вашої гілки у ваш репозиторій і відкриття PR (Pull Request).
```bash
git push --set-upstream origin [branch-name]
```
Наведена вище команда створює гілку у вашому форкованому репозиторії.
Наведена вище команда створює гілку у вашому форкнутому репозиторії.
1. **Відкрийте PR**. Далі ви хочете відкрити PR. Для цього перейдіть до форкованого репозиторію на GitHub. Ви побачите індикацію на GitHub, де вас запитають, чи хочете ви створити новий PR, натисніть на це, і вас перенаправлять на інтерфейс, де ви зможете змінити заголовок повідомлення про коміт, дати йому більш відповідний опис. Тепер підтримувач репозиторію, який ви форкнули, побачить цей PR і, _сподіваємося_, оцінить і _об'єднає_ ваш PR. Ви тепер учасник, ура :)
1. **Відкрийте PR**. Далі ви хочете відкрити PR. Ви робите це, перейшовши до форкнутого репозиторію на GitHub. Ви побачите індикацію на GitHub, де вас запитають, чи хочете ви створити новий PR. Натисніть це, і ви потрапите в інтерфейс, де зможете змінити заголовок повідомлення коміту, дати йому більш відповідний опис. Тепер підтримувач репозиторію, який ви форкнули, побачить цей PR і, _сподіваємося_, оцінить і _об'єднає_ ваш PR. Ви тепер учасник, ура :)
1. **Очистіть**. Вважається гарною практикою _очищати_ після успішного об'єднання PR. Ви хочете очистити як вашу локальну гілку, так і гілку, яку ви відправили на GitHub. Спочатку видаліть її локально за допомогою наступної команди:
1. **Очистіть**. Вважається гарною практикою _очистити_ після успішного об'єднання PR. Ви хочете очистити як локальну гілку, так і гілку, яку ви відправили на GitHub. Спочатку видаліть її локально за допомогою наступної команди:
```bash
git branch -d [branch-name]
```
Перейдіть на сторінку GitHub для форкнутого репозиторію та видаліть віддалену гілку, яку ви щойно запушили.
`Pull request` здається дивним терміном, адже насправді ви хочете запушити свої зміни до проєкту. Але мейнтейнер (власник проєкту) або основна команда повинні розглянути ваші зміни перед тим, як об'єднати їх із "головною" гілкою проєкту, тому ви фактично запитуєте рішення про зміну у мейнтейнера.
Переконайтеся, що ви перейшли на сторінку GitHub для форкнут
`Pull request` здається трохи дивним терміном, адже насправді ви хочете "запушити" свої зміни до проєкту. Але власник проєкту або основна команда повинні розглянути ваші зміни перед тим, як об'єднати їх із "головною" гілкою проєкту, тому ви фактично запитуєте рішення про внесення змін у власника.
Pull request — це місце для порівняння та обговорення відмінностей, внесених у гілку, з рецензіями, коментарями, інтегрованими тестами тощо. Хороший pull request дотримується приблизно тих самих правил, що й повідомлення про коміт. Ви можете додати посилання на проблему в трекері проблем, якщо ваша робота, наприклад, виправляє проблему. Це робиться за допомогою символу `#`, за яким слідує номер вашої проблеми. Наприклад, `#97`.
Pull request — це місце для порівняння та обговорення відмінностей, внесених у гілку, з рецензіями, коментарями, інтегрованими тестами тощо. Хороший pull request дотримується приблизно тих самих правил, що й повідомлення про коміт. Ви можете додати посилання на проблему в трекері проблем, якщо ваша робота, наприклад, виправляє цю проблему. Це робиться за допомогою символу `#`, за яким слідує номер вашої проблеми. Наприклад, `#97`.
🤞Сподіваємося, що всі перевірки пройдуть успішно, і власник(и) проєкту об'єднають ваші зміни в проєкт🤞
🤞Тримаємо кулаки, щоб усі перевірки пройшли успішно, і власник(и) проєкту об'єднали ваші зміни з проєктом🤞
Оновіть вашу поточну локальну робочу гілку всіма новими комітами з відповідної віддаленої гілки на GitHub:
`git pull`
## Як зробити внесок у проєкт з відкритим кодом
## Як зробити внесок у проєкти з відкритим кодом
Спочатку знайдіть репозиторій (або **repo**) на GitHub, який вас цікавить і до якого ви хочете внести зміни. Вам потрібно буде скопіювати його вміст на свій комп'ютер.
Спочатку знайдіть репозиторій (або **репо**) на GitHub, який вас цікавить і до якого ви хочете внести зміни. Вам потрібно буде скопіювати його вміст на свій комп'ютер.
✅ Хороший спосіб знайти репозиторії для початківців — це [шукати за тегом 'good-first-issue'](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/).
![Скопіювати репозиторій локально](../../../../translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.uk.png)
![Скопіюйте репозиторій локально](../../../../translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.uk.png)
Є кілька способів скопіювати код. Один із них — "клонувати" вміст репозиторію, використовуючи HTTPS, SSH або GitHub CLI (інтерфейс командного рядка).
Відкрийте термінал і клонуйте репозиторій таким чином:
`git clone https://github.com/ProjectURL`
Щоб працювати над проєктом, перейдіть у потрібну папку:
Щоб працювати над проєктом, перейдіть до потрібної папки:
`cd ProjectURL`
Ви також можете відкрити весь проєкт за допомогою [Codespaces](https://github.com/features/codespaces), вбудованого редактора коду / хмарного середовища розробки від GitHub, або [GitHub Desktop](https://desktop.github.com/).
@ -300,28 +300,28 @@ Pull request — це місце для порівняння та обговор
### Кілька цікавих фактів про GitHub
Ви можете додати зірочку, стежити або "форкнути" будь-який публічний репозиторій на GitHub. Ви знайдете свої зіркові репозиторії у випадаючому меню у верхньому правому куті. Це як закладки, але для коду.
Ви можете додати зірочку, спостерігати або "форкнути" будь-який публічний репозиторій на GitHub. Ваші зіркові репозиторії можна знайти у випадаючому меню у верхньому правому куті. Це як закладки, але для коду.
Проєкти мають трекер проблем, зазвичай на GitHub у вкладці "Issues", якщо не вказано інше, де люди обговорюють проблеми, пов'язані з проєктом. А вкладка Pull Requests — це місце, де люди обговорюють і переглядають зміни, які перебувають у процесі.
У проєктах є трекер проблем, зазвичай на GitHub у вкладці "Issues", якщо не вказано інше, де люди обговорюють проблеми, пов'язані з проєктом. А вкладка Pull Requests — це місце, де обговорюють і переглядають зміни, які перебувають у процесі.
Проєкти також можуть мати обговорення на форумах, у списках розсилки або в чатах, таких як Slack, Discord чи IRC.
У проєктах також можуть бути обговорення на форумах, у списках розсилки або в чатах, таких як Slack, Discord чи IRC.
✅ Ознайомтеся з вашим новим репозиторієм на GitHub і спробуйте кілька речей, наприклад, змінити налаштування, додати інформацію до репозиторію та створити проєкт (наприклад, дошку Kanban). Є багато цікавого, що можна зробити!
✅ Ознайомтеся з вашим новим репозиторієм на GitHub і спробуйте кілька речей, наприклад, змінити налаштування, додати інформацію до репозиторію або створити проєкт (наприклад, дошку Kanban). Є багато цікавого, що можна зробити!
---
## 🚀 Виклик
Попрацюйте разом із другом над кодом один одного. Створіть проєкт спільно, форкніть код, створіть гілки та об'єднайте зміни.
Попрацюйте в парі з другом над кодом один одного. Створіть спільний проєкт, форкніть код, створіть гілки та об'єднайте зміни.
## Післялекційний тест
[Післялекційний тест](https://ff-quizzes.netlify.app/web/quiz/4)
[Післялекційний тест](https://ff-quizzes.netlify.app/web/en/)
## Огляд і самостійне навчання
Дізнайтеся більше про [внесок у програмне забезпечення з відкритим кодом](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution).
[Шпаргалка по Git](https://training.github.com/downloads/github-git-cheat-sheet/).
[Шпаргалка з Git](https://training.github.com/downloads/github-git-cheat-sheet/).
Практикуйтеся, практикуйтеся, практикуйтеся. GitHub пропонує чудові навчальні шляхи через [skills.github.com](https://skills.github.com):
@ -336,4 +336,4 @@ Pull request — це місце для порівняння та обговор
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильне тлумачення, що виникають внаслідок використання цього перекладу.

@ -1,25 +1,25 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e4cd5b1faed4adab5acf720f82798003",
"translation_date": "2025-08-27T22:48:55+00:00",
"original_hash": "7598502c4dd1630c72b19ae6bd2523a4",
"translation_date": "2025-08-28T18:24:31+00:00",
"source_file": "1-getting-started-lessons/3-accessibility/README.md",
"language_code": "uk"
}
-->
# Створення доступних веб-сторінок
# Створення доступних вебсторінок
![Все про доступність](../../../../translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.uk.png)
> Скетчнот від [Tomomi Imura](https://twitter.com/girlie_mac)
## Тест перед лекцією
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/5)
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/)
> Сила вебу полягає в його універсальності. Доступ для всіх, незалежно від обмежень, є важливим аспектом.
> Сила Інтернету полягає в його універсальності. Доступ для всіх, незалежно від обмежень, є важливим аспектом.
>
> \- Сер Тімоті Бернерс-Лі, директор W3C та винахідник Всесвітньої павутини
Ця цитата ідеально підкреслює важливість створення доступних веб-сайтів. Додаток, який не може бути доступним для всіх, за визначенням є виключаючим. Як веб-розробники, ми завжди повинні пам’ятати про доступність. Якщо зосередитися на цьому з самого початку, ви будете на правильному шляху, щоб забезпечити доступність сторінок, які ви створюєте. У цьому уроці ви дізнаєтеся про інструменти, які допоможуть вам забезпечити доступність ваших веб-ресурсів, і як створювати з урахуванням доступності.
Ця цитата ідеально підкреслює важливість створення доступних вебсайтів. Додаток, який не може бути доступним для всіх, за визначенням є виключаючим. Як веброзробники, ми завжди повинні пам’ятати про доступність. Якщо зосередитися на цьому з самого початку, ви будете на правильному шляху, щоб забезпечити доступність сторінок, які ви створюєте. У цьому уроці ви дізнаєтеся про інструменти, які допоможуть вам забезпечити доступність ваших вебресурсів, і як створювати їх з урахуванням доступності.
> Ви можете пройти цей урок на [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon)!
@ -29,99 +29,99 @@ CO_OP_TRANSLATOR_METADATA:
Одним із найвідоміших інструментів доступності є екранні читачі.
[Екранні читачі](https://en.wikipedia.org/wiki/Screen_reader) зазвичай використовуються людьми з порушеннями зору. Як ми витрачаємо час на те, щоб браузер правильно передавав інформацію, яку ми хочемо поділитися, ми також повинні переконатися, що екранний читач робить те саме.
[Екранні читачі](https://en.wikipedia.org/wiki/Screen_reader) зазвичай використовуються людьми з порушеннями зору. Як ми витрачаємо час на те, щоб браузер правильно передавав інформацію, яку ми хочемо поділитися, так само ми повинні переконатися, що екранний читач робить це правильно.
У найпростішому вигляді екранний читач буде читати сторінку зверху вниз вголос. Якщо ваша сторінка складається лише з тексту, читач передасть інформацію аналогічно браузеру. Звісно, веб-сторінки рідко бувають лише текстовими; вони містять посилання, графіку, кольори та інші візуальні компоненти. Потрібно подбати про те, щоб ця інформація була правильно прочитана екранним читачем.
У найпростішому вигляді екранний читач буде читати сторінку зверху донизу вголос. Якщо ваша сторінка складається лише з тексту, читач передасть інформацію подібно до браузера. Звісно, вебсторінки рідко бувають лише текстовими; вони містять посилання, графіку, кольори та інші візуальні компоненти. Потрібно подбати про те, щоб ця інформація правильно читалася екранним читачем.
Кожен веб-розробник повинен ознайомитися з екранним читачем. Як зазначено вище, це клієнт, яким користуватимуться ваші користувачі. Так само, як ви знайомі з тим, як працює браузер, ви повинні дізнатися, як працює екранний читач. На щастя, екранні читачі вбудовані в більшість операційних систем.
Кожен веброзробник повинен ознайомитися з екранним читачем. Як зазначено вище, це клієнт, яким користуватимуться ваші користувачі. Так само, як ви знайомі з тим, як працює браузер, ви повинні дізнатися, як працює екранний читач. На щастя, екранні читачі вбудовані в більшість операційних систем.
Деякі браузери також мають вбудовані інструменти та розширення, які можуть читати текст вголос або навіть надавати деякі базові функції навігації, наприклад, [ці інструменти доступності для браузера Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Вони також є важливими інструментами доступності, але працюють зовсім інакше, ніж екранні читачі, і їх не слід плутати з інструментами тестування екранних читачів.
Деякі браузери також мають вбудовані інструменти та розширення, які можуть читати текст вголос або навіть надавати базові навігаційні функції, наприклад, [ці інструменти доступності для браузера Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Вони також є важливими інструментами доступності, але працюють зовсім інакше, ніж екранні читачі, і їх не слід плутати з інструментами тестування екранних читачів.
✅ Спробуйте екранний читач і текстовий читач браузера. У Windows за замовчуванням включено [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon), а також можна встановити [JAWS](https://webaim.org/articles/jaws/) і [NVDA](https://www.nvaccess.org/about-nvda/). У macOS та iOS за замовчуванням встановлено [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10).
### Збільшення
Ще одним інструментом, який часто використовують люди з порушеннями зору, є функція збільшення. Найбільш базовий тип збільшення — це статичне збільшення, яке контролюється через `Control + плюс (+)` або шляхом зменшення роздільної здатності екрана. Цей тип збільшення змушує всю сторінку змінювати розмір, тому використання [адаптивного дизайну](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) важливе для забезпечення гарного користувацького досвіду на збільшених рівнях.
Ще одним інструментом, який часто використовують люди з порушеннями зору, є функція збільшення. Найбільш базовий тип збільшення — це статичне збільшення, яке контролюється через `Control + плюс (+)` або зменшенням роздільної здатності екрана. Цей тип збільшення змушує всю сторінку змінювати розмір, тому використання [адаптивного дизайну](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) є важливим для забезпечення гарного користувацького досвіду на збільшених рівнях.
Інший тип збільшення використовує спеціалізоване програмне забезпечення для збільшення однієї області екрана та панорамування, як при використанні реальної лупи. У Windows вбудовано [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198), а [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) є стороннім програмним забезпеченням для збільшення з більшою кількістю функцій і ширшою базою користувачів. У macOS та iOS є вбудоване програмне забезпечення для збільшення під назвою [Zoom](https://www.apple.com/accessibility/mac/vision/).
Інший тип збільшення покладається на спеціалізоване програмне забезпечення, яке збільшує одну область екрана та дозволяє панорамувати, подібно до використання реальної лупи. У Windows вбудовано [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198), а [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) є стороннім програмним забезпеченням для збільшення з більшою кількістю функцій і ширшою базою користувачів. У macOS та iOS є вбудоване програмне забезпечення для збільшення під назвою [Zoom](https://www.apple.com/accessibility/mac/vision/).
### Перевірка контрасту
Кольори на веб-сайтах потрібно ретельно вибирати, щоб відповідати потребам користувачів із кольоровою сліпотою або людей, які мають труднощі з розпізнаванням кольорів із низьким контрастом.
Кольори на вебсайтах потрібно ретельно підбирати, щоб відповідати потребам користувачів із дальтонізмом або тих, хто має труднощі з розрізненням кольорів із низьким контрастом.
✅ Перевірте веб-сайт, який вам подобається, на використання кольорів за допомогою розширення браузера, наприклад, [перевірки контрасту кольорів WCAG](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon). Що ви дізналися?
✅ Перевірте вебсайт, який вам подобається, на використання кольорів за допомогою розширення браузера, наприклад, [перевірки контрасту кольорів WCAG](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon). Що ви дізналися?
### Lighthouse
У розділі інструментів розробника вашого браузера ви знайдете інструмент Lighthouse. Цей інструмент важливий для отримання першого погляду на доступність (а також інші аналізи) веб-сайту. Хоча важливо не покладатися виключно на Lighthouse, оцінка 100% є дуже корисною як базовий показник.
У розділі інструментів розробника вашого браузера ви знайдете інструмент Lighthouse. Цей інструмент важливий для отримання першого уявлення про доступність (а також інші аспекти аналізу) вебсайту. Хоча не варто покладатися виключно на Lighthouse, 100% оцінка є дуже корисною як базовий показник.
✅ Знайдіть Lighthouse у панелі інструментів розробника вашого браузера та проведіть аналіз будь-якого сайту. Що ви виявили?
## Проектування з урахуванням доступності
## Проєктування з урахуванням доступності
Доступність — це досить велика тема. Щоб допомогти вам, доступно багато ресурсів.
Доступність — це досить велика тема. Щоб допомогти вам, існує безліч ресурсів.
- [Accessible U - Університет Міннесоти](https://accessibility.umn.edu/your-role/web-developers)
Хоча ми не зможемо охопити всі аспекти створення доступних сайтів, нижче наведено деякі основні принципи, які ви захочете впровадити. Проектування доступної сторінки з самого початку **завжди** легше, ніж повернення до існуючої сторінки для її адаптації.
Хоча ми не зможемо охопити всі аспекти створення доступних сайтів, нижче наведено деякі основні принципи, які ви захочете впровадити. Проєктування доступної сторінки з самого початку **завжди** легше, ніж повертатися до існуючої сторінки, щоб зробити її доступною.
## Хороші принципи відображення
## Принципи гарного відображення
### Безпечні палітри кольорів
### Безпечні кольорові палітри
Люди бачать світ по-різному, і це включає кольори. Вибираючи кольорову схему для вашого сайту, ви повинні переконатися, що вона доступна для всіх. Один чудовий [інструмент для створення палітр кольорів — Color Safe](http://colorsafe.co/).
Люди бачать світ по-різному, і це стосується також кольорів. Вибираючи кольорову схему для вашого сайту, ви повинні переконатися, що вона доступна для всіх. Один із чудових [інструментів для створення кольорових палітр — Color Safe](http://colorsafe.co/).
✅ Визначте веб-сайт, який має серйозні проблеми у використанні кольорів. Чому?
✅ Визначте вебсайт, який має серйозні проблеми з використанням кольорів. Чому?
### Використовуйте правильний HTML
За допомогою CSS і JavaScript можна зробити будь-який елемент схожим на будь-який тип елемента управління. `<span>` може бути використаний для створення `<button>`, а `<b>` може стати гіперпосиланням. Хоча це може здатися легшим для стилізації, це нічого не передає екранному читачу. Використовуйте відповідний HTML при створенні елементів управління на сторінці. Якщо вам потрібне гіперпосилання, використовуйте `<a>`. Використання правильного HTML для правильного елемента управління називається використанням семантичного HTML.
За допомогою CSS і JavaScript можна зробити будь-який елемент схожим на будь-який тип елемента керування. `<span>` може бути використаний для створення `<button>`, а `<b>` може стати гіперпосиланням. Хоча це може здатися простішим для стилізації, це нічого не передає екранному читачу. Використовуйте відповідний HTML при створенні елементів керування на сторінці. Якщо вам потрібне гіперпосилання, використовуйте `<a>`. Використання правильного HTML для правильного елемента керування називається використанням семантичного HTML.
✅ Перейдіть на будь-який веб-сайт і перевірте, чи дизайнери та розробники правильно використовують HTML. Чи можете ви знайти кнопку, яка повинна бути посиланням? Підказка: клацніть правою кнопкою миші та виберіть "Переглянути джерело сторінки" у вашому браузері, щоб переглянути основний код.
✅ Перейдіть на будь-який вебсайт і подивіться, чи використовують дизайнери та розробники HTML правильно. Чи можете ви знайти кнопку, яка повинна бути посиланням? Підказка: клацніть правою кнопкою миші та виберіть "Переглянути вихідний код сторінки" у вашому браузері, щоб подивитися на основний код.
### Створіть описову ієрархію заголовків
### Створюйте описову ієрархію заголовків
Користувачі екранних читачів [дуже сильно покладаються на заголовки](https://webaim.org/projects/screenreadersurvey8/#finding), щоб знаходити інформацію та навігацію по сторінці. Написання описового змісту заголовків і використання семантичних тегів заголовків важливі для створення легкої навігації для користувачів екранних читачів.
Користувачі екранних читачів [дуже покладаються на заголовки](https://webaim.org/projects/screenreadersurvey8/#finding) для пошуку інформації та навігації сторінкою. Написання описового змісту заголовків і використання семантичних тегів заголовків є важливими для створення сайту, яким легко користуватися за допомогою екранного читача.
### Використовуйте хороші візуальні підказки
CSS пропонує повний контроль над виглядом будь-якого елемента на сторінці. Ви можете створити текстові поля без контуру або гіперпосилання без підкреслення. На жаль, видалення цих підказок може ускладнити розпізнавання типу елемента для тих, хто залежить від них.
CSS надає повний контроль над виглядом будь-якого елемента на сторінці. Ви можете створити текстові поля без обведення або гіперпосилання без підкреслення. На жаль, видалення цих підказок може ускладнити розпізнавання типу елемента керування для тих, хто залежить від них.
## Важливість тексту посилань
Гіперпосилання є основою навігації в Інтернеті. Тому забезпечення того, щоб екранний читач міг правильно читати посилання, дозволяє всім користувачам навігацію вашим сайтом.
Гіперпосилання є основою навігації в Інтернеті. Тому забезпечення того, щоб екранний читач міг правильно читати посилання, дозволяє всім користувачам орієнтуватися на вашому сайті.
### Екранні читачі та посилання
Як і очікувалося, екранні читачі читають текст посилань так само, як і будь-який інший текст на сторінці. З огляду на це, текст, наведений нижче, може здатися цілком прийнятним.
> Маленький пінгвін, іноді відомий як казковий пінгвін, є найменшим пінгвіном у світі. [Натисніть тут](https://en.wikipedia.org/wiki/Little_penguin) для отримання додаткової інформації.
> Малий пінгвін, іноді відомий як казковий пінгвін, є найменшим пінгвіном у світі. [Натисніть тут](https://en.wikipedia.org/wiki/Little_penguin) для отримання додаткової інформації.
> Маленький пінгвін, іноді відомий як казковий пінгвін, є найменшим пінгвіном у світі. Відвідайте https://en.wikipedia.org/wiki/Little_penguin для отримання додаткової інформації.
> Малий пінгвін, іноді відомий як казковий пінгвін, є найменшим пінгвіном у світі. Відвідайте https://en.wikipedia.org/wiki/Little_penguin для отримання додаткової інформації.
> **NOTE** Як ви зараз прочитаєте, ви **ніколи** не повинні створювати посилання, які виглядають як наведені вище.
> **NOTE** Як ви зараз прочитаєте, ви **ніколи** не повинні створювати посилання, які виглядають, як наведені вище.
Пам’ятайте, екранні читачі — це інший інтерфейс, ніж браузери, з іншим набором функцій.
### Проблема використання URL
### Проблема з використанням URL
Екранні читачі читають текст. Якщо URL з’являється в тексті, екранний читач прочитає URL. Загалом, URL не передає значущої інформації та може звучати дратівливо. Ви могли відчути це, якщо ваш телефон коли-небудь вголос читав текстове повідомлення з URL.
Екранні читачі читають текст. Якщо в тексті з’являється URL, екранний читач прочитає URL. Як правило, URL не передає змістовної інформації та може звучати дратівливо. Ви могли відчути це, якщо ваш телефон коли-небудь вголос читав текстове повідомлення з URL.
### Проблема "натисніть тут"
### Проблема з "натисніть тут"
Екранні читачі також мають можливість читати лише гіперпосилання на сторінці, так само, як людина з нормальним зором сканує сторінку на предмет посилань. Якщо текст посилання завжди "натисніть тут", користувач почує лише "натисніть тут, натисніть тут, натисніть тут, натисніть тут, натисніть тут, ..." Усі посилання тепер не відрізняються одне від одного.
Екранні читачі також мають можливість читати лише гіперпосилання на сторінці, так само, як людина з нормальним зором сканує сторінку в пошуках посилань. Якщо текст посилання завжди "натисніть тут", користувач почує лише "натисніть тут, натисніть тут, натисніть тут, натисніть тут, натисніть тут, ...". Усі посилання тепер не відрізняються одне від одного.
### Хороший текст посилання
Хороший текст посилання коротко описує, що знаходиться на іншій стороні посилання. У наведеному вище прикладі про маленьких пінгвінів посилання веде на сторінку Вікіпедії про цей вид. Фраза *маленькі пінгвіни* була б ідеальним текстом посилання, оскільки вона чітко пояснює, що хтось дізнається, якщо натисне на посилання - маленькі пінгвіни.
Хороший текст посилання коротко описує, що знаходиться за посиланням. У наведеному вище прикладі про малих пінгвінів посилання веде на сторінку Вікіпедії про цей вид. Фраза *малий пінгвін* була б ідеальним текстом посилання, оскільки вона чітко вказує, що дізнається користувач, якщо натисне на посилання — про малих пінгвінів.
> [Маленький пінгвін](https://en.wikipedia.org/wiki/Little_penguin), іноді відомий як казковий пінгвін, є найменшим пінгвіном у світі.
> [Малий пінгвін](https://en.wikipedia.org/wiki/Little_penguin), іноді відомий як казковий пінгвін, є найменшим пінгвіном у світі.
✅ Перегляньте Інтернет кілька хвилин, щоб знайти сторінки, які використовують незрозумілі стратегії посилань. Порівняйте їх із іншими, краще пов’язаними сайтами. Що ви дізналися?
#### Примітки для пошукових систем
Як додатковий бонус для забезпечення доступності вашого сайту для всіх, ви допоможете пошуковим системам навігацію вашим сайтом. Пошукові системи використовують текст посилань, щоб дізнатися теми сторінок. Тому використання хорошого тексту посилань допомагає всім!
Як додатковий бонус за забезпечення доступності вашого сайту для всіх, ви допоможете пошуковим системам орієнтуватися на вашому сайті. Пошукові системи використовують текст посилань, щоб дізнатися теми сторінок. Тому використання хорошого тексту посилань допомагає всім!
### ARIA
@ -129,22 +129,22 @@ CSS пропонує повний контроль над виглядом бу
| Продукт | Опис | Замовлення |
| ------------ | ----------------- | ------------ |
| Віджет | [Опис](../../../../1-getting-started-lessons/3-accessibility/') | [Замовлення](../../../../1-getting-started-lessons/3-accessibility/') |
| Супервіджет | [Опис](../../../../1-getting-started-lessons/3-accessibility/') | [Замовлення](../../../../1-getting-started-lessons/3-accessibility/') |
| Віджет | [Опис](../../../../1-getting-started-lessons/3-accessibility/') | [Замовити](../../../../1-getting-started-lessons/3-accessibility/') |
| Супервіджет | [Опис](../../../../1-getting-started-lessons/3-accessibility/') | [Замовити](../../../../1-getting-started-lessons/3-accessibility/') |
У цьому прикладі дублювання тексту опису та замовлення має сенс для тих, хто використовує браузер. Однак той, хто використовує екранний читач, почує лише слова *опис* і *замовлення*, повторені без контексту.
У цьому прикладі дублювання тексту "опис" і "замовлення" має сенс для користувача браузера. Однак користувач екранного читача почує лише слова *опис* і *замовлення*, повторені без контексту.
Щоб підтримати такі сценарії, HTML підтримує набір атрибутів, відомих як [Доступні багаті інтернет-додатки (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Ці атрибути дозволяють надавати додаткову інформацію екранним читачам.
Щоб підтримати такі сценарії, HTML підтримує набір атрибутів, відомих як [ARIA (Доступні багаті інтернет-додатки)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Ці атрибути дозволяють надавати додаткову інформацію екранним читачам.
> **NOTE**: Як і багато аспектів HTML, підтримка браузерів і екранних читачів може відрізнятися. Однак більшість основних клієнтів підтримують атрибути ARIA.
> **NOTE**: Як і багато аспектів HTML, підтримка браузерами та екранними читачами може відрізнятися. Однак більшість основних клієнтів підтримують атрибути ARIA.
Ви можете використовувати `aria-label`, щоб описати посилання, коли формат сторінки не дозволяє це зробити. Опис для віджета можна встановити як
Ви можете використовувати `aria-label`, щоб описати посилання, коли формат сторінки цього не дозволяє. Опис для віджета можна встановити як
``` html
<a href="#" aria-label="Widget description">description</a>
```
✅ Загалом, використання семантичної розмітки, як описано вище, перевершує використання ARIA, але іноді немає семантичного еквівалента для різних HTML-елементів. Хорошим прикладом є дерево. Немає HTML-еквівалента для дерева, тому ви ідентифікуєте загальний `<div>` для цього елемента з відповідною роллю та значеннями ARIA. [Документація MDN про ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) містить більше корисної інформації.
✅ Загалом, використання семантичної розмітки, як описано вище, має перевагу над використанням ARIA, але іноді немає семантичного еквівалента для різних HTML-елементів. Хорошим прикладом є дерево. Немає HTML-еквівалента для дерева, тому ви ідентифікуєте загальний `<div>` для цього елемента з відповідною роллю та значеннями ARIA. [Документація MDN про ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) містить більше корисної інформації.
```html
<h2 id="tree-label">File Viewer</h2>
@ -155,14 +155,14 @@ CSS пропонує повний контроль над виглядом бу
## Зображення
Само собою зрозуміло, що екранні читачі не можуть автоматично читати, що знаходиться на зображенні. Забезпечення доступності зображень не потребує багато роботи - саме для цього існує атрибут `alt`. Усі значущі зображення повинні мати `alt`, щоб описати, що вони представляють.
Само собою зрозуміло, що екранні читачі не можуть автоматично читати, що знаходиться на зображенні. Забезпечення доступності зображень не потребує багато зусиль — саме для цього існує атрибут `alt`. Усі значущі зображення повинні мати `alt`, щоб описати, що вони собою являють.
Зображення, які є суто декоративними, повинні мати атрибут `alt`, встановлений як порожній рядок: `alt=""`. Це запобігає непотрібному оголошенню декоративного зображення екранними читачами.
✅ Як ви могли очікувати, пошукові системи також не можуть зрозуміти, що знаходиться на зображенні. Вони також використовують текст alt. Тому, як завжди, забезпечення доступності вашої сторінки приносить додаткові бонуси!
✅ Як ви могли очікувати, пошукові системи також не можуть зрозуміти, що знаходиться на зображенні. Вони також використовують текст `alt`. Тому, знову ж таки, забезпечення доступності вашої сторінки приносить додаткові бонуси!
## Клавіатура
Деякі користувачі не можуть використовувати мишу або трекпад, натомість покладаються на взаємодію з клавіатурою, щоб переходити від одного елемента до іншого. Важливо, щоб ваш веб-сайт представляв ваш контент у логічному порядку, щоб користувач клавіатури міг отримати доступ до кожного інтерактивного елемента, рухаючись вниз по документу. Якщо ви створюєте свої веб-сторінки за допомогою семантичної розмітки та використовуєте CSS для стилізації їхнього візуального макета, ваш сайт повинен бути доступним для навігації за допомогою клавіатури, але
Деякі користувачі не можуть використовувати мишу або трекпад, натомість покладаючись на взаємодію з клавіатурою, щоб переходити від одного елемента до іншого. Важливо, щоб ваш вебсайт представляв ваш контент у логічному порядку, щоб користувач клавіатури міг отримати доступ до кожного інтерактивного елемента, рухаючись вниз по документу. Якщо ви створюєте свої вебсторінки з семантичною розміткою та використовуєте CSS для стилізації їхнього в
Багато урядів мають закони щодо вимог доступності. Ознайомтеся із законами про доступність у вашій країні. Що охоплюється, а що ні? Наприклад, [цей урядовий вебсайт](https://accessibility.blog.gov.uk/).
## Завдання

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "fc6aef8ecfdd5b0ad2afa6e6ba52bfde",
"translation_date": "2025-08-27T22:31:15+00:00",
"original_hash": "b95fdd8310ef467305015ece1b0f9411",
"translation_date": "2025-08-28T18:17:27+00:00",
"source_file": "2-js-basics/1-data-types/README.md",
"language_code": "uk"
}
@ -13,7 +13,7 @@ CO_OP_TRANSLATOR_METADATA:
> Скетчноут від [Tomomi Imura](https://twitter.com/girlie_mac)
## Тест перед лекцією
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/7)
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/)
Цей урок охоплює основи JavaScript — мови, яка забезпечує інтерактивність у вебі.
@ -29,13 +29,13 @@ CO_OP_TRANSLATOR_METADATA:
## Змінні
Змінні зберігають значення, які можна використовувати та змінювати в коді.
Змінні зберігають значення, які можна використовувати та змінювати у вашому коді.
Створення та **оголошення** змінної має наступний синтаксис **[ключове слово] [назва]**. Це складається з двох частин:
- **Ключове слово**. Ключовими словами можуть бути `let` або `var`.
✅ Ключове слово `let` було введено в ES6 і надає змінній так звану _блокову область видимості_. Рекомендується використовувати `let` замість `var`. Ми детальніше розглянемо блокові області видимості в наступних частинах.
✅ Ключове слово `let` було введено в ES6 і надає вашій змінній так звану _блокову область видимості_. Рекомендується використовувати `let` замість `var`. Ми детальніше розглянемо блокову область видимості в наступних частинах.
- **Назва змінної**, це ім'я, яке ви обираєте самостійно.
@ -47,7 +47,7 @@ CO_OP_TRANSLATOR_METADATA:
let myVariable;
```
`myVariable` тепер оголошено за допомогою ключового слова `let`. На даний момент вона не має значення.
`myVariable` тепер оголошено за допомогою ключового слова `let`. Наразі вона не має значення.
1. **Присвойте значення**. Збережіть значення у змінній за допомогою оператора `=`, після якого йде очікуване значення.
@ -65,7 +65,7 @@ CO_OP_TRANSLATOR_METADATA:
let myVariable = 123;
```
Вище наведено приклад _явної ініціалізації_, коли змінна оголошується і їй одночасно присвоюється значення.
Вище наведено _явну ініціалізацію_, коли змінна оголошується і їй одночасно присвоюється значення.
1. **Змініть значення змінної**. Змініть значення змінної наступним чином:
@ -73,21 +73,21 @@ CO_OP_TRANSLATOR_METADATA:
myVariable = 321;
```
Після того, як змінна оголошена, ви можете змінити її значення в будь-який момент у вашому коді за допомогою оператора `=` і нового значення.
Після того, як змінна оголошена, ви можете змінити її значення в будь-який момент вашого коду за допомогою оператора `=` і нового значення.
✅ Спробуйте! Ви можете писати JavaScript прямо у вашому браузері. Відкрийте вікно браузера та перейдіть до Інструментів розробника. У консолі ви знайдете запит; введіть `let myVariable = 123`, натисніть Enter, а потім введіть `myVariable`. Що відбувається? Зверніть увагу, що ви дізнаєтеся більше про ці концепції в наступних уроках.
✅ Спробуйте! Ви можете писати JavaScript прямо у вашому браузері. Відкрийте вікно браузера і перейдіть до Інструментів розробника. У консолі ви знайдете запит; введіть `let myVariable = 123`, натисніть Enter, а потім введіть `myVariable`. Що відбувається? Зверніть увагу, що ви дізнаєтеся більше про ці концепції в наступних уроках.
## Константи
Оголошення та ініціалізація константи слідує тим самим принципам, що і змінна, за винятком ключового слова `const`. Константи зазвичай оголошуються великими літерами.
Оголошення та ініціалізація константи слідує тим же концепціям, що і змінна, за винятком ключового слова `const`. Константи зазвичай оголошуються великими літерами.
```javascript
const MY_VARIABLE = 123;
```
Константи схожі на змінні, але мають дві відмінності:
Константи схожі на змінні, але мають два винятки:
- **Мають значення**. Константи повинні бути ініціалізовані, інакше виникне помилка при виконанні коду.
- **Мають мати значення**. Константи повинні бути ініціалізовані, інакше виникне помилка при виконанні коду.
- **Посилання не може бути змінено**. Посилання константи не може бути змінено після ініціалізації, інакше виникне помилка при виконанні коду. Розглянемо два приклади:
- **Просте значення**. Наступне НЕ дозволено:
@ -110,19 +110,19 @@ const MY_VARIABLE = 123;
obj.a = 5; // allowed
```
Вище ви змінюєте значення об'єкта, але не його посилання, що робить це дозволеним.
Вище ви змінюєте значення об'єкта, але не саме посилання, що робить це дозволеним.
> Примітка: `const` означає, що посилання захищене від повторного присвоєння. Значення не є езмінним_ і може змінюватися, особливо якщо це складна структура, як об'єкт.
## Типи даних
Змінні можуть зберігати багато різних типів значень, таких як числа та текст. Ці різні типи значень відомі як **типи даних**. Типи даних є важливою частиною розробки програмного забезпечення, оскільки вони допомагають розробникам приймати рішення про те, як має бути написаний код і як має працювати програмне забезпечення. Крім того, деякі типи даних мають унікальні функції, які допомагають трансформувати або витягувати додаткову інформацію зі значення.
Змінні можуть зберігати багато різних типів значень, таких як числа і текст. Ці різні типи значень відомі як **типи даних**. Типи даних є важливою частиною розробки програмного забезпечення, оскільки вони допомагають розробникам приймати рішення про те, як має бути написаний код і як має працювати програмне забезпечення. Крім того, деякі типи даних мають унікальні функції, які допомагають трансформувати або витягувати додаткову інформацію зі значення.
✅ Типи даних також називаються примітивами даних JavaScript, оскільки вони є найнижчим рівнем типів даних, які надаються мовою. Існує 7 примітивних типів даних: string, number, bigint, boolean, undefined, null і symbol. Зробіть паузу, щоб уявити, що кожен із цих примітивів може представляти. Що таке `zebra`? А `0`? `true`?
### Числа
У попередньому розділі значення `myVariable` було типом даних "число".
У попередньому розділі значення `myVariable` було типу даних "число".
`let myVariable = 123;`
@ -132,13 +132,13 @@ const MY_VARIABLE = 123;
Існує кілька типів операторів для виконання арифметичних функцій, і деякі з них наведені тут:
| Символ | Опис | Приклад |
| ------ | ------------------------------------------------------------------------ | -------------------------------- |
| `+` | **Додавання**: обчислює суму двох чисел | `1 + 2 //очікувана відповідь 3` |
| `-` | **Віднімання**: обчислює різницю двох чисел | `1 - 2 //очікувана відповідь -1` |
| `*` | **Множення**: обчислює добуток двох чисел | `1 * 2 //очікувана відповідь 2` |
| `/` | **Ділення**: обчислює частку двох чисел | `1 / 2 //очікувана відповідь 0.5` |
| `%` | **Залишок**: обчислює залишок від ділення двох чисел | `1 % 2 //очікувана відповідь 1` |
| Символ | Опис | Приклад |
| ------ | ---------------------------------------------------------------------- | -------------------------------- |
| `+` | **Додавання**: Обчислює суму двох чисел | `1 + 2 //очікувана відповідь 3` |
| `-` | **Віднімання**: Обчислює різницю двох чисел | `1 - 2 //очікувана відповідь -1` |
| `*` | **Множення**: Обчислює добуток двох чисел | `1 * 2 //очікувана відповідь 2` |
| `/` | **Ділення**: Обчислює частку двох чисел | `1 / 2 //очікувана відповідь 0.5` |
| `%` | **Залишок**: Обчислює залишок від ділення двох чисел | `1 % 2 //очікувана відповідь 1` |
✅ Спробуйте! Спробуйте виконати арифметичну операцію в консолі вашого браузера. Чи здивували вас результати?
@ -170,7 +170,7 @@ myString1 + ", " + myString2 + "!"; //Hello, World!
✅ Чому `1 + 1 = 2` у JavaScript, але `'1' + '1' = 11?` Подумайте про це. А як щодо `'1' + 1`?
**Шаблонні літерали** — це ще один спосіб форматування рядків, за винятком того, що замість лапок використовується зворотний апостроф. Все, що не є простим текстом, має бути поміщено в заповнювачі `${ }`. Це включає будь-які змінні, які можуть бути рядками.
**Шаблонні літерали** — це ще один спосіб форматування рядків, але замість лапок використовується зворотний апостроф. Все, що не є простим текстом, має бути поміщено в заповнювачі `${ }`. Це включає будь-які змінні, які можуть бути рядками.
```javascript
let myString1 = "Hello";
@ -186,7 +186,7 @@ let myString2 = "World";
### Булеві значення
Булеві значення можуть бути лише двох значень: `true` або `false`. Булеві значення допомагають приймати рішення про те, які рядки коду повинні виконуватися, коли виконуються певні умови. У багатьох випадках [оператори](../../../../2-js-basics/1-data-types) допомагають встановлювати значення булевих змінних, і ви часто помітите та напишете змінні, які ініціалізуються або їх значення оновлюються за допомогою оператора.
Булеві значення можуть бути лише двох значень: `true` або `false`. Булеві значення допомагають приймати рішення про те, які рядки коду повинні виконуватися, коли виконуються певні умови. У багатьох випадках [оператори](../../../../2-js-basics/1-data-types) допомагають встановлювати значення булевих змінних, і ви часто помічаєте та пишете змінні, які ініціалізуються або їх значення оновлюються за допомогою оператора.
- `let myTrueBool = true`
- `let myFalseBool = false`
@ -200,7 +200,7 @@ let myString2 = "World";
JavaScript відомий своїми несподіваними способами обробки типів даних час від часу. Проведіть невелике дослідження цих "підводних каменів". Наприклад: чутливість до регістру може вас здивувати! Спробуйте це у вашій консолі: `let age = 1; let Age = 2; age == Age` (результат `false` — чому?). Які ще підводні камені ви можете знайти?
## Тест після лекції
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/8)
[Тест після лекції](https://ff-quizzes.netlify.app)
## Огляд і самостійне навчання

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b4612bbb9ace984f374fcc80e3e035ad",
"translation_date": "2025-08-27T22:28:17+00:00",
"original_hash": "92e136090efc4341b1d51c37924c1802",
"translation_date": "2025-08-28T18:16:05+00:00",
"source_file": "2-js-basics/2-functions-methods/README.md",
"language_code": "uk"
}
@ -13,9 +13,9 @@ CO_OP_TRANSLATOR_METADATA:
> Скетчноут від [Tomomi Imura](https://twitter.com/girlie_mac)
## Тест перед лекцією
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/9)
[Тест перед лекцією](https://ff-quizzes.netlify.app)
Коли ми думаємо про написання коду, завжди важливо забезпечити його читабельність. Хоч це може звучати нелогічно, код читається набагато більше разів, ніж пишеться. Одним із ключових інструментів у наборі розробника для забезпечення підтримуваності коду є **функція**.
Коли ми думаємо про написання коду, завжди важливо забезпечити його читабельність. Хоч це може здатися нелогічним, код читається набагато більше разів, ніж пишеться. Одним із основних інструментів у наборі розробника для забезпечення підтримуваного коду є **функція**.
[![Методи та функції](https://img.youtube.com/vi/XgKsD6Zwvlc/0.jpg)](https://youtube.com/watch?v=XgKsD6Zwvlc "Методи та функції")
@ -25,9 +25,9 @@ CO_OP_TRANSLATOR_METADATA:
## Функції
У своїй основі функція — це блок коду, який ми можемо виконати за запитом. Це ідеально підходить для ситуацій, коли потрібно виконати одну й ту ж задачу кілька разів; замість дублювання логіки в різних місцях (що ускладнює оновлення в майбутньому), ми можемо централізувати її в одному місці та викликати, коли потрібно виконати операцію — функції навіть можна викликати з інших функцій!
У своїй основі функція — це блок коду, який ми можемо виконати за запитом. Це ідеально підходить для ситуацій, коли потрібно виконати одну й ту ж задачу кілька разів; замість дублювання логіки в різних місцях (що ускладнює оновлення в майбутньому), ми можемо централізувати її в одному місці та викликати, коли нам потрібно виконати операцію — функції навіть можна викликати з інших функцій!
Не менш важливою є можливість назвати функцію. Хоч це може здатися дрібницею, назва забезпечує швидкий спосіб документування частини коду. Це можна порівняти з написом на кнопці. Якщо я натисну кнопку з написом "Скасувати таймер", я знаю, що вона зупинить роботу годинника.
Не менш важливою є можливість назвати функцію. Хоч це може здатися дрібницею, назва забезпечує швидкий спосіб документування частини коду. Ви можете уявити це як мітку на кнопці. Якщо я натисну кнопку з написом "Скасувати таймер", я знаю, що вона зупинить годинник.
## Створення та виклик функції
@ -47,26 +47,26 @@ function displayGreeting() {
}
```
Щоразу, коли ми хочемо викликати (або виконати) нашу функцію, ми використовуємо її назву, а потім `()`. Варто зазначити, що функцію можна визначити як до, так і після її виклику; компілятор JavaScript знайде її для вас.
Коли ми хочемо викликати (або активувати) нашу функцію, ми використовуємо її назву, а потім `()`. Варто зазначити, що функцію можна визначити як до, так і після її виклику; компілятор JavaScript знайде її для вас.
```javascript
// calling our function
displayGreeting();
```
> **NOTE:** Існує особливий тип функції, відомий як **метод**, який ви вже використовували! Насправді, ми бачили це в нашій демонстрації вище, коли використовували `console.log`. Відмінність методу від функції полягає в тому, що метод прив’язаний до обєкта (`console` у нашому прикладі), тоді як функція є незалежною. Багато розробників використовують ці терміни взаємозамінно.
> **NOTE:** Існує особливий тип функції, відомий як **метод**, який ви вже використовували! Насправді, ми бачили це в нашій демонстрації вище, коли використовували `console.log`. Що відрізняє метод від функції, так це те, що метод прикріплений до об'єкта (`console` у нашому прикладі), тоді як функція є незалежною. Ви часто почуєте, як розробники використовують ці терміни взаємозамінно.
### Найкращі практики для функцій
Є кілька найкращих практик, які варто памятати при створенні функцій:
Є кілька найкращих практик, які варто пам'ятати при створенні функцій:
- Як завжди, використовуйте описові назви, щоб знати, що робитиме функція
- Використовуйте **camelCasing** для об’єднання слів
- Зосереджуйте функції на виконанні конкретного завдання
- Як завжди, використовуйте описові назви, щоб знати, що робить функція.
- Використовуйте **camelCasing** для об'єднання слів.
- Зосереджуйте функції на виконанні конкретного завдання.
## Передача інформації у функцію
Щоб зробити функцію більш універсальною, часто потрібно передавати їй інформацію. Якщо ми розглянемо наш приклад `displayGreeting` вище, він буде відображати лише **Hello, world!**. Не найкорисніша функція, яку можна створити. Якщо ми хочемо зробити її трохи більш гнучкою, наприклад, дозволити комусь вказати імя людини, яку потрібно привітати, ми можемо додати **параметр**. Параметр (іноді також називається **аргументом**) — це додаткова інформація, яка передається функції.
Щоб зробити функцію більш універсальною, часто потрібно передавати їй інформацію. Якщо ми розглянемо наш приклад `displayGreeting` вище, він буде відображати лише **Hello, world!**. Не найкорисніша функція, яку можна створити. Якщо ми хочемо зробити її трохи більш гнучкою, наприклад, дозволити комусь вказати ім'я людини, яку потрібно привітати, ми можемо додати **параметр**. Параметр (іноді також називається **аргументом**) — це додаткова інформація, яка передається функції.
Параметри перераховуються в частині визначення в дужках і розділяються комами, як показано нижче:
@ -76,7 +76,7 @@ function name(param, param2, param3) {
}
```
Ми можемо оновити наш `displayGreeting`, щоб приймати імя та відображати його.
Ми можемо оновити наш `displayGreeting`, щоб приймати ім'я та відображати його.
```javascript
function displayGreeting(name) {
@ -94,7 +94,7 @@ displayGreeting('Christopher');
## Значення за замовчуванням
Ми можемо зробити нашу функцію ще більш гнучкою, додавши більше параметрів. Але що, якщо ми не хочемо, щоб кожне значення було обов’язковим? Залишаючи ім’я обов’язковим (нам потрібно знати, кого ми вітаємо), ми можемо дозволити налаштувати саме привітання за бажанням. Якщо хтось не хоче його налаштовувати, ми надаємо значення за замовчуванням. Щоб надати значення за замовчуванням параметру, ми встановлюємо його так само, як встановлюємо значення для змінної — `parameterName = 'defaultValue'`. Повний приклад:
Ми можемо зробити нашу функцію ще більш гнучкою, додавши більше параметрів. Але що, якщо ми не хочемо вимагати, щоб кожне значення було вказане? Залишаючись у нашому прикладі привітання, ми можемо залишити ім'я обов'язковим (нам потрібно знати, кого ми вітаємо), але хочемо дозволити налаштувати саме привітання за бажанням. Якщо хтось не хоче його налаштовувати, ми надаємо значення за замовчуванням. Щоб надати значення за замовчуванням параметру, ми встановлюємо його так само, як встановлюємо значення для змінної — `parameterName = 'defaultValue'`. Повний приклад:
```javascript
function displayGreeting(name, salutation='Hello') {
@ -112,11 +112,11 @@ displayGreeting('Christopher', 'Hi');
// displays "Hi, Christopher"
```
## Значення, які повертаються
## Значення, що повертаються
До цього моменту функція, яку ми створили, завжди виводила результат у [консоль](https://developer.mozilla.org/docs/Web/API/console). Іноді це може бути саме те, що нам потрібно, особливо коли ми створюємо функції, які викликатимуть інші сервіси. Але що, якщо я хочу створити допоміжну функцію для виконання обчислення та отримати значення назад, щоб я міг використовувати його в іншому місці?
До цього моменту функція, яку ми створили, завжди виводила результат у [консоль](https://developer.mozilla.org/docs/Web/API/console). Іноді це може бути саме те, що нам потрібно, особливо коли ми створюємо функції, які викликають інші сервіси. Але що, якщо я хочу створити допоміжну функцію для виконання обчислення та отримати значення назад, щоб використовувати його в іншому місці?
Ми можемо зробити це за допомогою **значення, яке повертається**. Значення, яке повертається, повертається функцією і може бути збережене у змінній так само, як ми могли б зберегти літеральне значення, наприклад рядок або число.
Ми можемо зробити це, використовуючи **значення, що повертається**. Значення, що повертається, повертається функцією і може бути збережене у змінній так само, як ми могли б зберегти літеральне значення, наприклад рядок або число.
Якщо функція повертає щось, то використовується ключове слово `return`. Ключове слово `return` очікує значення або посилання на те, що повертається, як показано нижче:
@ -124,7 +124,7 @@ displayGreeting('Christopher', 'Hi');
return myVariable;
```
Ми могли б створити функцію для створення повідомлення привітання та повернення значення назад до виклику.
Ми можемо створити функцію для створення повідомлення привітання та повернення значення назад до виклику.
```javascript
function createGreetingMessage(name) {
@ -141,7 +141,7 @@ const greetingMessage = createGreetingMessage('Christopher');
## Функції як параметри для функцій
У міру того, як ви будете розвиватися у своїй програмістській кар’єрі, ви зустрінете функції, які приймають функції як параметри. Цей цікавий прийом часто використовується, коли ми не знаємо, коли щось станеться або завершиться, але знаємо, що потрібно виконати операцію у відповідь.
У міру вашого прогресу в програмуванні ви зіткнетеся з функціями, які приймають функції як параметри. Цей цікавий прийом часто використовується, коли ми не знаємо, коли щось станеться або завершиться, але знаємо, що потрібно виконати операцію у відповідь.
Наприклад, розглянемо [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), який запускає таймер і виконує код після його завершення. Нам потрібно сказати йому, який код ми хочемо виконати. Звучить як ідеальна робота для функції!
@ -157,9 +157,9 @@ setTimeout(displayDone, 3000);
### Анонімні функції
Давайте ще раз подивимося на те, що ми створили. Ми створюємо функцію з назвою, яка буде використана один раз. У міру того, як наш додаток стає складнішим, ми можемо побачити, що створюємо багато функцій, які будуть викликані лише один раз. Це не ідеально. Як виявляється, нам не завжди потрібно надавати назву!
Давайте ще раз поглянемо на те, що ми створили. Ми створюємо функцію з назвою, яка буде використана лише один раз. У міру ускладнення нашого додатка ми можемо побачити, що створюємо багато функцій, які будуть викликані лише один раз. Це не ідеально. Як виявляється, нам не завжди потрібно надавати назву!
Коли ми передаємо функцію як параметр, ми можемо обійти створення її заздалегідь і натомість створити її як частину параметра. Ми використовуємо те ж ключове слово `function`, але створюємо її як параметр.
Коли ми передаємо функцію як параметр, ми можемо обійтися без її попереднього створення і натомість створити її як частину параметра. Ми використовуємо те ж ключове слово `function`, але створюємо її як параметр.
Давайте перепишемо код вище, щоб використовувати анонімну функцію:
@ -173,7 +173,7 @@ setTimeout(function() {
### Функції зі стрілками
Одним із скорочень, поширених у багатьох мовах програмування (включаючи JavaScript), є можливість використовувати так звану **стрілкову** або **жирну стрілкову** функцію. Вона використовує спеціальний індикатор `=>`, який виглядає як стрілка — звідси й назва! Використовуючи `=>`, ми можемо пропустити ключове слово `function`.
Одним із скорочень, поширених у багатьох мовах програмування (включаючи JavaScript), є можливість використовувати так звану **стрілкову** або **жирну стрілкову** функцію. Вона використовує спеціальний індикатор `=>`, який виглядає як стрілка — звідси і назва! Використовуючи `=>`, ми можемо пропустити ключове слово `function`.
Давайте перепишемо наш код ще раз, щоб використовувати функцію зі стрілкою:
@ -185,7 +185,7 @@ setTimeout(() => {
### Коли використовувати кожну стратегію
Тепер ви бачили три способи передати функцію як параметр і, можливо, задаєтеся питанням, коли використовувати кожен із них. Якщо ви знаєте, що будете використовувати функцію більше одного разу, створіть її звичайним способом. Якщо ви будете використовувати її лише в одному місці, зазвичай найкраще використовувати анонімну функцію. Чи використовувати функцію зі стрілкою або більш традиційний синтаксис `function` — залежить від вас, але ви помітите, що більшість сучасних розробників віддають перевагу `=>`.
Тепер ви бачили три способи передати функцію як параметр і, можливо, задаєтеся питанням, коли використовувати кожен. Якщо ви знаєте, що будете використовувати функцію більше одного разу, створіть її звичайним способом. Якщо ви будете використовувати її лише в одному місці, зазвичай краще використовувати анонімну функцію. Чи використовувати функцію зі стрілкою або більш традиційний синтаксис `function` — залежить від вас, але ви помітите, що більшість сучасних розробників віддають перевагу `=>`.
---
@ -194,11 +194,11 @@ setTimeout(() => {
Чи можете ви сформулювати в одному реченні різницю між функціями та методами? Спробуйте!
## Тест після лекції
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/10)
[Тест після лекції](https://ff-quizzes.netlify.app)
## Огляд і самостійне навчання
Варто [прочитати трохи більше про функції зі стрілками](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), оскільки вони все частіше використовуються в кодових базах. Попрактикуйтеся у написанні функції, а потім перепишіть її за допомогою цього синтаксису.
Варто [прочитати трохи більше про функції зі стрілками](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), оскільки вони все частіше використовуються в коді. Попрактикуйтеся у написанні функції, а потім перепишіть її з використанням цього синтаксису.
## Завдання

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "888609c48329c280ca2477d2df40f2e5",
"translation_date": "2025-08-27T22:29:26+00:00",
"original_hash": "f7009631b73556168ca435120a231c98",
"translation_date": "2025-08-28T18:16:33+00:00",
"source_file": "2-js-basics/3-making-decisions/README.md",
"language_code": "uk"
}
@ -11,13 +11,13 @@ CO_OP_TRANSLATOR_METADATA:
![Основи JavaScript - Прийняття рішень](../../../../translated_images/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.uk.png)
> Скетчноут від [Tomomi Imura](https://twitter.com/girlie_mac)
> Скетчнот від [Tomomi Imura](https://twitter.com/girlie_mac)
## Тест перед лекцією
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/11)
Прийняття рішень і контроль порядку виконання вашого коду робить його багаторазовим і надійним. У цьому розділі розглядається синтаксис для управління потоком даних у JavaScript і його важливість при використанні з булевими типами даних.
Прийняття рішень і контроль порядку виконання вашого коду робить його багаторазовим і надійним. У цьому розділі розглядається синтаксис для управління потоком даних у JavaScript і його значення при використанні з булевими типами даних.
[![Прийняття рішень](https://img.youtube.com/vi/SxTp8j-fMMY/0.jpg)](https://youtube.com/watch?v=SxTp8j-fMMY "Прийняття рішень")
@ -27,9 +27,9 @@ CO_OP_TRANSLATOR_METADATA:
## Короткий огляд булевих значень
Булеві значення можуть мати лише два значення: `true` або `false`. Булеві значення допомагають приймати рішення, які рядки коду повинні виконуватися за певних умов.
Булеві значення можуть мати лише два значення: `true` або `false`. Булеві значення допомагають приймати рішення про те, які рядки коду повинні виконуватися за певних умов.
Встановіть булеве значення як true або false ось так:
Встановіть булеве значення як true або false таким чином:
`let myTrueBool = true`
`let myFalseBool = false`
@ -46,8 +46,8 @@ CO_OP_TRANSLATOR_METADATA:
| `<=` | **Менше або дорівнює**: Порівнює два значення і повертає булеве значення `true`, якщо значення зліва менше або дорівнює значенню справа | `5 <= 6 // true` |
| `>` | **Більше ніж**: Порівнює два значення і повертає булеве значення `true`, якщо значення зліва більше, ніж справа | `5 > 6 // false` |
| `>=` | **Більше або дорівнює**: Порівнює два значення і повертає булеве значення `true`, якщо значення зліва більше або дорівнює значенню справа | `5 >= 6 // false` |
| `===` | **Строга рівність**: Порівнює два значення і повертає булеве значення `true`, якщо значення справа і зліва рівні І мають однаковий тип даних | `5 === 6 // false` |
| `!==` | **Нерівність**: Порівнює два значення і повертає протилежне булеве значення тому, яке повернув би оператор строгої рівності | `5 !== 6 // true` |
| `===` | **Строга рівність**: Порівнює два значення і повертає булеве значення `true`, якщо значення справа і зліва рівні і мають однаковий тип даних | `5 === 6 // false` |
| `!==` | **Нерівність**: Порівнює два значення і повертає протилежне булеве значення тому, що повернув би оператор строгої рівності | `5 !== 6 // true` |
✅ Перевірте свої знання, написавши кілька порівнянь у консолі вашого браузера. Чи здивували вас якісь отримані дані?
@ -90,7 +90,7 @@ if (currentMoney >= laptopPrice) {
}
```
✅ Перевірте своє розуміння цього коду та наступного, запустивши його в консолі браузера. Змініть значення змінних currentMoney і laptopPrice, щоб змінити результат `console.log()`.
✅ Перевірте своє розуміння цього коду та наступного коду, запустивши його в консолі браузера. Змініть значення змінних currentMoney і laptopPrice, щоб змінити результат `console.log()`.
## Оператор switch
@ -127,11 +127,11 @@ switch (a) {
console.log(`The value is ${a}`);
```
✅ Перевірте своє розуміння цього коду та наступного, запустивши його в консолі браузера. Змініть значення змінної a, щоб змінити результат `console.log()`.
✅ Перевірте своє розуміння цього коду та наступного коду, запустивши його в консолі браузера. Змініть значення змінної a, щоб змінити результат `console.log()`.
## Логічні оператори та булеві значення
Прийняття рішень може вимагати більше одного порівняння, і їх можна об’єднати за допомогою логічних операторів для отримання булевого значення.
Рішення можуть вимагати більше одного порівняння, і їх можна об’єднати за допомогою логічних операторів для отримання булевого значення.
| Символ | Опис | Приклад |
| ------ | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
@ -159,7 +159,7 @@ if (currentMoney >= laptopPrice || currentMoney >= laptopDiscountPrice) {
### Оператор заперечення
Ви вже бачили, як можна використовувати оператор `if...else` для створення умовної логіки. Все, що потрапляє в `if`, має оцінюватися як true/false. Використовуючи оператор `!`, ви можете аперечити_ вираз. Це виглядатиме так:
Ви вже бачили, як можна використовувати оператор `if...else` для створення умовної логіки. Усе, що потрапляє в `if`, має оцінюватися як true/false. Використовуючи оператор `!`, ви можете аперечити_ вираз. Це виглядатиме так:
```javascript
if (!condition) {
@ -187,7 +187,7 @@ let biggestNumber = firstNumber > secondNumber ? firstNumber : secondNumber;
✅ Приділіть хвилину, щоб кілька разів прочитати цей код. Чи розумієте ви, як працюють ці оператори?
Вищезазначене стверджує, що:
У наведеному вище коді зазначено:
- якщо `firstNumber` більше, ніж `secondNumber`
- тоді присвоїти `firstNumber` змінній `biggestNumber`
@ -208,7 +208,7 @@ if (firstNumber > secondNumber) {
## 🚀 Виклик
Створіть програму, яка спочатку написана з логічними операторами, а потім перепишіть її, використовуючи тернарний вираз. Який синтаксис вам більше подобається?
Створіть програму, яка спочатку написана з використанням логічних операторів, а потім перепишіть її, використовуючи тернарний вираз. Який синтаксис вам більше подобається?
---
@ -229,4 +229,4 @@ if (firstNumber > secondNumber) {
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ було перекладено за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматизовані переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "3f7f87871312cf6cc12662da7d973182",
"translation_date": "2025-08-27T22:32:31+00:00",
"original_hash": "9029f96b0e034839c1799f4595e4bb66",
"translation_date": "2025-08-28T18:17:54+00:00",
"source_file": "2-js-basics/4-arrays-loops/README.md",
"language_code": "uk"
}
@ -15,7 +15,7 @@ CO_OP_TRANSLATOR_METADATA:
## Тест перед лекцією
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/13)
Цей урок охоплює основи JavaScript мови, яка забезпечує інтерактивність у вебі. У цьому уроці ви дізнаєтеся про масиви та цикли, які використовуються для обробки даних.
Цей урок охоплює основи JavaScript, мови, яка забезпечує інтерактивність у вебі. У цьому уроці ви дізнаєтеся про масиви та цикли, які використовуються для обробки даних.
[![Масиви](https://img.youtube.com/vi/1U4qTyq02Xw/0.jpg)](https://youtube.com/watch?v=1U4qTyq02Xw "Масиви")
@ -29,7 +29,7 @@ CO_OP_TRANSLATOR_METADATA:
Робота з даними — це поширене завдання для будь-якої мови програмування, і це завдання стає набагато простішим, коли дані організовані у структурованому форматі, наприклад, у масивах. У масивах дані зберігаються у структурі, схожій на список. Однією з головних переваг масивів є те, що ви можете зберігати різні типи даних в одному масиві.
✅ Масиви оточують нас всюди! Чи можете ви придумати приклад масиву в реальному житті, наприклад, масив сонячних панелей?
✅ Масиви оточують нас всюди! Чи можете ви придумати реальний приклад масиву, наприклад, масив сонячних панелей?
Синтаксис масиву — це пара квадратних дужок.
@ -43,7 +43,7 @@ let myArray = [];
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
```
Значення масиву отримують унікальне значення, яке називається **індексом** ціле число, яке присвоюється залежно від його відстані від початку масиву. У наведеному вище прикладі рядкове значення "Chocolate" має індекс 0, а індекс "Rocky Road" дорівнює 4. Використовуйте індекс із квадратними дужками, щоб отримати, змінити або вставити значення масиву.
Значення масиву отримують унікальне значення, яке називається **індексом**, ціле число, яке присвоюється залежно від його відстані від початку масиву. У наведеному вище прикладі рядкове значення "Chocolate" має індекс 0, а індекс "Rocky Road" дорівнює 4. Використовуйте індекс із квадратними дужками, щоб отримати, змінити або вставити значення масиву.
Вас дивує, що індекси масивів починаються з нуля? У деяких мовах програмування індекси починаються з 1. Це цікава історія, яку ви можете [прочитати на Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering).
@ -58,7 +58,7 @@ iceCreamFlavors[2]; //"Vanilla"
iceCreamFlavors[4] = "Butter Pecan"; //Changed "Rocky Road" to "Butter Pecan"
```
Або вставити нове значення за певним індексом ось так:
Або вставити нове значення за певним індексом, ось так:
```javascript
iceCreamFlavors[5] = "Cookie Dough"; //Added "Cookie Dough"
@ -77,7 +77,7 @@ iceCreamFlavors.length; //5
## Цикли
Цикли дозволяють виконувати повторювані або **ітеративні** завдання, що може значно заощадити час і код. Кожна ітерація може відрізнятися змінними, значеннями та умовами. У JavaScript є різні типи циклів, які мають невеликі відмінності, але по суті виконують одне й те саме: проходять через дані.
Цикли дозволяють виконувати повторювані або **ітеративні** завдання, що може значно заощадити час і код. Кожна ітерація може відрізнятися змінними, значеннями та умовами. У JavaScript є різні типи циклів, які мають невеликі відмінності, але по суті виконують те саме: проходять через дані.
### Цикл For
@ -97,7 +97,7 @@ for (let i = 0; i < 10; i++) {
### Цикл While
На відміну від синтаксису циклу `for`, цикл `while` вимагає лише умови, яка зупинить цикл, коли умова стане `false`. Умови в циклах зазвичай залежать від інших значень, таких як лічильники, і повинні управлятися під час виконання циклу. Початкові значення для лічильників повинні бути створені поза циклом, а будь-які вирази для виконання умови, включаючи зміну лічильника, повинні підтримуватися всередині циклу.
На відміну від синтаксису циклу `for`, цикл `while` вимагає лише умови, яка зупинить цикл, коли умова стане `false`. Умови в циклах зазвичай залежать від інших значень, таких як лічильники, і повинні керуватися під час виконання циклу. Початкові значення для лічильників повинні бути створені поза циклом, а будь-які вирази для виконання умови, включаючи зміну лічильника, повинні підтримуватися всередині циклу.
```javascript
//Counting up to 10
@ -122,7 +122,7 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
} //Ends when all flavors are printed
```
✅ Експериментуйте з проходженням через масив власного створення у консолі вашого браузера.
✅ Експериментуйте з проходженням через масив власного створення у консолі вашого браузера.
---
@ -144,4 +144,4 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматизовані переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "46a0639e719b9cf1dfd062aa24cad639",
"translation_date": "2025-08-27T22:34:53+00:00",
"original_hash": "89f7f9f800ce7c9f149e98baaae8491a",
"translation_date": "2025-08-28T18:18:14+00:00",
"source_file": "3-terrarium/1-intro-to-html/README.md",
"language_code": "uk"
}
@ -23,13 +23,13 @@ CO_OP_TRANSLATOR_METADATA:
### Вступ
HTML, або HyperText Markup Language, — це "скелет" вебу. Якщо CSS "одягає" ваш HTML, а JavaScript оживляє його, то HTML — це тіло вашого веб-додатку. Синтаксис HTML навіть відображає цю ідею, оскільки включає теги "head", "body" і "footer".
HTML, або HyperText Markup Language, є "скелетом" вебу. Якщо CSS "одягає" ваш HTML, а JavaScript оживляє його, то HTML — це тіло вашого веб-додатку. Синтаксис HTML навіть відображає цю ідею, оскільки включає теги "head", "body" і "footer".
У цьому уроці ми використаємо HTML для створення "скелету" інтерфейсу нашого віртуального тераріуму. Він матиме заголовок і три колонки: праву та ліву, де будуть розташовані перетягувані рослини, і центральну область, яка буде виглядати як скляний тераріум. До кінця цього уроку ви зможете побачити рослини в колонках, але інтерфейс виглядатиме трохи дивно; не хвилюйтеся, у наступному розділі ви додасте стилі CSS, щоб зробити інтерфейс більш привабливим.
У цьому уроці ми використаємо HTML для створення "скелета" інтерфейсу нашого віртуального тераріуму. Він матиме заголовок і три колонки: праву та ліву, де будуть розташовані перетягувані рослини, і центральну область, яка буде виглядати як скляний тераріум. До кінця цього уроку ви зможете побачити рослини в колонках, але інтерфейс виглядатиме трохи дивно; не хвилюйтеся, у наступному розділі ви додасте стилі CSS, щоб зробити інтерфейс більш привабливим.
### Завдання
На вашому комп'ютері створіть папку під назвою 'terrarium', а всередині неї файл 'index.html'. Ви можете зробити це у Visual Studio Code після створення папки terrarium, відкривши нове вікно VS Code, натиснувши 'open folder' і перейшовши до вашої нової папки. Натисніть маленьку кнопку 'file' у панелі Explorer і створіть новий файл:
На вашому комп'ютері створіть папку під назвою 'terrarium', а всередині неї файл 'index.html'. Ви можете зробити це у Visual Studio Code після створення папки 'terrarium', відкривши нове вікно VS Code, натиснувши 'open folder' і перейшовши до вашої нової папки. Натисніть маленьку кнопку 'file' у панелі Explorer і створіть новий файл:
![explorer у VS Code](../../../../translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.uk.png)
@ -41,17 +41,17 @@ HTML, або HyperText Markup Language, — це "скелет" вебу. Якщ
* `touch index.html`
* `code index.html` або `nano index.html`
> Файли index.html вказують браузеру, що це файл за замовчуванням у папці; URL-адреси, такі як `https://anysite.com/test`, можуть бути побудовані за допомогою структури папок, включаючи папку під назвою `test` з файлом `index.html` всередині; `index.html` не обов'язково має відображатися в URL.
> Файли index.html вказують браузеру, що це файл за замовчуванням у папці; URL-адреси, такі як `https://anysite.com/test`, можуть бути побудовані за допомогою структури папок, яка включає папку під назвою `test` з файлом `index.html` всередині; `index.html` не обов'язково має відображатися в URL.
---
## DocType і теги html
Перший рядок HTML-файлу — це його doctype. Це трохи дивно, що цей рядок має бути на самому верху файлу, але він повідомляє старим браузерам, що сторінка повинна відображатися у стандартному режимі, відповідно до поточної специфікації HTML.
Перший рядок HTML-файлу — це його doctype. Це трохи дивно, що цей рядок має бути на самому початку файлу, але він повідомляє старим браузерам, що сторінка повинна відображатися у стандартному режимі, відповідно до поточної специфікації HTML.
> Порада: у VS Code ви можете навести курсор на тег і отримати інформацію про його використання з довідників MDN.
Другий рядок має бути відкриваючим тегом `<html>`, а заразом і закриваючим тегом `</html>`. Ці теги є кореневими елементами вашого інтерфейсу.
Другий рядок має бути відкриваючим тегом `<html>`, а заразом і його закриваючим тегом `</html>`. Ці теги є кореневими елементами вашого інтерфейсу.
### Завдання
@ -68,13 +68,13 @@ HTML, або HyperText Markup Language, — це "скелет" вебу. Якщ
## 'head' документа
Область 'head' HTML-документа включає важливу інформацію про вашу веб-сторінку, також відому як [метадані](https://developer.mozilla.org/docs/Web/HTML/Element/meta). У нашому випадку ми повідомляємо веб-серверу, на який буде надіслана ця сторінка для відображення, про такі чотири речі:
Область 'head' HTML-документа включає важливу інформацію про вашу веб-сторінку, також відому як [метадані](https://developer.mozilla.org/docs/Web/HTML/Element/meta). У нашому випадку ми повідомляємо веб-серверу, на якому ця сторінка буде відображатися, про такі чотири речі:
- заголовок сторінки
- метадані сторінки, включаючи:
- 'character set', який повідомляє про те, яке кодування символів використовується на сторінці
- інформацію про браузер, включаючи `x-ua-compatible`, що вказує на підтримку браузера IE=edge
- інформацію про те, як має поводитися viewport при завантаженні. Встановлення початкового масштабу viewport на 1 контролює рівень масштабування при першому завантаженні сторінки.
- інформацію про те, як має поводитися viewport при завантаженні. Встановлення viewport з початковим масштабом 1 контролює рівень масштабування при першому завантаженні сторінки.
### Завдання
@ -118,7 +118,7 @@ HTML, або HyperText Markup Language, — це "скелет" вебу. Якщ
### Зображення
Один HTML-тег, який не потребує закриваючого тега, — це `<img>`, оскільки він має елемент `src`, який містить всю інформацію, необхідну сторінці для відображення елемента.
Один HTML-тег, який не потребує закриваючого тега, — це `<img>`, оскільки він має елемент `src`, який містить всю інформацію, необхідну для відображення елемента на сторінці.
Створіть папку у вашому додатку під назвою `images` і додайте до неї всі зображення з [папки вихідного коду](../../../../3-terrarium/solution/images); (там є 14 зображень рослин).
@ -177,19 +177,19 @@ HTML, або HyperText Markup Language, — це "скелет" вебу. Якщ
</div>
```
> Примітка: Спани проти Дівів. Діви вважаються елементами 'block', а спани — 'inline'. Що станеться, якщо ви перетворите ці діви на спани?
> Примітка: Спани проти Дівів. Діви вважаються елементами 'block', а Спани — 'inline'. Що станеться, якщо ви перетворите ці діви на спани?
З цим кодом рослини тепер з'являються на екрані. Виглядає це досить погано, оскільки вони ще не стилізовані за допомогою CSS, і ми зробимо це у наступному уроці.
Кожне зображення має альтернативний текст, який з'являється навіть якщо ви не можете побачити або відобразити зображення. Це важливий атрибут для забезпечення доступності. Дізнайтеся більше про доступність у майбутніх уроках; наразі пам'ятайте, що атрибут alt надає альтернативну інформацію для зображення, якщо користувач з якоїсь причини не може його переглянути (через повільне з'єднання, помилку в атрибуті src або якщо користувач використовує екранний зчитувач).
Кожне зображення має альтернативний текст, який з'являється, навіть якщо ви не можете побачити або відобразити зображення. Це важливий атрибут для забезпечення доступності. Дізнайтеся більше про доступність у майбутніх уроках; поки що пам'ятайте, що атрибут alt надає альтернативну інформацію для зображення, якщо користувач з якоїсь причини не може його переглянути (через повільне з'єднання, помилку в атрибуті src або якщо користувач використовує екранний рідер).
✅ Ви помітили, що кожне зображення має однаковий alt-тег? Чи це хороша практика? Чому або чому ні? Чи можете ви покращити цей код?
✅ Ви помітили, що кожне зображення має однаковий alt-тег? Чи є це хорошою практикою? Чому або чому ні? Чи можете ви покращити цей код?
---
## Семантична розмітка
Загалом, краще використовувати осмислену 'семантику' при написанні HTML. Що це означає? Це означає, що ви використовуєте HTML-теги для представлення типу даних або взаємодії, для яких вони були створені. Наприклад, основний заголовок тексту на сторінці має використовувати тег `<h1>`.
Загалом, краще використовувати осмислену 'семантику' при написанні HTML. Що це означає? Це означає, що ви використовуєте HTML-теги для представлення типу даних або взаємодії, для яких вони були створені. Наприклад, основний текст заголовка на сторінці має використовувати тег `<h1>`.
Додайте наступний рядок прямо під вашим відкриваючим тегом `<body>`:
@ -197,9 +197,9 @@ HTML, або HyperText Markup Language, — це "скелет" вебу. Якщ
<h1>My Terrarium</h1>
```
Використання семантичної розмітки, такої як заголовки `<h1>` і ненумеровані списки `<ul>`, допомагає екранним зчитувачам орієнтуватися на сторінці. Загалом, кнопки слід писати як `<button>`, а списки — як `<li>`. Хоча ожливо_ використовувати спеціально стилізовані елементи `<span>` з обробниками кліків для імітації кнопок, краще для користувачів з обмеженими можливостями використовувати технології для визначення місця розташування кнопки на сторінці та взаємодії з нею, якщо елемент виглядає як кнопка. З цієї причини намагайтеся використовувати семантичну розмітку якомога більше.
Використання семантичної розмітки, такої як заголовки `<h1>` і невпорядковані списки `<ul>`, допомагає екранним рідерам орієнтуватися на сторінці. Загалом, кнопки слід писати як `<button>`, а списки — як `<li>`. Хоча ожливо_ використовувати спеціально стилізовані елементи `<span>` з обробниками кліків для імітації кнопок, краще для користувачів з обмеженими можливостями використовувати технології для визначення місця розташування кнопки на сторінці та взаємодії з нею, якщо елемент виглядає як кнопка. З цієї причини намагайтеся використовувати семантичну розмітку якомога більше.
✅ Ознайомтеся з екранним зчитувачем і [як він взаємодіє з веб-сторінкою](https://www.youtube.com/watch?v=OUDV1gqs9GA). Чи можете ви зрозуміти, чому використання несемантичної розмітки може засмутити користувача?
✅ Ознайомтеся з екранним рідером і [як він взаємодіє з веб-сторінкою](https://www.youtube.com/watch?v=OUDV1gqs9GA). Чи можете ви зрозуміти, чому використання несемантичної розмітки може засмутити користувача?
## Тераріум
@ -227,7 +227,7 @@ HTML, або HyperText Markup Language, — це "скелет" вебу. Якщ
## 🚀Виклик
Існують деякі цікаві "старі" теги в HTML, які все ще весело використовувати, хоча вам не слід використовувати застарілі теги, такі як [ці теги](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) у вашій розмітці. Все ж, чи можете ви використати старий тег `<marquee>`, щоб зробити заголовок h1 прокручуваним горизонтально? (якщо ви це зробите, не забудьте видалити його потім)
Існують деякі цікаві "старі" теги в HTML, які все ще весело використовувати, хоча вам не слід використовувати застарілі теги, такі як [ці теги](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) у вашій розмітці. Все ж, чи можете ви використати старий тег `<marquee>`, щоб зробити заголовок h1, який прокручується горизонтально? (якщо ви це зробите, не забудьте видалити його потім)
## Тест після лекції
@ -241,9 +241,9 @@ HTML — це "перевірена часом" система будівель
## Завдання
[Практикуйте HTML: створіть макет блогу](assignment.md)
[Практикуйте HTML: Створіть макет блогу](assignment.md)
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

@ -1,41 +1,41 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e375c2aeb94e2407f2667633d39580bd",
"translation_date": "2025-08-27T22:36:40+00:00",
"original_hash": "acb5ae00cde004304296bb97da8ff4c3",
"translation_date": "2025-08-28T18:18:50+00:00",
"source_file": "3-terrarium/2-intro-to-css/README.md",
"language_code": "uk"
}
-->
# Проєкт "Тераріум", Частина 2: Вступ до CSS
![Вступ до CSS](../../../../translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.uk.png)
> Скетчноут від [Tomomi Imura](https://twitter.com/girlie_mac)
![Вступ до CSS](../../../../translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.uk.png)
> Скетчнот від [Tomomi Imura](https://twitter.com/girlie_mac)
## Передлекційна вікторина
## Тест перед лекцією
[Передлекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/17)
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/17)
### Вступ
CSS, або каскадні таблиці стилів, вирішують важливу проблему веброзробки: як зробити ваш вебсайт привабливим. Стилізація ваших додатків робить їх більш зручними та естетичними; також за допомогою CSS можна створювати адаптивний вебдизайн (Responsive Web Design, RWD), що дозволяє вашим додаткам виглядати добре незалежно від розміру екрана. CSS — це не лише про зовнішній вигляд; його специфікація включає анімації та трансформації, які дозволяють створювати складні взаємодії у ваших додатках. Робоча група CSS допомагає підтримувати актуальність специфікацій CSS; ви можете стежити за їхньою роботою на [сайті World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
CSS, або каскадні таблиці стилів, вирішують важливу проблему веб-розробки: як зробити ваш вебсайт привабливим. Стилізація ваших додатків робить їх більш зручними та естетично привабливими; також за допомогою CSS можна створити адаптивний веб-дизайн (Responsive Web Design, RWD), що дозволяє вашим додаткам виглядати добре незалежно від розміру екрана. CSS — це не лише про зовнішній вигляд; його специфікація включає анімації та трансформації, які можуть забезпечити складні взаємодії для ваших додатків. Робоча група CSS допомагає підтримувати актуальні специфікації CSS; ви можете стежити за їхньою роботою на [сайті World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
> Зверніть увагу, CSS — це мова, яка постійно розвивається, як і все у вебі, і не всі браузери підтримують нові частини специфікації. Завжди перевіряйте свої реалізації, звертаючись до [CanIUse.com](https://caniuse.com).
У цьому уроці ми додамо стилі до нашого онлайн-тераріуму та дізнаємося більше про кілька концепцій CSS: каскадність, наслідування, використання селекторів, позиціонування та створення макетів за допомогою CSS. У процесі ми створимо макет тераріуму та сам тераріум.
У цьому уроці ми додамо стилі до нашого онлайн-тераріуму та дізнаємося більше про кілька концепцій CSS: каскадність, успадкування, використання селекторів, позиціонування та створення макетів за допомогою CSS. У процесі ми створимо макет тераріуму та сам тераріум.
### Передумови
### Попередні знання
Ви повинні мати HTML для вашого тераріуму, готовий до стилізації.
Ви повинні мати готовий HTML для вашого тераріуму, щоб його можна було стилізувати.
> Перегляньте відео
>
> [![Відео про основи Git і GitHub](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I)
> [![Відео про основи Git та GitHub](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I)
### Завдання
У папці вашого тераріуму створіть новий файл під назвою `style.css`. Підключіть цей файл у секції `<head>`:
У папці вашого тераріуму створіть новий файл під назвою `style.css`. Імпортуйте цей файл у секцію `<head>`:
```html
<link rel="stylesheet" href="./style.css" />
@ -45,7 +45,7 @@ CSS, або каскадні таблиці стилів, вирішують в
## Каскадність
Каскадні таблиці стилів включають ідею, що стилі "каскадують", тобто застосування стилю визначається його пріоритетом. Стилі, задані автором вебсайту, мають пріоритет над стилями, заданими браузером. Стилі, задані "вбудовано" (inline), мають пріоритет над стилями у зовнішньому файлі стилів.
Каскадні таблиці стилів включають ідею, що стилі "каскадують", тобто застосування стилю керується його пріоритетом. Стилі, встановлені автором вебсайту, мають пріоритет над стилями, встановленими браузером. Стилі, встановлені "вбудовано", мають пріоритет над стилями, встановленими у зовнішньому файлі стилів.
### Завдання
@ -63,17 +63,17 @@ h1 {
}
```
✅ Який колір відображається у вашому вебдодатку? Чому? Чи можете ви знайти спосіб перевизначити стилі? Коли ви б хотіли це зробити, а коли ні?
✅ Який колір відображається у вашому веб-додатку? Чому? Чи можете ви знайти спосіб перевизначити стилі? Коли ви хотіли б це зробити, або чому ні?
---
## Наслідування
## Успадкування
Стилі наслідуються від предка до нащадка, тобто вкладені елементи наслідують стилі своїх батьків.
Стилі успадковуються від стилю предка до нащадка, так що вкладені елементи успадковують стилі своїх батьків.
### Завдання
Задайте шрифт для тіла (`body`) і перевірте, чи наслідує вкладений елемент цей шрифт:
Встановіть шрифт для тіла документа і перевірте шрифт вкладеного елемента:
```CSS
body {
@ -81,11 +81,11 @@ body {
}
```
Відкрийте консоль вашого браузера на вкладці 'Elements' і спостерігайте за шрифтом H1. Він наслідує свій шрифт від тіла, як зазначено у браузері:
Відкрийте консоль вашого браузера на вкладці 'Elements' і спостерігайте за шрифтом H1. Він успадковує свій шрифт від тіла документа, як зазначено у браузері:
![успадкований шрифт](../../../../translated_images/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.uk.png)
✅ Чи можете ви зробити так, щоб вкладений стиль наслідував іншу властивість?
✅ Чи можете ви зробити так, щоб вкладений стиль успадковував іншу властивість?
---
@ -93,7 +93,7 @@ body {
### Теги
На даний момент ваш файл `style.css` має лише кілька стилізованих тегів, і додаток виглядає досить дивно:
На даний момент ваш файл `style.css` має стилізовані лише кілька тегів, і додаток виглядає досить дивно:
```CSS
body {
@ -110,7 +110,7 @@ h1 {
### Ідентифікатори (Ids)
Додайте трохи стилів для розташування лівого та правого контейнерів. Оскільки є лише один лівий контейнер і один правий контейнер, їм у розмітці присвоєно ідентифікатори. Щоб стилізувати їх, використовуйте `#`:
Додайте стиль для розташування лівого та правого контейнерів. Оскільки є лише один лівий контейнер і лише один правий контейнер, їм присвоєно ідентифікатори у розмітці. Для їх стилізації використовуйте `#`:
```CSS
#left-container {
@ -134,9 +134,9 @@ h1 {
}
```
Тут ви розмістили ці контейнери з абсолютним позиціонуванням зліва та справа від екрана, а також використали відсотки для їхньої ширини, щоб вони могли масштабуватися для невеликих мобільних екранів.
Тут ви розмістили ці контейнери з абсолютним позиціонуванням на крайній лівій та правій частині екрана, і використали відсотки для їх ширини, щоб вони могли масштабуватися для маленьких мобільних екранів.
✅ Цей код досить повторюваний, тобто не відповідає принципу "DRY" (Don't Repeat Yourself). Чи можете ви знайти кращий спосіб стилізувати ці ідентифікатори, можливо, використовуючи ідентифікатор та клас? Вам потрібно буде змінити розмітку та рефакторити CSS:
✅ Цей код досить повторюваний, тобто не відповідає принципу "DRY" (Don't Repeat Yourself); чи можете ви знайти кращий спосіб стилізувати ці ідентифікатори, можливо, за допомогою ідентифікатора та класу? Вам потрібно буде змінити розмітку та рефакторити CSS:
```html
<div id="left-container" class="container"></div>
@ -146,7 +146,7 @@ h1 {
У наведеному вище прикладі ви стилізували два унікальні елементи на екрані. Якщо ви хочете, щоб стилі застосовувалися до багатьох елементів на екрані, ви можете використовувати класи CSS. Зробіть це для розташування рослин у лівому та правому контейнерах.
Зверніть увагу, що кожна рослина в HTML-розмітці має комбінацію ідентифікаторів та класів. Ідентифікатори тут використовуються JavaScript, який ви додасте пізніше, для маніпуляції розташуванням рослин у тераріумі. Класи ж надають усім рослинам певний стиль.
Зверніть увагу, що кожна рослина у HTML-розмітці має комбінацію ідентифікаторів та класів. Ідентифікатори тут використовуються JavaScript, який ви додасте пізніше, для маніпуляції розташуванням рослин у тераріумі. Класи ж надають всім рослинам певний стиль.
```html
<div class="plant-holder">
@ -171,37 +171,37 @@ h1 {
}
```
Примітно в цьому фрагменті змішування відносного та абсолютного позиціонування, яке ми розглянемо в наступному розділі. Зверніть увагу на те, як висоти обробляються у відсотках:
Примітним у цьому фрагменті є змішування відносного та абсолютного позиціонування, яке ми розглянемо у наступному розділі. Зверніть увагу на те, як висоти обробляються за допомогою відсотків:
Ви встановили висоту тримача рослин на 13%, що є хорошим значенням, щоб усі рослини відображалися у кожному вертикальному контейнері без необхідності прокручування.
Ви встановили висоту тримача рослин на 13%, гарне значення, щоб усі рослини відображалися у кожному вертикальному контейнері без необхідності прокручування.
Ви змістили тримач рослин вліво, щоб рослини були більш центровані в межах їхнього контейнера. Зображення мають великий обсяг прозорого фону, щоб зробити їх більш зручними для перетягування, тому їх потрібно змістити вліво, щоб краще вписатися на екрані.
Ви змістили тримач рослин вліво, щоб рослини були більш центровані у своєму контейнері. Зображення мають великий обсяг прозорого фону, щоб зробити їх більш зручними для перетягування, тому їх потрібно змістити вліво, щоб краще вписатися на екрані.
Потім самій рослині надано максимальну ширину 150%. Це дозволяє їй масштабуватися вниз разом із масштабуванням браузера. Спробуйте змінити розмір вашого браузера; рослини залишаються у своїх контейнерах, але масштабуються вниз, щоб вписатися.
Потім самій рослині встановлено максимальну ширину 150%. Це дозволяє їй масштабуватися вниз, коли браузер масштабується вниз. Спробуйте змінити розмір вашого браузера; рослини залишаються у своїх контейнерах, але масштабуються вниз, щоб вписатися.
Також примітно використання z-index, який контролює відносну висоту елемента (щоб рослини розташовувалися поверх контейнера і виглядали так, ніби вони знаходяться всередині тераріуму).
Також примітним є використання z-index, який контролює відносну висоту елемента (щоб рослини розташовувалися поверх контейнера і виглядали так, ніби вони знаходяться всередині тераріуму).
✅ Чому вам потрібні як тримач рослин, так і селектор рослин у CSS?
## Позиціонування в CSS
## Позиціонування CSS
Змішування властивостей позиціонування (існують статичне, відносне, фіксоване, абсолютне та липке позиціонування) може бути трохи складним, але якщо зроблено правильно, це дає вам хороший контроль над елементами на ваших сторінках.
Змішування властивостей позиціонування (є статичне, відносне, фіксоване, абсолютне та липке позиціонування) може бути трохи складним, але якщо зроблено правильно, це дає вам хороший контроль над елементами на ваших сторінках.
Абсолютно позиціоновані елементи розташовуються відносно найближчих позиціонованих предків, а якщо таких немає, то відносно тіла документа.
Відносно позиціоновані елементи розташовуються на основі вказівок CSS щодо їхнього зміщення від початкової позиції.
Відносно позиціоновані елементи розташовуються на основі вказівок CSS, щоб змістити їх від початкової позиції.
У нашому прикладі `plant-holder` є елементом із відносним позиціонуванням, який розташовується всередині контейнера з абсолютним позиціонуванням. Результат полягає в тому, що бічні контейнери закріплені зліва та справа, а `plant-holder` вкладений, регулюючи себе всередині бічних контейнерів, залишаючи місце для розташування рослин у вертикальному ряду.
У нашому прикладі `plant-holder` є елементом з відносним позиціонуванням, який розташовується всередині контейнера з абсолютним позиціонуванням. Результат такої поведінки полягає в тому, що бокові контейнери закріплені ліворуч і праворуч, а `plant-holder` вкладений, зміщуючи себе всередині бокових контейнерів, створюючи простір для розміщення рослин у вертикальному ряду.
> Сам `plant` також має абсолютне позиціонування, необхідне для того, щоб зробити його перетягуваним, як ви дізнаєтеся в наступному уроці.
> Сам `plant` також має абсолютне позиціонування, необхідне для того, щоб зробити його перетягуваним, як ви дізнаєтеся у наступному уроці.
✅ Експериментуйте зі зміною типів позиціонування бічних контейнерів і `plant-holder`. Що відбувається?
✅ Експериментуйте зі зміною типів позиціонування бокових контейнерів і `plant-holder`. Що відбувається?
## Макети в CSS
## Макети CSS
Тепер ви використаєте те, що дізналися, щоб створити сам тераріум, використовуючи лише CSS!
Спочатку стилізуйте дочірні елементи `.terrarium` як заокруглений прямокутник за допомогою CSS:
Спочатку стилізуйте дочірні елементи `.terrarium` як закруглений прямокутник за допомогою CSS:
```CSS
.jar-walls {
@ -250,29 +250,29 @@ h1 {
}
```
Зверніть увагу на використання відсотків тут. Якщо ви зменшите масштаб вашого браузера, ви побачите, як банка також масштабується. Також зверніть увагу на відсотки ширини та висоти для елементів банки і на те, як кожен елемент абсолютно позиціонується в центрі, закріплений у нижній частині вікна перегляду.
Зверніть увагу на використання відсотків тут. Якщо ви зменшите масштаб вашого браузера, ви побачите, як банка також масштабується. Також зверніть увагу на ширини та висоти у відсотках для елементів банки і на те, як кожен елемент абсолютно позиціонується у центрі, закріплений до нижньої частини вікна перегляду.
Ми також використовуємо `rem` для border-radius, що є відносною до шрифту одиницею виміру. Дізнайтеся більше про цей тип відносного вимірювання у [специфікації CSS](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
Ми також використовуємо `rem` для border-radius, довжини, що залежить від шрифту. Дізнайтеся більше про цей тип відносного вимірювання у [специфікації CSS](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
✅ Спробуйте змінити кольори банки та прозорість у порівнянні з кольорами ґрунту. Що відбувається? Чому?
✅ Спробуйте змінити кольори банки та прозорість порівняно з кольорами ґрунту. Що відбувається? Чому?
---
## 🚀 Виклик
## 🚀Виклик
Додайте "блискучу" відблиск у нижній лівій частині банки, щоб вона виглядала більш схожою на скло. Ви будете стилізувати `.jar-glossy-long` і `.jar-glossy-short`, щоб вони виглядали як відблиск. Ось як це виглядатиме:
Додайте "бульбашковий" блиск у нижній лівій частині банки, щоб вона виглядала більш схожою на скло. Ви будете стилізувати `.jar-glossy-long` та `.jar-glossy-short`, щоб вони виглядали як відблиск. Ось як це виглядатиме:
![готовий тераріум](../../../../translated_images/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.uk.png)
Щоб завершити післялекційну вікторину, пройдіть цей модуль Learn: [Стилізуйте ваш HTML-додаток за допомогою CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
Щоб завершити тест після лекції, пройдіть цей модуль Learn: [Стилізуйте ваш HTML-додаток за допомогою CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
## Післялекційна вікторина
## Тест після лекції
[Післялекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/18)
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/18)
## Огляд і самостійне навчання
## Огляд та самостійне навчання
CSS здається оманливо простим, але є багато викликів при спробі ідеально стилізувати додаток для всіх браузерів і всіх розмірів екранів. CSS-Grid і Flexbox — це інструменти, розроблені для того, щоб зробити роботу трохи більш структурованою та надійною. Дізнайтеся про ці інструменти, граючи в [Flexbox Froggy](https://flexboxfroggy.com/) і [Grid Garden](https://codepip.com/games/grid-garden/).
CSS здається оманливо простим, але є багато викликів при спробі ідеально стилізувати додаток для всіх браузерів і всіх розмірів екранів. CSS-Grid і Flexbox — це інструменти, які були розроблені, щоб зробити роботу трохи більш структурованою та надійною. Дізнайтеся про ці інструменти, граючи у [Flexbox Froggy](https://flexboxfroggy.com/) та [Grid Garden](https://codepip.com/games/grid-garden/).
## Завдання

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "30f8903a1f290e3d438dc2c70fe60259",
"translation_date": "2025-08-27T22:38:32+00:00",
"original_hash": "61c14b27044861e5e69db35dd52c4403",
"translation_date": "2025-08-28T18:19:22+00:00",
"source_file": "3-terrarium/3-intro-to-DOM-and-closures/README.md",
"language_code": "uk"
}
@ -12,17 +12,17 @@ CO_OP_TRANSLATOR_METADATA:
![DOM і замикання](../../../../translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.uk.png)
> Скетчнот від [Tomomi Imura](https://twitter.com/girlie_mac)
## Передлекційна вікторина
## Тест перед лекцією
[Передлекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/19)
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/19)
### Вступ
Маніпуляція DOM, або "Document Object Model", є ключовим аспектом веброзробки. Згідно з [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "Document Object Model (DOM) — це представлення даних об'єктів, які складають структуру та зміст документа в Інтернеті". Виклики, пов'язані з маніпуляцією DOM, часто спонукали розробників використовувати JavaScript-фреймворки замість чистого JavaScript для управління DOM, але ми впораємося самостійно!
Маніпуляція DOM, або "Document Object Model", є ключовим аспектом веброзробки. Згідно з [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "Document Object Model (DOM) — це представлення даних об'єктів, які складають структуру та зміст документа в Інтернеті". Виклики, пов'язані з маніпуляцією DOM, часто спонукали до використання JavaScript-фреймворків замість чистого JavaScript для управління DOM, але ми впораємося самостійно!
Крім того, цей урок познайомить вас із поняттям [замикання в JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), яке можна уявити як функцію, вкладену в іншу функцію, що дозволяє внутрішній функції отримувати доступ до області видимості зовнішньої функції.
> Замикання в JavaScript — це велика і складна тема. У цьому уроці ми торкнемося найосновнішої ідеї: у коді цього тераріуму ви знайдете замикання — внутрішню функцію та зовнішню функцію, побудовані таким чином, щоб внутрішня функція мала доступ до області видимості зовнішньої функції. Для більш детальної інформації про те, як це працює, відвідайте [розширену документацію](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
> Замикання в JavaScript — це велика і складна тема. У цьому уроці ми торкнемося найосновнішої ідеї, що в коді цього тераріуму ви знайдете замикання: внутрішню функцію та зовнішню функцію, побудовані таким чином, щоб внутрішня функція мала доступ до області видимості зовнішньої функції. Для більш детальної інформації про те, як це працює, відвідайте [розширену документацію](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
Ми використаємо замикання для маніпуляції DOM.
@ -46,8 +46,7 @@ CO_OP_TRANSLATOR_METADATA:
<script src="./script.js" defer></script>
```
> Примітка: використовуйте `defer` при імпорті зовнішнього JavaScript-файлу в HTML-файл, щоб дозволити виконання JavaScript лише після повного завантаження HTML-файлу. Ви також можете використовувати атрибут `async`, який дозволяє скрипту виконуватися під час парсингу HTML-файлу, але в нашому випадку важливо, щоб елементи HTML були повністю доступні для перетягування перед виконанням скрипту.
> Примітка: використовуйте `defer` при імпорті зовнішнього JavaScript-файлу в HTML-файл, щоб дозволити виконання JavaScript лише після повного завантаження HTML-файлу. Ви також можете використовувати атрибут `async`, який дозволяє скрипту виконуватися під час розбору HTML-файлу, але в нашому випадку важливо, щоб HTML-елементи були повністю доступні для перетягування перед виконанням скрипту перетягування.
---
## Елементи DOM
@ -73,7 +72,7 @@ dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
```
Що тут відбувається? Ви посилаєтеся на документ і шукаєте в його DOM елемент із певним Id. Пам'ятаєте, як у першому уроці з HTML ви дали індивідуальні Id кожному зображенню рослини (`id="plant1"`)? Тепер ви скористаєтеся цією роботою. Після ідентифікації кожного елемента ви передаєте цей елемент у функцію `dragElement`, яку ви створите за хвилину. Таким чином, елемент у HTML тепер готовий до перетягування або скоро буде.
Що тут відбувається? Ви посилаєтеся на документ і шукаєте в його DOM елемент із певним Id. Пам'ятаєте, як у першому уроці з HTML ви дали індивідуальні Id кожному зображенню рослини (`id="plant1"`)? Тепер ви скористаєтеся цією роботою. Після ідентифікації кожного елемента ви передаєте цей елемент у функцію `dragElement`, яку ви створите за хвилину. Таким чином, елемент у HTML тепер готовий до перетягування, або скоро буде.
✅ Чому ми посилаємося на елементи за Id? Чому не за їх CSS-класом? Ви можете звернутися до попереднього уроку з CSS, щоб відповісти на це запитання.
@ -103,7 +102,7 @@ console.log(candy)
### Завдання
Під оголошеннями елементів у `script.js` створіть функцію:
Під деклараціями елементів у `script.js` створіть функцію:
```javascript
function dragElement(terrariumElement) {
@ -116,11 +115,11 @@ function dragElement(terrariumElement) {
}
```
`dragElement` отримує свій об'єкт `terrariumElement` із оголошень у верхній частині скрипту. Потім ви встановлюєте деякі локальні позиції на `0` для об'єкта, переданого у функцію. Це локальні змінні, які будуть маніпулюватися для кожного елемента, коли ви додасте функціональність перетягування до кожного елемента в замиканні. Тераріум буде заповнений цими перетягнутими елементами, тому додаток має відстежувати, де вони розміщені.
`dragElement` отримує свій об'єкт `terrariumElement` із декларацій на початку скрипту. Потім ви встановлюєте деякі локальні позиції на `0` для об'єкта, переданого у функцію. Це локальні змінні, які будуть маніпулюватися для кожного елемента, коли ви додасте функціональність перетягування до кожного елемента в межах замикання. Тераріум буде заповнений цими перетягнутими елементами, тому додаток має відстежувати, де вони розміщені.
Крім того, елемент `terrariumElement`, переданий у цю функцію, отримує подію `pointerdown`, яка є частиною [веб API](https://developer.mozilla.org/docs/Web/API), створених для допомоги в управлінні DOM. `onpointerdown` спрацьовує, коли натискається кнопка або, у нашому випадку, торкається елемент, який можна перетягувати. Цей обробник подій працює як у [веббраузерах, так і в мобільних браузерах](https://caniuse.com/?search=onpointerdown), з кількома винятками.
Крім того, елемент `terrariumElement`, переданий у цю функцію, отримує подію `pointerdown`, яка є частиною [web API](https://developer.mozilla.org/docs/Web/API), створеного для допомоги в управлінні DOM. `onpointerdown` спрацьовує, коли натискається кнопка або, у нашому випадку, торкається елемент, який можна перетягувати. Цей обробник подій працює як у [веббраузерах, так і в мобільних браузерах](https://caniuse.com/?search=onpointerdown), з кількома винятками.
✅ [Обробник подій `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) має набагато більшу підтримку між браузерами; чому б не використати його тут? Подумайте про точний тип взаємодії зі сторінкою, який ви намагаєтеся створити.
✅ [Обробник подій `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) має набагато більшу підтримку між браузерами; чому б не використати його тут? Подумайте про точний тип взаємодії з екраном, який ви намагаєтеся створити.
---
@ -147,7 +146,7 @@ function pointerDrag(e) {
Далі зверніть увагу, як локальні змінні `pos3` і `pos4` встановлюються на e.clientX. Ви можете знайти значення `e` у панелі інспекції. Ці значення захоплюють координати x і y рослини в момент її натискання або торкання. Вам потрібен детальний контроль над поведінкою рослин під час їх натискання та перетягування, тому ви відстежуєте їх координати.
✅ Чи стає зрозумілішим, чому весь цей додаток побудований на одному великому замиканні? Як би ви підтримували область видимості для кожної з 14 рослин, які можна перетягувати, якщо б це було не так?
✅ Чи стає зрозуміліше, чому весь цей додаток побудований на одному великому замиканні? Як би ви підтримували область видимості для кожної з 14 рослин, які можна перетягувати, якщо б це було не так?
Завершіть початкову функцію, додавши ще дві маніпуляції подіями pointer під `pos4 = e.clientY`:
@ -178,9 +177,9 @@ function elementDrag(e) {
```
У цій функції ви багато редагуєте початкові позиції 1-4, які ви встановили як локальні змінні у зовнішній функції. Що тут відбувається?
Під час перетягування ви перепризначаєте `pos1`, роблячи його рівним `pos3` (який ви встановили раніше як `e.clientX`) мінус поточне значення `e.clientX`. Ви виконуєте аналогічну операцію для `pos2`. Потім ви скидаєте `pos3` і `pos4` до нових координат X і Y елемента. Ви можете спостерігати ці зміни в консолі під час перетягування. Потім ви маніпулюєте стилем css рослини, щоб встановити її нову позицію на основі нових позицій `pos1` і `pos2`, обчислюючи верхні та ліві координати X і Y рослини, порівнюючи її зміщення з цими новими позиціями.
Під час перетягування ви переназначаєте `pos1`, роблячи його рівним `pos3` (який ви встановили раніше як `e.clientX`) мінус поточне значення `e.clientX`. Ви виконуєте подібну операцію для `pos2`. Потім ви скидаєте `pos3` і `pos4` на нові координати X і Y елемента. Ви можете спостерігати ці зміни в консолі під час перетягування. Потім ви маніпулюєте стилем css рослини, щоб встановити її нову позицію на основі нових позицій `pos1` і `pos2`, обчислюючи верхні та ліві координати X і Y рослини на основі порівняння її зміщення з цими новими позиціями.
> `offsetTop` і `offsetLeft` — це властивості CSS, які встановлюють позицію елемента на основі його батьківського елемента; його батьком може бути будь-який елемент, який не має позиції `static`.
> `offsetTop` і `offsetLeft` — це властивості CSS, які встановлюють позицію елемента на основі його батьківського елемента; його батьківський елемент може бути будь-яким елементом, який не має позиції `static`.
Усі ці перерахунки позицій дозволяють вам точно налаштувати поведінку тераріуму та його рослин.
@ -197,11 +196,11 @@ function stopElementDrag() {
Ця невелика функція скидає події `onpointerup` і `onpointermove`, щоб ви могли або перезапустити прогрес вашої рослини, почавши її перетягувати знову, або почати перетягувати нову рослину.
✅ Що відбувається, якщо ви не встановите ці події в null?
✅ Що станеться, якщо ви не встановите ці події на null?
Тепер ваш проєкт завершено!
🥇Вітаємо! Ви завершили свій чудовий тераріум! ![готовий тераріум](../../../../translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.uk.png)
🥇Вітаємо! Ви завершили свій чудовий тераріум! ![завершений тераріум](../../../../translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.uk.png)
---
@ -209,13 +208,13 @@ function stopElementDrag() {
Додайте новий обробник подій до вашого замикання, щоб зробити щось ще з рослинами; наприклад, подвійне клацання на рослині, щоб перемістити її на передній план. Проявіть креативність!
## Післялекційна вікторина
## Тест після лекції
[Післялекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/20)
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/20)
## Огляд і самостійне навчання
Хоча перетягування елементів на екрані здається тривіальним, існує багато способів зробити це і багато підводних каменів, залежно від ефекту, якого ви прагнете. Насправді існує цілий [API для перетягування](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API), який ви можете спробувати. Ми не використовували його в цьому модулі, оскільки ефект, який ми хотіли, був дещо іншим, але спробуйте цей API у своєму власному проєкті і подивіться, чого ви можете досягти.
Хоча перетягування елементів по екрану здається тривіальним, існує багато способів зробити це і багато підводних каменів, залежно від ефекту, якого ви прагнете. Насправді існує цілий [API для перетягування](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API), який ви можете спробувати. Ми не використовували його в цьому модулі, оскільки ефект, який ми хотіли, був дещо іншим, але спробуйте цей API у своєму власному проєкті і подивіться, чого ви можете досягти.
Знайдіть більше інформації про події вказівника в [документації W3C](https://www.w3.org/TR/pointerevents1/) і на [MDN web docs](https://developer.mozilla.org/docs/Web/API/Pointer_events).

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e982871b8388c59c22a41b73b5fca70f",
"translation_date": "2025-08-27T22:43:30+00:00",
"original_hash": "1b0aeccb600f83c603cd70cb42df594d",
"translation_date": "2025-08-28T18:21:23+00:00",
"source_file": "4-typing-game/typing-game/README.md",
"language_code": "uk"
}
@ -15,19 +15,19 @@ CO_OP_TRANSLATOR_METADATA:
## Програмування, кероване подіями
Коли ми створюємо веб-додаток, ми надаємо графічний інтерфейс користувача (GUI), щоб користувач міг взаємодіяти з тим, що ми створили. Найпоширеніший спосіб взаємодії з браузером — це кліки та введення тексту в різних елементах. Виклик для нас, як розробників, полягає в тому, що ми не знаємо, коли користувач виконає ці дії!
Коли ми створюємо браузерний додаток, ми надаємо графічний інтерфейс користувача (GUI), щоб користувач міг взаємодіяти з тим, що ми створили. Найпоширеніший спосіб взаємодії з браузером — це кліки та введення тексту в різні елементи. Виклик для нас, як розробників, полягає в тому, що ми не знаємо, коли користувач виконає ці дії!
[Програмування, кероване подіями](https://en.wikipedia.org/wiki/Event-driven_programming) — це тип програмування, який нам потрібен для створення GUI. Якщо розібрати цю фразу, то основним словом тут є **подія**. [Подія](https://www.merriam-webster.com/dictionary/event), згідно з Merriam-Webster, визначається як "щось, що відбувається". Це ідеально описує нашу ситуацію. Ми знаємо, що щось станеться, і ми хочемо виконати певний код у відповідь, але ми не знаємо, коли це станеться.
[Програмування, кероване подіями](https://uk.wikipedia.org/wiki/Програмування,_кероване_подіями) — це назва типу програмування, який нам потрібно використовувати для створення нашого GUI. Якщо розібрати цю фразу, то основним словом тут є **подія**. [Подія](https://www.merriam-webster.com/dictionary/event), за визначенням Merriam-Webster, — це "щось, що відбувається". Це ідеально описує нашу ситуацію. Ми знаємо, що щось відбудеться, і ми хочемо виконати певний код у відповідь, але ми не знаємо, коли це станеться.
Щоб позначити частину коду, яку ми хочемо виконати, ми створюємо функцію. У [процедурному програмуванні](https://en.wikipedia.org/wiki/Procedural_programming) функції викликаються у певному порядку. Те ж саме буде справедливим для програмування, керованого подіями. Різниця полягає в тому, **як** функції будуть викликатися.
Спосіб, яким ми позначаємо частину коду, яку хочемо виконати, — це створення функції. Якщо ми говоримо про [процедурне програмування](https://uk.wikipedia.org/wiki/Процедурне_програмування), функції викликаються у певному порядку. Те ж саме стосується програмування, керованого подіями. Різниця лише в тому, **як** викликаються функції.
Для обробки подій (кліки кнопок, введення тексту тощо) ми реєструємо **слухачів подій**. Слухач подій — це функція, яка чекає на виникнення події та виконується у відповідь. Слухачі подій можуть оновлювати інтерфейс користувача, викликати сервер або виконувати будь-які інші дії у відповідь на дії користувача. Ми додаємо слухача подій за допомогою [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) і передаємо функцію для виконання.
Для обробки подій (натискання кнопок, введення тексту тощо) ми реєструємо **обробники подій**. Обробник подій — це функція, яка "слухає" подію та виконується у відповідь. Обробники подій можуть оновлювати інтерфейс користувача, викликати сервер або виконувати будь-які інші дії у відповідь на дії користувача. Ми додаємо обробник подій за допомогою [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) і передаємо функцію для виконання.
> **NOTE:** Варто зазначити, що існує багато способів створення слухачів подій. Ви можете використовувати анонімні функції або створювати іменовані. Ви можете використовувати різні скорочення, наприклад, встановлювати властивість `click` або використовувати `addEventListener`. У нашій вправі ми зосередимося на `addEventListener` і анонімних функціях, оскільки це, мабуть, найпоширеніша техніка, яку використовують веб-розробники. Це також найгнучкіший спосіб, оскільки `addEventListener` працює для всіх подій, а назву події можна передати як параметр.
> **NOTE:** Варто зазначити, що існує багато способів створення обробників подій. Ви можете використовувати анонімні функції або створювати іменовані. Ви можете використовувати різні скорочення, наприклад, встановлювати властивість `click` або використовувати `addEventListener`. У нашій вправі ми зосередимося на `addEventListener` та анонімних функціях, оскільки це, мабуть, найпоширеніший підхід, який використовують веброзробники. Це також найгнучкіший спосіб, оскільки `addEventListener` працює для всіх подій, а ім'я події можна передати як параметр.
### Поширені події
Існує [безліч подій](https://developer.mozilla.org/docs/Web/Events), які ви можете використовувати при створенні додатків. Практично будь-яка дія користувача на сторінці викликає подію, що дає вам багато можливостей для забезпечення бажаного досвіду. На щастя, вам зазвичай потрібна лише невелика кількість подій. Ось кілька поширених (включаючи ті, які ми будемо використовувати для створення нашої гри):
Існує [безліч подій](https://developer.mozilla.org/docs/Web/Events), які ви можете використовувати у своїх додатках. Практично будь-яка дія користувача на сторінці викликає подію, що дає вам багато можливостей для створення бажаного досвіду. На щастя, зазвичай вам знадобиться лише кілька основних подій. Ось кілька поширених (включаючи ті, які ми будемо використовувати для створення нашої гри):
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): Користувач натиснув на щось, зазвичай кнопку або гіперпосилання
- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): Користувач натиснув праву кнопку миші
@ -36,21 +36,21 @@ CO_OP_TRANSLATOR_METADATA:
## Створення гри
Ми створимо гру, щоб дослідити, як працюють події в JavaScript. Наша гра перевірятиме навички набору тексту гравця, що є однією з найбільш недооцінених навичок, які повинні мати всі розробники. Ми всі повинні практикувати набір тексту! Загальний процес гри виглядатиме так:
Ми створимо гру, щоб дослідити, як працюють події в JavaScript. Наша гра перевірятиме навички друку гравця, що є однією з найбільш недооцінених навичок, які повинен мати кожен розробник. Ми всі повинні практикувати друк! Загальний хід гри виглядатиме так:
- Гравець натискає кнопку старту і отримує цитату для набору
- Гравець набирає цитату якомога швидше у текстовому полі
- Кожне завершене слово виділяється наступним
- Якщо гравець зробив помилку, текстове поле стає червоним
- Гравець натискає кнопку "Почати" і отримує цитату для друку
- Гравець друкує цитату якомога швидше у текстовому полі
- Коли кожне слово завершено, наступне виділяється
- Якщо гравець робить помилку, текстове поле стає червоним
- Коли гравець завершує цитату, відображається повідомлення про успіх із витраченим часом
Давайте створимо нашу гру та дізнаємося про події!
### Структура файлів
Нам знадобиться три файли: **index.html**, **script.js** і **style.css**. Давайте почнемо з їх налаштування, щоб полегшити собі життя.
Нам знадобиться три файли: **index.html**, **script.js** і **style.css**. Почнемо з їх створення, щоб полегшити собі життя.
- Створіть нову папку для вашої роботи, відкривши консоль або термінал і виконавши наступну команду:
- Створіть нову папку для своєї роботи, відкривши консоль або термінал і виконавши наступну команду:
```bash
# Linux or macOS
@ -66,7 +66,7 @@ md typing-game && cd typing-game
code .
```
- Додайте три файли до папки у Visual Studio Code з наступними назвами:
- Додайте три файли до папки у Visual Studio Code з такими іменами:
- index.html
- script.js
- style.css
@ -75,14 +75,14 @@ code .
Якщо ми розглянемо вимоги, то зрозуміємо, що нам знадобиться кілька елементів на нашій HTML-сторінці. Це схоже на рецепт, де нам потрібні інгредієнти:
- Місце для відображення цитати, яку користувач має набрати
- Місце для відображення цитати, яку користувач має надрукувати
- Місце для відображення повідомлень, наприклад, повідомлення про успіх
- Текстове поле для введення тексту
- Кнопка старту
- Кнопка "Почати"
Кожному з цих елементів потрібні ID, щоб ми могли працювати з ними у нашому JavaScript. Ми також додамо посилання на CSS і JavaScript файли, які ми створимо.
Кожен із цих елементів потребуватиме ідентифікаторів, щоб ми могли працювати з ними у нашому JavaScript. Ми також додамо посилання на файли CSS і JavaScript, які ми створимо.
Створіть новий файл під назвою **index.html**. Додайте наступний HTML:
Створіть новий файл із назвою **index.html**. Додайте наступний HTML:
```html
<!-- inside index.html -->
@ -107,24 +107,24 @@ code .
### Запуск додатка
Завжди краще розробляти поступово, щоб бачити, як виглядає результат. Давайте запустимо наш додаток. У Visual Studio Code є чудове розширення під назвою [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), яке буде локально хостити ваш додаток і оновлювати браузер кожного разу, коли ви зберігаєте зміни.
Завжди краще розробляти ітеративно, щоб бачити, як усе виглядає. Давайте запустимо наш додаток. У Visual Studio Code є чудове розширення під назвою [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), яке дозволяє локально хостити ваш додаток і автоматично оновлювати браузер після збереження.
- Встановіть [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), перейшовши за посиланням і натиснувши **Install**
- Браузер запропонує вам відкрити Visual Studio Code, а потім Visual Studio Code запропонує виконати установку
- Браузер запропонує відкрити Visual Studio Code, а потім Visual Studio Code запропонує виконати встановлення
- Перезапустіть Visual Studio Code, якщо буде запропоновано
- Після встановлення у Visual Studio Code натисніть Ctrl-Shift-P (або Cmd-Shift-P), щоб відкрити командну палітру
- Після встановлення у Visual Studio Code натисніть Ctrl-Shift-P (або Cmd-Shift-P), щоб відкрити командний палітру
- Введіть **Live Server: Open with Live Server**
- Live Server почне хостити ваш додаток
- Відкрийте браузер і перейдіть на **https://localhost:5500**
- Тепер ви повинні побачити створену вами сторінку!
- Відкрийте браузер і перейдіть за адресою **https://localhost:5500**
- Тепер ви повинні побачити створену сторінку!
Давайте додамо функціональність.
Додамо трохи функціональності.
## Додати CSS
## Додавання CSS
Після створення HTML додамо CSS для основного стилювання. Нам потрібно виділити слово, яке гравець має набрати, і змінити колір текстового поля, якщо введений текст неправильний. Ми зробимо це за допомогою двох класів.
Після створення HTML додамо CSS для основного стилю. Нам потрібно виділити слово, яке гравець має друкувати, і змінити колір текстового поля, якщо введено неправильний текст. Ми зробимо це за допомогою двох класів.
Створіть новий файл під назвою **style.css** і додайте наступний синтаксис.
Створіть новий файл із назвою **style.css** і додайте наступний синтаксис.
```css
/* inside style.css */
@ -146,24 +146,24 @@ code .
## JavaScript
Після створення інтерфейсу користувача настав час зосередитися на JavaScript, який забезпечить логіку. Ми розділимо це на кілька етапів:
Після створення інтерфейсу користувача настав час зосередитися на JavaScript, який забезпечить логіку. Ми розділимо це на кілька кроків:
- [Створення констант](../../../../4-typing-game/typing-game)
- [Слухач подій для старту гри](../../../../4-typing-game/typing-game)
- [Слухач подій для введення тексту](../../../../4-typing-game/typing-game)
- [Обробник подій для початку гри](../../../../4-typing-game/typing-game)
- [Обробник подій для введення тексту](../../../../4-typing-game/typing-game)
Але спочатку створіть новий файл під назвою **script.js**.
Але спочатку створіть новий файл із назвою **script.js**.
### Додати константи
### Додавання констант
Нам знадобиться кілька елементів, щоб полегшити собі програмування. Знову ж таки, як у рецепті, ось що нам потрібно:
Нам знадобиться кілька елементів, щоб полегшити програмування. Знову ж таки, як у рецепті, ось що нам потрібно:
- Масив із списком усіх цитат
- Порожній масив для зберігання всіх слів поточної цитати
- Місце для зберігання індексу слова, яке гравець зараз набирає
- Час, коли гравець натиснув старт
- Масив із переліком усіх цитат
- Порожній масив для зберігання слів поточної цитати
- Місце для зберігання індексу слова, яке гравець зараз друкує
- Час, коли гравець натиснув "Почати"
Нам також потрібні посилання на елементи інтерфейсу користувача:
Нам також знадобляться посилання на елементи інтерфейсу:
- Текстове поле (**typed-value**)
- Відображення цитати (**quote**)
@ -194,19 +194,19 @@ const typedValueElement = document.getElementById('typed-value');
✅ Додайте більше цитат до вашої гри
> **NOTE:** Ми можемо отримувати елементи в будь-який момент у коді за допомогою `document.getElementById`. Оскільки ми будемо часто звертатися до цих елементів, ми уникнемо помилок із рядковими літералами, використовуючи константи. Фреймворки, такі як [Vue.js](https://vuejs.org/) або [React](https://reactjs.org/), можуть допомогти вам краще централізувати ваш код.
> **NOTE:** Ми можемо отримувати елементи в будь-який момент у коді за допомогою `document.getElementById`. Оскільки ми будемо часто звертатися до цих елементів, ми уникнемо помилок у рядкових літералах, використовуючи константи. Фреймворки, такі як [Vue.js](https://vuejs.org/) або [React](https://reactjs.org/), можуть допомогти вам краще централізувати ваш код.
Приділіть хвилинку, щоб переглянути відео про використання `const`, `let` і `var`.
Перегляньте відео про використання `const`, `let` і `var`
[![Типи змінних](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "Типи змінних")
> 🎥 Натисніть на зображення вище, щоб переглянути відео про змінні.
### Додати логіку старту
### Додавання логіки початку гри
Щоб почати гру, гравець натисне старт. Звісно, ми не знаємо, коли він це зробить. Тут нам допоможе [слухач подій](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener). Слухач подій дозволить нам чекати на виникнення події та виконувати код у відповідь. У нашому випадку ми хочемо виконати код, коли користувач натисне старт.
Щоб почати гру, гравець натискає "Почати". Звісно, ми не знаємо, коли він це зробить. Тут у гру вступає [обробник подій](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener). Обробник подій дозволяє нам слухати певну подію та виконувати код у відповідь. У нашому випадку ми хочемо виконати код, коли користувач натискає "Почати".
Коли користувач натискає **старт**, нам потрібно вибрати цитату, налаштувати інтерфейс користувача та налаштувати відстеження поточного слова та часу. Нижче наведено JavaScript, який вам потрібно додати; ми обговоримо його після блоку коду.
Коли користувач натискає **Почати**, нам потрібно вибрати цитату, налаштувати інтерфейс користувача та відстеження поточного слова й часу. Нижче наведено JavaScript, який вам потрібно додати; ми обговоримо його після блоку коду.
```javascript
// at the end of script.js
@ -245,23 +245,23 @@ document.getElementById('start').addEventListener('click', () => {
- Налаштування відстеження слів
- Використання [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, оскільки гравець почне з першого слова
- Ми перетворюємо `quote` на масив `words`, щоб відстежувати слово, яке гравець зараз друкує
- `wordIndex` встановлюється на 0, оскільки гравець починає з першого слова
- Налаштування інтерфейсу користувача
- Створюємо масив `spanWords`, який містить кожне слово всередині елемента `span`
- Це дозволить нам виділити слово на екрані
- `join` масиву створює рядок, який ми можемо використовувати для оновлення `innerHTML` у `quoteElement`
- Це відобразить цитату для гравця
- Встановлюємо `className` першого елемента `span` на `highlight`, щоб виділити його жовтим кольором
- Очищаємо `messageElement`, встановлюючи `innerText` на `''`
- Створюється масив `spanWords`, який містить кожне слово всередині елемента `span`
- Це дозволяє нам виділяти слово на екрані
- `join` масиву створює рядок, який ми можемо використати для оновлення `innerHTML` у `quoteElement`
- Це відображає цитату для гравця
- Встановлюється `className` першого елемента `span` на `highlight`, щоб виділити його жовтим
- Очищається `messageElement`, встановлюючи `innerText` у `''`
- Налаштування текстового поля
- Очищаємо поточне `value` у `typedValueElement`
- Встановлюємо `focus` на `typedValueElement`
- Запускаємо таймер, викликаючи `getTime`
- Очищається поточне `value` у `typedValueElement`
- Встановлюється `focus` на `typedValueElement`
- Запускається таймер, викликаючи `getTime`
### Додати логіку введення тексту
### Додавання логіки введення тексту
Коли гравець вводить текст, виникає подія `input`. Цей слухач подій перевірятиме, чи правильно гравець вводить слово, і оброблятиме поточний стан гри. Повертаючись до **script.js**, додайте наступний код у кінці. Ми розберемо його після блоку коду.
Коли гравець друкує, викликається подія `input`. Цей обробник подій перевіряє, чи правильно гравець друкує слово, і обробляє поточний стан гри. Поверніться до **script.js** і додайте наступний код у кінець. Ми розберемо його після блоку коду.
```javascript
// at the end of script.js
@ -300,27 +300,27 @@ typedValueElement.addEventListener('input', () => {
});
```
Розберемо код! Ми починаємо з отримання поточного слова та значення, яке гравець ввів на даний момент. Потім ми використовуємо каскадну логіку, де перевіряємо, чи завершена цитата, чи завершене слово, чи слово правильне, або (нарешті), чи є помилка.
Розберемо код! Ми починаємо з отримання поточного слова та значення, яке гравець ввів на цей момент. Потім ми використовуємо каскадну логіку, де перевіряємо, чи завершена цитата, чи завершене слово, чи слово правильне, або (нарешті), чи є помилка.
- Цитата завершена, якщо `typedValue` дорівнює `currentWord`, а `wordIndex` дорівнює одному менше, ніж `length` масиву `words`
- Обчислюємо `elapsedTime`, віднімаючи `startTime` від поточного часу
- Ділимо `elapsedTime` на 1,000, щоб перетворити мілісекунди на секунди
- Відображаємо повідомлення про успіх
- Цитата завершена, якщо `typedValue` дорівнює `currentWord`, а `wordIndex` дорівнює довжині `words` мінус один
- Обчислюється `elapsedTime`, віднімаючи `startTime` від поточного часу
- `elapsedTime` ділиться на 1,000, щоб перетворити мілісекунди на секунди
- Відображається повідомлення про успіх
- Слово завершене, якщо `typedValue` закінчується пробілом (кінець слова) і `typedValue` дорівнює `currentWord`
- Встановлюємо `value` у `typedElement` на `''`, щоб дозволити введення наступного слова
- Збільшуємо `wordIndex`, щоб перейти до наступного слова
- Проходимо через всі `childNodes` у `quoteElement`, встановлюючи `className` на `''`, щоб повернути стандартний вигляд
- Встановлюємо `className` поточного слова на `highlight`, щоб позначити його як наступне слово для введення
- Слово введено правильно (але не завершено), якщо `currentWord` починається з `typedValue`
- Переконуємося, що `typedValueElement` відображається як стандартний, очищаючи `className`
- Встановлюється `value` у `typedElement` на `''`, щоб дозволити друкувати наступне слово
- Збільшується `wordIndex`, щоб перейти до наступного слова
- Проходиться по всіх `childNodes` у `quoteElement`, щоб встановити `className` у `''`, повертаючи до стандартного вигляду
- Встановлюється `className` поточного слова на `highlight`, щоб позначити його як наступне для друку
- Слово наразі друкується правильно (але не завершене), якщо `currentWord` починається з `typedValue`
- Забезпечується відображення `typedValueElement` у стандартному вигляді, очищаючи `className`
- Якщо ми дійшли до цього моменту, є помилка
- Встановлюємо `className` у `typedValueElement` на `error`
- Встановлюється `className` у `typedValueElement` на `error`
## Перевірте ваш додаток
## Тестування додатка
Ви дійшли до кінця! Останній крок — переконатися, що ваш додаток працює. Спробуйте! Не хвилюйтеся, якщо виникнуть помилки; **усі розробники** стикаються з помилками. Аналізуйте повідомлення та виправляйте їх за потреби.
Ви дійшли до кінця! Останній крок — переконатися, що наш додаток працює. Спробуйте! Не хвилюйтеся, якщо виникнуть помилки; **усі розробники** стикаються з помилками. Перегляньте повідомлення та налагоджуйте за потреби.
Натисніть **старт** і починайте вводити текст! Це має виглядати приблизно так, як показано на анімації.
Натисніть **Почати** і починайте друкувати! Це має виглядати приблизно так, як на анімації, яку ми бачили раніше.
![Анімація гри в дії](../../../../4-typing-game/images/demo.gif)
@ -330,18 +330,17 @@ typedValueElement.addEventListener('input', () => {
Додайте більше функціональності
- Вимкніть слухач подій `input` після завершення гри та увімкніть його знову, коли натиснуто кнопку
- Вимкніть текстове поле, коли гравець завершує цитату
- Відобразіть модальне діалогове вікно з повідомленням про успіх
- Зберігайте найвищі результати за допомогою [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)
- Вимикайте обробник подій `input` після завершення гри та знову вмикайте його, коли натискається кнопка
- Вимикайте текстове поле, коли гравець завершує цитату
- Відображайте модальне діалогове вікно з повідомленням про успіх
- Зберігайте найкращі результати за допомогою [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)
## Тест після лекції
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/22)
## Огляд і самостійне навчання
## Огляд та самостійне навчання
Ознайомтеся з [усіма доступними подіями](https://developer.mozilla.org/docs/Web/Events) для розробника через веб-браузер і подумайте про сценарії, в яких ви б використовували кожну з них.
Ознайомтеся з [усіма доступними подіями](https://developer.mozilla.org/docs/Web/Events), які веб-браузер надає розробнику, і подумайте про сценарії, в яких ви б використовували кожну з них.
## Завдання

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "0bb55e0b98600afab801eea115228873",
"translation_date": "2025-08-27T22:09:38+00:00",
"original_hash": "2326d04e194a10aa760b51f5e5a1f61d",
"translation_date": "2025-08-28T18:10:07+00:00",
"source_file": "5-browser-extension/1-about-browsers/README.md",
"language_code": "uk"
}
@ -22,47 +22,47 @@ CO_OP_TRANSLATOR_METADATA:
### Про браузер
У цьому циклі уроків ви навчитеся створювати розширення для браузера, яке працюватиме в Chrome, Firefox та Edge. У цій частині ви дізнаєтеся, як працюють браузери, і створите структуру елементів розширення для браузера.
У цьому циклі уроків ви навчитеся створювати розширення для браузера, яке працюватиме в Chrome, Firefox та Edge. У цій частині ви дізнаєтеся, як працюють браузери, і створите основні елементи розширення для браузера.
Але що таке браузер? Це програмне забезпечення, яке дозволяє кінцевому користувачеві отримувати контент із сервера та відображати його на веб-сторінках.
✅ Трохи історії: перший браузер називався "WorldWideWeb" і був створений сером Тімоті Бернерсом-Лі у 1990 році.
✅ Трохи історії: перший браузер називався 'WorldWideWeb' і був створений сером Тімоті Бернерсом-Лі у 1990 році.
![early browsers](../../../../translated_images/earlybrowsers.d984b711cdf3a42ddac919d46c4b5ca7232f68ccfbd81395e04e5a64c0015277.uk.jpg)
> Деякі ранні браузери, через [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
Коли користувач підключається до інтернету, використовуючи адресу URL (Uniform Resource Locator), зазвичай через протокол передачі гіпертексту `http` або `https`, браузер взаємодіє з веб-сервером і отримує веб-сторінку.
Коли користувач підключається до інтернету за допомогою адреси URL (Uniform Resource Locator), зазвичай через протокол передачі гіпертексту `http` або `https`, браузер взаємодіє з веб-сервером і отримує веб-сторінку.
На цьому етапі механізм рендерингу браузера відображає її на пристрої користувача, який може бути мобільним телефоном, настільним комп'ютером або ноутбуком.
Браузери також мають можливість кешувати контент, щоб його не доводилося отримувати з сервера кожного разу. Вони можуть записувати історію активності користувача, зберігати "куки" — невеликі фрагменти даних, які містять інформацію про активність користувача, і багато іншого.
Браузери також мають можливість кешувати контент, щоб його не доводилося отримувати з сервера кожного разу. Вони можуть записувати історію активності користувача, зберігати 'cookies' — невеликі фрагменти даних, які містять інформацію про активність користувача, і багато іншого.
Важливо пам'ятати, що браузери не однакові! Кожен браузер має свої сильні та слабкі сторони, і професійний веб-розробник повинен розуміти, як зробити веб-сторінки ефективними для різних браузерів. Це включає роботу з маленькими екранами, такими як мобільні телефони, а також з користувачами, які перебувають офлайн.
Дуже корисний веб-сайт, який варто додати в закладки у вашому улюбленому браузері, це [caniuse.com](https://www.caniuse.com). Коли ви створюєте веб-сторінки, дуже корисно використовувати списки підтримуваних технологій на цьому сайті, щоб найкраще підтримувати своїх користувачів.
Дуже корисний веб-сайт, який варто додати в закладки у вашому улюбленому браузері — [caniuse.com](https://www.caniuse.com). Коли ви створюєте веб-сторінки, дуже зручно використовувати списки підтримуваних технологій на цьому сайті, щоб найкраще підтримувати своїх користувачів.
✅ Як дізнатися, які браузери найпопулярніші серед користувачів вашого веб-сайту? Перевірте свою аналітику — ви можете встановити різні пакети аналітики як частину процесу веб-розробки, і вони покажуть вам, які браузери найчастіше використовуються.
## Розширення для браузера
Чому варто створювати розширення для браузера? Це зручний інструмент, який можна прикріпити до браузера для швидкого доступу до завдань, які ви часто повторюєте. Наприклад, якщо вам потрібно перевіряти кольори на різних веб-сторінках, які ви використовуєте, ви можете встановити розширення для вибору кольорів. Якщо вам важко запам'ятовувати паролі, ви можете використовувати розширення для управління паролями.
Чому варто створювати розширення для браузера? Це зручний інструмент, який можна прикріпити до браузера для швидкого доступу до завдань, які ви часто повторюєте. Наприклад, якщо вам потрібно перевіряти кольори на різних веб-сторінках, ви можете встановити розширення для вибору кольорів. Якщо вам важко запам'ятовувати паролі, ви можете використовувати розширення для управління паролями.
Розширення для браузера також цікаво розробляти. Вони зазвичай виконують обмежену кількість завдань, але роблять це дуже добре.
Розробка розширень для браузера також приносить задоволення. Вони зазвичай виконують обмежену кількість завдань, але роблять це дуже добре.
✅ Які ваші улюблені розширення для браузера? Які завдання вони виконують?
### Встановлення розширень
Перед тим, як почати створювати, ознайомтеся з процесом створення та розгортання розширення для браузера. Хоча кожен браузер трохи відрізняється у тому, як він управляє цим завданням, процес схожий у Chrome і Firefox на прикладі Edge:
Перед тим, як почати створювати розширення, ознайомтеся з процесом його створення та розгортання. Хоча кожен браузер трохи відрізняється у тому, як він управляє цим завданням, процес схожий у Chrome і Firefox на прикладі Edge:
![screenshot of the Edge browser showing the open edge://extensions page and open settings menu](../../../../translated_images/install-on-edge.d68781acaf0b3d3dada8b7507cde7a64bf74b7040d9818baaa9070668e819f90.uk.png)
> Примітка: Переконайтеся, що ви увімкнули режим розробника та дозволили встановлення розширень з інших магазинів.
> Примітка: Переконайтеся, що увімкнули режим розробника та дозволили розширення з інших магазинів.
Суть процесу:
- створіть своє розширення, використовуючи `npm run build`
- перейдіть у браузері до панелі розширень, використовуючи кнопку "Налаштування та інше" (значок `...`) у верхньому правому куті
- створіть своє розширення за допомогою `npm run build`
- перейдіть у браузері до панелі розширень через кнопку "Налаштування та інше" (значок `...`) у верхньому правому куті
- якщо це нова установка, виберіть `load unpacked`, щоб завантажити нове розширення з його папки збірки (у нашому випадку це `/dist`)
- або натисніть `reload`, якщо ви перезавантажуєте вже встановлене розширення
@ -70,28 +70,28 @@ CO_OP_TRANSLATOR_METADATA:
### Початок роботи
Ви створите розширення для браузера, яке відображатиме вуглецевий слід вашого регіону, показуючи енергоспоживання вашого регіону та джерело енергії. Розширення матиме форму для збору ключа API, щоб ви могли отримати доступ до API CO2 Signal.
Ви створите розширення для браузера, яке показуватиме вуглецевий слід вашого регіону, відображаючи енергоспоживання вашого регіону та джерело енергії. Розширення матиме форму для введення ключа API, щоб ви могли отримати доступ до API CO2 Signal.
**Вам потрібно:**
- [ключ API](https://www.co2signal.com/); введіть свою електронну адресу у поле на цій сторінці, і вам буде надіслано ключ
- [код вашого регіону](http://api.electricitymap.org/v3/zones), який відповідає [Electricity Map](https://www.electricitymap.org/map) (наприклад, у Бостоні я використовую 'US-NEISO').
- [початковий код](../../../../5-browser-extension/start). Завантажте папку `start`; ви будете доповнювати код у цій папці.
- [NPM](https://www.npmjs.com) - NPM — це інструмент управління пакетами; встановіть його локально, і пакети, зазначені у вашому файлі `package.json`, будуть встановлені для використання у вашому веб-активі
- [NPM](https://www.npmjs.com) - NPM — це інструмент управління пакетами; встановіть його локально, і пакети, зазначені у вашому файлі `package.json`, будуть встановлені для використання у вашому веб-ресурсі
✅ Дізнайтеся більше про управління пакетами у цьому [чудовому модулі Learn](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)
Приділіть хвилину, щоб переглянути кодову базу:
Витратьте хвилину, щоб ознайомитися з кодовою базою:
dist
-|manifest.json (налаштування за замовчуванням тут)
-|index.html (HTML-розмітка фронтенду тут)
-|background.js (JS для фону тут)
-|main.js (збірка JS)
-|main.js (згенерований JS)
src
-|index.js (ваш JS-код тут)
✅ Як тільки у вас буде ключ API та код регіону, збережіть їх десь у нотатках для подальшого використання.
✅ Як тільки у вас буде ключ API та код регіону, збережіть їх у нотатці для подальшого використання.
### Створення HTML для розширення
@ -103,9 +103,9 @@ src
![screenshot of the completed extension displaying values for carbon usage and fossil fuel percentage for the US-NEISO region.](../../../../translated_images/2.1dae52ff0804224692cd648afbf2342955d7afe3b0101b617268130dfb427f55.uk.png)
Почнемо зі створення HTML для форми та стилізації її за допомогою CSS.
Почнемо зі створення HTML для форми та її стилізації за допомогою CSS.
У папці `/dist` ви створите форму та область результатів. У файлі `index.html` заповніть позначену область форми:
У папці `/dist` ви створите форму та область результатів. У файлі `index.html` заповніть область форми:
```HTML
<form class="form-data" autocomplete="on">
@ -125,7 +125,7 @@ src
```
Це форма, де збережена інформація буде введена та збережена у локальному сховищі.
Далі створіть область результатів; під фінальним тегом форми додайте кілька div:
Далі створіть область результатів; під останнім тегом форми додайте кілька div:
```HTML
<div class="result">
@ -164,7 +164,7 @@ npm install
## Огляд та самостійне навчання
На цьому уроці ви дізналися трохи про історію веб-браузера; скористайтеся цією можливістю, щоб дізнатися, як винахідники Всесвітньої павутини уявляли її використання, прочитавши більше про її історію. Деякі корисні сайти:
У цьому уроці ви дізналися трохи про історію веб-браузера; скористайтеся цією можливістю, щоб дізнатися більше про те, як винахідники Всесвітньої павутини уявляли її використання, прочитавши більше про її історію. Деякі корисні сайти:
[Історія веб-браузерів](https://www.mozilla.org/firefox/browsers/browser-history/)
@ -179,4 +179,4 @@ npm install
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e10f168beac4e7b05e30e0eb5c92bf11",
"translation_date": "2025-08-27T22:17:02+00:00",
"original_hash": "a7587943d38d095de8613e1b508609f5",
"translation_date": "2025-08-28T18:12:39+00:00",
"source_file": "5-browser-extension/2-forms-browsers-local-storage/README.md",
"language_code": "uk"
}
-->
# Проєкт розширення для браузера, частина 2: Виклик API, використання Local Storage
# Проєкт розширення для браузера, частина 2: Виклик API, використання локального сховища
## Тест перед лекцією
@ -15,13 +15,13 @@ CO_OP_TRANSLATOR_METADATA:
### Вступ
У цьому уроці ви навчитеся викликати API, надсилаючи форму вашого розширення для браузера, і відображати результати в ньому. Крім того, ви дізнаєтеся, як зберігати дані в локальному сховищі браузера для подальшого використання.
У цьому уроці ви навчитеся викликати API, надсилаючи форму вашого розширення для браузера, і відображати результати у розширенні. Крім того, ви дізнаєтеся, як зберігати дані у локальному сховищі браузера для подальшого використання.
✅ Дотримуйтесь нумерованих сегментів у відповідних файлах, щоб знати, куди вставляти код.
✅ Дотримуйтесь нумерованих сегментів у відповідних файлах, щоб знати, куди вставляти ваш код.
### Налаштування елементів для роботи в розширенні:
### Налаштування елементів для маніпуляцій у розширенні:
На цьому етапі ви вже створили HTML для форми та `<div>` для результатів вашого розширення. Тепер вам потрібно працювати у файлі `/src/index.js` і поступово будувати ваше розширення. Зверніться до [попереднього уроку](../1-about-browsers/README.md) для налаштування проєкту та процесу збірки.
На цьому етапі ви вже створили HTML для форми та `<div>` для результатів вашого розширення. Тепер вам потрібно працювати у файлі `/src/index.js` і поступово будувати ваше розширення. Зверніться до [попереднього уроку](../1-about-browsers/README.md), щоб налаштувати ваш проєкт і ознайомитися з процесом збірки.
Працюючи у файлі `index.js`, почніть із створення кількох змінних `const`, щоб зберігати значення, пов'язані з різними полями:
@ -41,11 +41,11 @@ const myregion = document.querySelector('.my-region');
const clearBtn = document.querySelector('.clear-btn');
```
Усі ці поля посилаються на їхні CSS-класи, які ви налаштували в HTML на попередньому уроці.
Усі ці поля посилаються на їхні CSS-класи, які ви налаштували у HTML на попередньому уроці.
### Додайте слухачі подій
Далі додайте слухачі подій для форми та кнопки очищення, яка скидає форму, щоб при надсиланні форми або натисканні кнопки очищення щось відбувалося. Також додайте виклик для ініціалізації додатка в кінці файлу:
Далі додайте слухачі подій для форми та кнопки очищення, яка скидає форму. Таким чином, якщо користувач надсилає форму або натискає кнопку скидання, щось відбуватиметься. Також додайте виклик для ініціалізації програми в кінці файлу:
```JavaScript
form.addEventListener('submit', (e) => handleSubmit(e));
@ -53,11 +53,11 @@ clearBtn.addEventListener('click', (e) => reset(e));
init();
```
✅ Зверніть увагу на скорочений запис для прослуховування подій submit або click і на те, як подія передається у функції handleSubmit або reset. Чи можете ви написати еквівалент цього скорочення у довшому форматі? Який підхід вам більше подобається?
✅ Зверніть увагу на скорочений синтаксис для прослуховування подій submit або click і те, як подія передається у функції handleSubmit або reset. Чи можете ви написати еквівалент цього скорочення у більш розгорнутому форматі? Який підхід вам більше подобається?
### Розробка функцій init() та reset():
### Створіть функції init() та reset():
Тепер ви створите функцію, яка ініціалізує розширення, і називається вона init():
Тепер вам потрібно створити функцію, яка ініціалізує розширення, і називається вона init():
```JavaScript
function init() {
@ -93,30 +93,30 @@ function reset(e) {
```
У цій функції є цікава логіка. Прочитавши її, чи можете ви зрозуміти, що відбувається?
У цій функції є цікава логіка. Прочитайте її уважно, чи можете ви зрозуміти, що відбувається?
- створюються дві змінні `const`, щоб перевірити, чи зберіг користувач APIKey і код регіону в локальному сховищі.
- якщо будь-яке з цих значень дорівнює null, форма відображається, змінюючи її стиль на 'block'.
- приховуються результати, завантаження та кнопка очищення, а текст помилки встановлюється як порожній рядок.
- якщо ключ і регіон існують, запускається процедура:
- виклик API для отримання даних про вуглецеве споживання,
- Створюються дві змінні `const`, щоб перевірити, чи зберіг користувач APIKey і код регіону у локальному сховищі.
- Якщо будь-яке з цих значень дорівнює null, форма відображається, змінюючи її стиль на 'block'.
- Ховаються результати, завантаження та кнопка очищення, а текст помилки встановлюється як порожній рядок.
- Якщо ключ і регіон існують, запускається процедура:
- виклик API для отримання даних про вуглецевий слід,
- приховування області результатів,
- приховування форми,
- відображення кнопки скидання.
Перед тим як рухатися далі, корисно дізнатися про дуже важливу концепцію, доступну в браузерах: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage — це зручний спосіб зберігати рядки в браузері у вигляді пари `ключ-значення`. Цей тип веб-сховища можна маніпулювати за допомогою JavaScript для управління даними в браузері. LocalStorage не має терміну дії, тоді як SessionStorage, інший вид веб-сховища, очищується при закритті браузера. Різні типи сховищ мають свої переваги та недоліки.
Перед тим як рухатися далі, корисно дізнатися про дуже важливу концепцію, доступну у браузерах: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage — це зручний спосіб зберігати рядки у браузері у вигляді пар `ключ-значення`. Цей тип веб-сховища можна маніпулювати за допомогою JavaScript для управління даними у браузері. LocalStorage не має терміну дії, тоді як SessionStorage, інший тип веб-сховища, очищується при закритті браузера. Різні типи сховищ мають свої переваги та недоліки.
> Примітка: ваше розширення для браузера має власне локальне сховище; головне вікно браузера — це окремий екземпляр і працює незалежно.
> Зверніть увагу: ваше розширення для браузера має власне локальне сховище; головне вікно браузера — це окремий екземпляр і працює незалежно.
Ви встановлюєте значення APIKey як рядок, наприклад, і можете побачити, що воно встановлене в Edge, "інспектуючи" веб-сторінку (ви можете клацнути правою кнопкою миші в браузері, щоб інспектувати) і перейти на вкладку Applications, щоб побачити сховище.
Ви можете встановити значення для вашого APIKey, наприклад, і побачити його у Edge, "інспектуючи" веб-сторінку (ви можете клацнути правою кнопкою миші у браузері, щоб інспектувати) і перейти на вкладку Applications, щоб побачити сховище.
![Панель локального сховища](../../../../translated_images/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.uk.png)
✅ Подумайте про ситуації, коли НЕ варто зберігати деякі дані в LocalStorage. Загалом, розміщення API Keys у LocalStorage — це погана ідея! Чи розумієте ви чому? У нашому випадку, оскільки наш додаток створений виключно для навчання і не буде розміщений у магазині додатків, ми використовуємо цей метод.
✅ Подумайте про ситуації, коли ви НЕ хотіли б зберігати певні дані у LocalStorage. Загалом, зберігати API Keys у LocalStorage — погана ідея! Чи розумієте ви чому? У нашому випадку, оскільки наш додаток створений лише для навчання і не буде розміщений у магазині додатків, ми використовуємо цей метод.
Зверніть увагу, що ви використовуєте Web API для маніпуляції LocalStorage, використовуючи `getItem()`, `setItem()` або `removeItem()`. Це широко підтримується у браузерах.
Зверніть увагу, що ви використовуєте Web API для маніпуляцій із LocalStorage, використовуючи `getItem()`, `setItem()` або `removeItem()`. Це широко підтримується у браузерах.
Перш ніж створювати функцію `displayCarbonUsage()`, яка викликається в `init()`, давайте створимо функціонал для обробки початкового надсилання форми.
Перед тим як створювати функцію `displayCarbonUsage()`, яка викликається у `init()`, давайте створимо функціонал для обробки початкового надсилання форми.
### Обробка надсилання форми
@ -129,7 +129,7 @@ function handleSubmit(e) {
}
```
✅ Освіжіть пам'ять — HTML, який ви створили на попередньому уроці, має два поля введення, значення яких захоплюються через `const`, які ви створили на початку файлу, і обидва вони є `required`, тому браузер не дозволяє користувачам вводити порожні значення.
✅ Освіжіть пам'ять — HTML, який ви створили на попередньому уроці, має два поля введення, значення яких захоплюються через `const`, які ви створили на початку файлу, і вони обидва є `required`, тому браузер не дозволяє користувачам вводити порожні значення.
### Налаштування користувача
@ -147,17 +147,17 @@ function setUpUser(apiKey, regionName) {
}
```
Ця функція встановлює повідомлення про завантаження, яке відображається під час виклику API. На цьому етапі ви дійшли до створення найважливішої функції цього розширення для браузера!
Ця функція встановлює повідомлення про завантаження, яке відображається під час виклику API. На цьому етапі ви підійшли до створення найважливішої функції цього розширення для браузера!
### Відображення вуглецевого споживання
### Відображення вуглецевого сліду
Нарешті, час зробити запит до API!
Нарешті, настав час зробити запит до API!
Перш ніж рухатися далі, варто обговорити API. API, або [Інтерфейси програмування додатків](https://www.webopedia.com/TERM/A/API.html), є критичним елементом інструментарію веб-розробника. Вони забезпечують стандартні способи взаємодії та інтерфейсу між програмами. Наприклад, якщо ви створюєте веб-сайт, який потребує запиту до бази даних, хтось міг створити API для вас. Хоча існує багато типів API, одним із найпопулярніших є [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/).
Перед тим як рухатися далі, варто обговорити API. API, або [Інтерфейси програмування додатків](https://www.webopedia.com/TERM/A/API.html), є критичним елементом інструментарію веб-розробника. Вони забезпечують стандартні способи взаємодії програм між собою. Наприклад, якщо ви створюєте веб-сайт, який потребує доступу до бази даних, хтось міг створити API для використання. Хоча існує багато типів API, одним із найпопулярніших є [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/).
✅ Термін 'REST' означає 'Representational State Transfer' і передбачає використання різноманітно налаштованих URL-адрес для отримання даних. Проведіть невелике дослідження про різні типи API, доступні розробникам. Який формат вам здається найбільш привабливим?
✅ Термін 'REST' означає 'Representational State Transfer' і передбачає використання різноманітно налаштованих URL для отримання даних. Проведіть невелике дослідження про різні типи API, доступні розробникам. Який формат вам подобається найбільше?
Є важливі моменти, на які слід звернути увагу в цій функції. По-перше, зверніть увагу на ключове слово [`async`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Написання ваших функцій таким чином, щоб вони працювали асинхронно, означає, що вони чекатимуть завершення дії, наприклад, повернення даних, перш ніж продовжити.
Є кілька важливих моментів у цій функції. По-перше, зверніть увагу на ключове слово [`async`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Написання функцій, які працюють асинхронно, означає, що вони чекають завершення певної дії, наприклад, повернення даних, перед тим як продовжити.
Ось коротке відео про `async`:
@ -207,20 +207,20 @@ async function displayCarbonUsage(apiKey, region) {
Це велика функція. Що тут відбувається?
- дотримуючись найкращих практик, ви використовуєте ключове слово `async`, щоб ця функція працювала асинхронно. Функція містить блок `try/catch`, оскільки вона повертає обіцянку, коли API повертає дані. Оскільки ви не контролюєте швидкість відповіді API (він може взагалі не відповісти!), вам потрібно обробити цю невизначеність, викликаючи його асинхронно.
- ви робите запит до API co2signal, щоб отримати дані вашого регіону, використовуючи ваш API Key. Щоб використовувати цей ключ, вам потрібно використовувати тип автентифікації в параметрах заголовка.
- коли API відповідає, ви призначаєте різні елементи його відповіді частинам вашого екрану, які ви налаштували для відображення цих даних.
- якщо виникає помилка або результату немає, ви відображаєте повідомлення про помилку.
- Дотримуючись найкращих практик, ви використовуєте ключове слово `async`, щоб зробити цю функцію асинхронною. Функція містить блок `try/catch`, оскільки вона повертає обіцянку, коли API повертає дані. Оскільки ви не контролюєте швидкість відповіді API (він може взагалі не відповісти!), вам потрібно обробляти цю невизначеність, викликаючи його асинхронно.
- Ви робите запит до API co2signal, щоб отримати дані вашого регіону, використовуючи ваш API Key. Для використання цього ключа потрібно використовувати тип автентифікації у параметрах заголовка.
- Коли API відповідає, ви призначаєте різні елементи його даних відповідним частинам вашого екрану, які ви налаштували для відображення цих даних.
- Якщо виникає помилка або немає результату, ви відображаєте повідомлення про помилку.
✅ Використання асинхронних шаблонів програмування — це ще один дуже корисний інструмент у вашому арсеналі. Прочитайте [про різні способи](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function), якими можна налаштувати цей тип коду.
✅ Використання асинхронних шаблонів програмування — це ще один дуже корисний інструмент у вашому арсеналі. Прочитайте [про різні способи](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) налаштування такого коду.
Вітаємо! Якщо ви зберете своє розширення (`npm run build`) і оновите його на панелі розширень, у вас буде працююче розширення! Єдине, що поки не працює, — це іконка, і ви виправите це в наступному уроці.
Вітаємо! Якщо ви зберете ваше розширення (`npm run build`) і оновите його у панелі розширень, у вас буде працююче розширення! Єдине, що поки не працює, — це іконка, і ви виправите це у наступному уроці.
---
## 🚀 Виклик
Ми обговорили кілька типів API у цих уроках. Оберіть веб-API та дослідіть, що воно пропонує. Наприклад, ознайомтеся з API, доступними в браузерах, такими як [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). Що, на вашу думку, робить API чудовим?
Ми обговорили кілька типів API у цих уроках. Оберіть веб-API і дослідіть детально, що воно пропонує. Наприклад, ознайомтеся з API, доступними у браузерах, такими як [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). Що, на вашу думку, робить API чудовим?
## Тест після лекції
@ -228,7 +228,7 @@ async function displayCarbonUsage(apiKey, region) {
## Огляд і самостійне навчання
У цьому уроці ви дізналися про LocalStorage та API, обидва дуже корисні для професійного веб-розробника. Чи можете ви подумати, як ці дві речі працюють разом? Подумайте, як би ви спроєктували веб-сайт, який зберігає елементи для використання API.
У цьому уроці ви дізналися про LocalStorage і API, обидва дуже корисні для професійного веб-розробника. Чи можете ви подумати, як ці дві речі працюють разом? Подумайте, як би ви спроєктували веб-сайт, який зберігає елементи для використання API.
## Завдання
@ -237,4 +237,4 @@ async function displayCarbonUsage(apiKey, region) {
---
**Відмова від відповідальності**:
Цей документ було перекладено за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, зверніть увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ мовою оригіналу слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f198c6b817b4b2a99749f4662e7cae98",
"translation_date": "2025-08-27T22:11:28+00:00",
"original_hash": "49b58721a71cfda824e2f3e1f46908c6",
"translation_date": "2025-08-28T18:11:15+00:00",
"source_file": "5-browser-extension/3-background-tasks-and-performance/README.md",
"language_code": "uk"
}
@ -15,25 +15,25 @@ CO_OP_TRANSLATOR_METADATA:
### Вступ
У двох попередніх уроках цього модуля ви навчилися створювати форму та область відображення для даних, отриманих з API. Це дуже стандартний спосіб створення веб-присутності. Ви навіть дізналися, як асинхронно отримувати дані. Ваше розширення для браузера майже готове.
У двох попередніх уроках цього модуля ви навчилися створювати форму та область відображення для даних, отриманих з API. Це дуже стандартний спосіб створення веб-присутності в інтернеті. Ви навіть навчилися обробляти асинхронне отримання даних. Ваше розширення для браузера майже готове.
Залишилося впоратися з деякими фоновими завданнями, зокрема оновленням кольору значка розширення. Це чудова нагода поговорити про те, як браузер керує такими завданнями. Давайте розглянемо ці завдання у контексті продуктивності ваших веб-ресурсів під час їх створення.
Залишилося впоратися з деякими фоновими завданнями, включаючи оновлення кольору іконки розширення, тому зараз чудовий час поговорити про те, як браузер управляє такими завданнями. Давайте розглянемо ці завдання в контексті продуктивності ваших веб-ресурсів під час їх створення.
## Основи продуктивності вебсайтів
## Основи веб-продуктивності
> "Продуктивність вебсайту стосується двох речей: наскільки швидко завантажується сторінка і наскільки швидко виконується код на ній." -- [Зак Гроссбарт](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
> "Продуктивність вебсайту стосується двох речей: як швидко завантажується сторінка і як швидко виконується код на ній." -- [Зак Гроссбарт](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
Тема оптимізації вебсайтів для швидкої роботи на всіх типах пристроїв, для всіх користувачів і в будь-яких умовах є надзвичайно обширною. Ось кілька моментів, які варто враховувати під час створення стандартного вебпроєкту або розширення для браузера.
Тема про те, як зробити ваші вебсайти надзвичайно швидкими на всіх типах пристроїв, для всіх типів користувачів і в усіх ситуаціях, є, як не дивно, дуже обширною. Ось кілька моментів, які варто враховувати під час створення стандартного вебпроєкту або розширення для браузера.
Перше, що потрібно зробити, щоб переконатися, що ваш сайт працює ефективно, — це зібрати дані про його продуктивність. Найперше місце для цього — інструменти розробника вашого веббраузера. У Edge ви можете вибрати кнопку "Налаштування та інше" (значок із трьома крапками у верхньому правому куті браузера), потім перейти до "Додаткові інструменти" > "Інструменти розробника" і відкрити вкладку "Продуктивність". Ви також можете скористатися комбінацією клавіш `Ctrl` + `Shift` + `I` у Windows або `Option` + `Command` + `I` на Mac, щоб відкрити інструменти розробника.
Перше, що вам потрібно зробити, щоб переконатися, що ваш сайт працює ефективно, — це зібрати дані про його продуктивність. Першим місцем для цього є інструменти розробника вашого веббраузера. У Edge ви можете вибрати кнопку "Налаштування та інше" (іконка з трьома крапками у верхньому правому куті браузера), потім перейти до "Додаткові інструменти" > "Інструменти розробника" і відкрити вкладку "Продуктивність". Ви також можете використовувати комбінації клавіш `Ctrl` + `Shift` + `I` на Windows або `Option` + `Command` + `I` на Mac, щоб відкрити інструменти розробника.
На вкладці "Продуктивність" є інструмент профілювання. Відкрийте вебсайт (наприклад, [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) і натисніть кнопку "Запис", а потім оновіть сайт. Зупиніть запис у будь-який момент, і ви зможете побачити рутинні процеси, які генеруються для "скриптів", "рендерингу" та "малювання" сайту:
Вкладка "Продуктивність" містить інструмент профілювання. Відкрийте вебсайт (спробуйте, наприклад, [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) і натисніть кнопку "Запис", потім оновіть сайт. Зупиніть запис у будь-який момент, і ви зможете побачити процедури, які генеруються для "скрипту", "рендерингу" та "малювання" сайту:
![Профайлер Edge](../../../../translated_images/profiler.5a4a62479c5df01cfec9aab74173dba13f91d2c968e1a1ae434c26165792df15.uk.png)
✅ Відвідайте [документацію Microsoft](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) про панель продуктивності в Edge.
✅ Відвідайте [Документацію Microsoft](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) про панель продуктивності в Edge.
> Порада: щоб отримати точні дані про час завантаження вашого сайту, очистіть кеш браузера.
> Порада: щоб отримати точні дані про час запуску вашого сайту, очистіть кеш браузера.
Виберіть елементи на шкалі часу профілю, щоб збільшити події, які відбуваються під час завантаження вашої сторінки.
@ -41,29 +41,29 @@ CO_OP_TRANSLATOR_METADATA:
![Знімок профайлера Edge](../../../../translated_images/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.uk.png)
Перевірте панель журналу подій, щоб побачити, чи є події, які тривали довше 15 мс:
Перевірте панель журналу подій, щоб побачити, чи будь-яка подія тривала довше ніж 15 мс:
![Журнал подій Edge](../../../../translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.uk.png)
✅ Ознайомтеся з вашим профайлером! Відкрийте інструменти розробника на цьому сайті та перевірте, чи є вузькі місця. Який ресурс завантажується найдовше? Найшвидше?
✅ Ознайомтеся з вашим профайлером! Відкрийте інструменти розробника на цьому сайті та перевірте, чи є якісь вузькі місця. Який ресурс завантажується найповільніше? Найшвидше?
## Перевірки профілювання
Загалом, існують деякі "проблемні зони", за якими кожен веброзробник повинен стежити під час створення сайту, щоб уникнути неприємних сюрпризів під час розгортання у продакшн.
Загалом, існують деякі "проблемні зони", які кожен веброзробник повинен враховувати під час створення сайту, щоб уникнути неприємних сюрпризів під час розгортання в продакшн.
**Розміри ресурсів**: За останні кілька років веб став "важчим", а отже, й повільнішим. Частково це пов'язано з використанням зображень.
**Розміри ресурсів**: Веб став "важчим", а отже, повільнішим за останні кілька років. Частина цієї ваги пов'язана з використанням зображень.
✅ Перегляньте [Архів Інтернету](https://httparchive.org/reports/page-weight) для історичного огляду ваги сторінок та іншого.
Хорошою практикою є оптимізація зображень і їх доставка у відповідному розмірі та роздільній здатності для ваших користувачів.
Хорошою практикою є забезпечення оптимізації ваших зображень і їх доставки у правильному розмірі та роздільній здатності для ваших користувачів.
**Перегляд DOM**: Браузер має створити свою модель об'єктів документа (DOM) на основі коду, який ви пишете, тому в інтересах хорошої продуктивності сторінки слід мінімізувати теги, використовуючи та стилізуючи лише те, що потрібно сторінці. Наприклад, надлишкові CSS, пов'язані зі сторінкою, можна оптимізувати; стилі, які потрібні лише на одній сторінці, не потрібно включати до основного стилю.
**Переміщення DOM**: Браузер має побудувати свою модель об'єктів документа (DOM) на основі коду, який ви пишете, тому в інтересах хорошої продуктивності сторінки слід мінімізувати теги, використовуючи та стилізуючи лише те, що потрібно сторінці. Наприклад, надлишковий CSS, пов'язаний зі сторінкою, може бути оптимізований; стилі, які потрібно використовувати лише на одній сторінці, не потрібно включати до основного стилю.
**JavaScript**: Кожен розробник JavaScript повинен стежити за "скриптами, що блокують рендеринг", які мають бути завантажені перед тим, як решта DOM може бути переглянута та відображена у браузері. Розгляньте можливість використання `defer` для ваших вбудованих скриптів (як це зроблено у модулі Terrarium).
**JavaScript**: Кожен розробник JavaScript повинен стежити за скриптами, які блокують рендеринг і мають бути завантажені перед тим, як решта DOM може бути переміщена та намальована в браузері. Розгляньте можливість використання `defer` з вашими вбудованими скриптами (як це зроблено в модулі Terrarium).
✅ Спробуйте кілька сайтів на [вебсайті тестування швидкості сайтів](https://www.webpagetest.org/), щоб дізнатися більше про загальні перевірки, які виконуються для визначення продуктивності сайту.
✅ Спробуйте деякі сайти на [вебсайті тестування швидкості сайту](https://www.webpagetest.org/), щоб дізнатися більше про загальні перевірки, які виконуються для визначення продуктивності сайту.
Тепер, коли ви маєте уявлення про те, як браузер відображає ресурси, які ви йому надсилаєте, давайте розглянемо останні кілька кроків, які потрібно виконати, щоб завершити ваше розширення:
Тепер, коли ви маєте уявлення про те, як браузер рендерить ресурси, які ви йому надсилаєте, давайте розглянемо останні кілька речей, які потрібно зробити, щоб завершити ваше розширення:
### Створіть функцію для обчислення кольору
@ -88,19 +88,19 @@ function calculateColor(value) {
}
```
Що тут відбувається? Ви передаєте значення (інтенсивність вуглецю) з виклику API, який ви завершили на попередньому уроці, а потім обчислюєте, наскільки близьке його значення до індексу, представленого у масиві кольорів. Потім ви надсилаєте це найближче значення кольору до chrome runtime.
Що тут відбувається? Ви передаєте значення (інтенсивність вуглецю) з виклику API, який ви завершили в попередньому уроці, а потім обчислюєте, наскільки близьке його значення до індексу, представленого в масиві кольорів. Потім ви надсилаєте це найближче значення кольору через chrome runtime.
Chrome.runtime має [API](https://developer.chrome.com/extensions/runtime), яке обробляє всі види фонових завдань, і ваше розширення використовує це:
Chrome.runtime має [API](https://developer.chrome.com/extensions/runtime), який обробляє всі види фонових завдань, і ваше розширення використовує його:
> "Використовуйте chrome.runtime API для отримання фонової сторінки, повернення деталей про маніфест і прослуховування та реагування на події у життєвому циклі додатка або розширення. Ви також можете використовувати це API для перетворення відносного шляху URL на повністю кваліфіковані URL."
> "Використовуйте API chrome.runtime, щоб отримати фонову сторінку, повернути деталі про маніфест і слухати та реагувати на події в життєвому циклі програми або розширення. Ви також можете використовувати цей API для перетворення відносного шляху URL-адрес на повністю кваліфіковані URL-адреси."
✅ Якщо ви розробляєте це розширення для Edge, вас може здивувати, що ви використовуєте API Chrome. Новіші версії браузера Edge працюють на рушії браузера Chromium, тому ви можете використовувати ці інструменти.
✅ Якщо ви розробляєте це розширення для Edge, вас може здивувати, що ви використовуєте API Chrome. Новіші версії браузера Edge працюють на браузерному двигуні Chromium, тому ви можете використовувати ці інструменти.
> Зверніть увагу, якщо ви хочете профілювати розширення для браузера, відкрийте інструменти розробника безпосередньо у розширенні, оскільки воно є окремим екземпляром браузера.
> Зверніть увагу, якщо ви хочете профілювати розширення для браузера, запустіть інструменти розробника з самого розширення, оскільки воно є окремим екземпляром браузера.
### Встановіть колір значка за замовчуванням
### Встановіть колір іконки за замовчуванням
Тепер у функції `init()` встановіть значок на універсальний зелений колір, викликавши дію `updateIcon` у Chrome:
Тепер у функції `init()` встановіть іконку на стандартний зелений колір, викликавши дію `updateIcon` Chrome:
```JavaScript
chrome.runtime.sendMessage({
@ -120,7 +120,7 @@ chrome.runtime.sendMessage({
calculateColor(CO2);
```
І нарешті, у файлі `/dist/background.js` додайте слухач для цих викликів фонових дій:
І нарешті, у файлі `/dist/background.js` додайте слухач для цих викликів фонових завдань:
```JavaScript
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
@ -142,19 +142,19 @@ function drawIcon(value) {
}
```
У цьому коді ви додаєте слухач для будь-яких повідомлень, що надходять до менеджера фонових завдань. Якщо це виклик "updateIcon", тоді виконується наступний код для малювання значка відповідного кольору за допомогою Canvas API.
У цьому коді ви додаєте слухач для будь-яких повідомлень, які надходять до менеджера фонових завдань. Якщо його назва — 'updateIcon', тоді виконується наступний код для малювання іконки відповідного кольору за допомогою Canvas API.
✅ Ви дізнаєтеся більше про Canvas API у [уроках про космічну гру](../../6-space-game/2-drawing-to-canvas/README.md).
✅ Ви дізнаєтеся більше про Canvas API в [уроках про космічну гру](../../6-space-game/2-drawing-to-canvas/README.md).
Тепер перебудуйте своє розширення (`npm run build`), оновіть і запустіть його, і спостерігайте за зміною кольору. Час сходити за покупками чи помити посуд? Тепер ви знаєте!
Тепер перебудуйте своє розширення (`npm run build`), оновіть і запустіть його, і спостерігайте за зміною кольору. Чи настав час зробити перерву або помити посуд? Тепер ви знаєте!
Вітаємо, ви створили корисне розширення для браузера та дізналися більше про те, як працює браузер і як профілювати його продуктивність.
Вітаємо, ви створили корисне розширення для браузера і дізналися більше про те, як працює браузер і як профілювати його продуктивність.
---
## 🚀 Виклик
Дослідіть деякі вебсайти з відкритим кодом, які існують вже давно, і, спираючись на їхню історію в GitHub, спробуйте визначити, як вони оптимізувалися з роками для покращення продуктивності, якщо взагалі оптимізувалися. Яка найпоширеніша проблема?
Дослідіть деякі вебсайти з відкритим кодом, які існують вже давно, і, ґрунтуючись на їхній історії в GitHub, спробуйте визначити, як вони оптимізувалися протягом років для продуктивності, якщо взагалі оптимізувалися. Яка найпоширеніша проблема?
## Тест після лекції
@ -164,13 +164,13 @@ function drawIcon(value) {
Розгляньте можливість підписки на [розсилку про продуктивність](https://perf.email/).
Дослідіть деякі способи, якими браузери оцінюють продуктивність вебсайтів, переглянувши вкладки продуктивності у їхніх вебінструментах. Чи знаходите ви якісь суттєві відмінності?
Дослідіть деякі способи, якими браузери оцінюють продуктивність вебсайтів, переглянувши вкладки продуктивності в їхніх вебінструментах. Чи знайшли ви якісь суттєві відмінності?
## Завдання
[Аналізуйте сайт на продуктивність](assignment.md)
[Проаналізуйте сайт на продуктивність](assignment.md)
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, звертаємо вашу увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "d9da6dc61fb712b29f65e108c79b8a5d",
"translation_date": "2025-08-27T22:26:48+00:00",
"original_hash": "979cfcce2413a87d9e4c67eb79234bc3",
"translation_date": "2025-08-28T18:15:44+00:00",
"source_file": "6-space-game/1-introduction/README.md",
"language_code": "uk"
}
@ -15,24 +15,24 @@ CO_OP_TRANSLATOR_METADATA:
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/29)
### Наслідування та композиція в розробці ігор
### Наслідування та композиція у розробці ігор
У попередніх уроках не було великої потреби турбуватися про архітектуру додатків, які ви створювали, оскільки проєкти були невеликими за масштабом. Однак, коли ваші додатки зростають у розмірах і масштабах, архітектурні рішення стають важливішими. Існує два основних підходи до створення великих додатків у JavaScript: *композиція* або *наслідування*. У кожного з них є свої переваги та недоліки, але давайте пояснимо їх у контексті гри.
У попередніх уроках не було великої потреби турбуватися про архітектуру додатків, які ви створювали, оскільки проєкти були невеликими за масштабом. Однак, коли ваші додатки зростають у розмірах і складності, архітектурні рішення стають важливішими. Існує два основних підходи до створення великих додатків у JavaScript: *композиція* або *наслідування*. У кожного з них є свої переваги та недоліки, але давайте розглянемо їх у контексті гри.
✅ Одна з найвідоміших книг про програмування присвячена [шаблонам проєктування](https://en.wikipedia.org/wiki/Design_Patterns).
У грі є `ігрові об'єкти`, які є об'єктами, що існують на екрані. Це означає, що вони мають розташування в декартовій системі координат, яке характеризується наявністю координат `x` і `y`. У процесі розробки гри ви помітите, що всі ваші ігрові об'єкти мають стандартні властивості, спільні для кожної гри, яку ви створюєте, а саме елементи, які є:
У грі є `ігрові об'єкти`, які є об'єктами, що існують на екрані. Це означає, що вони мають розташування в декартовій системі координат, яке характеризується наявністю координат `x` та `y`. У процесі розробки гри ви помітите, що всі ваші ігрові об'єкти мають стандартні властивості, спільні для кожної гри, яку ви створюєте, а саме елементи, які є:
- **залежними від розташування** Більшість, якщо не всі, ігрові елементи залежать від розташування. Це означає, що вони мають розташування, `x` і `y`.
- **залежними від розташування** Більшість, якщо не всі, ігрові елементи залежать від розташування. Це означає, що вони мають координати `x` та `y`.
- **рухомими** Це об'єкти, які можуть переміщатися в нове місце. Зазвичай це герой, монстр або NPC (персонаж, яким не керує гравець), але не, наприклад, статичний об'єкт, як дерево.
- **самознищуваними** Ці об'єкти існують лише протягом певного періоду часу, після чого вони готуються до видалення. Зазвичай це представлено булевою змінною `dead` або `destroyed`, яка сигналізує ігровому двигуну, що цей об'єкт більше не потрібно відображати.
- **з затримкою** 'Затримка' — це типова властивість короткочасних об'єктів. Типовий приклад — це текст або графічний ефект, як вибух, який має бути видимим лише кілька мілісекунд.
- **з затримкою** 'Затримка' — це типова властивість короткотривалих об'єктів. Типовий приклад — це текст або графічний ефект, як вибух, який має бути видимим лише кілька мілісекунд.
✅ Подумайте про гру, як Pac-Man. Чи можете ви визначити чотири типи об'єктів, описаних вище, у цій грі?
✅ Подумайте про гру, як-от Pac-Man. Чи можете ви визначити чотири типи об'єктів, описаних вище, у цій грі?
### Вираження поведінки
Все, що ми описали вище, — це поведінка, яку можуть мати ігрові об'єкти. Як же ми можемо закодувати це? Ми можемо виразити цю поведінку як методи, пов'язані з класами або об'єктами.
Все, що ми описали вище, — це поведінка, яку можуть мати ігрові об'єкти. Як же її закодувати? Ми можемо виразити цю поведінку як методи, пов'язані з класами або об'єктами.
**Класи**
@ -88,11 +88,11 @@ hero.moveTo(5,5);
const tree = new Tree();
```
✅ Приділіть кілька хвилин, щоб переосмислити героя Pac-Man (наприклад, Inky, Pinky або Blinky) і як його можна було б написати на JavaScript.
✅ Приділіть кілька хвилин, щоб уявити героя Pac-Man (наприклад, Inky, Pinky або Blinky) і як його можна було б написати на JavaScript.
**Композиція**
Інший спосіб обробки наслідування об'єктів — використання *композиції*. Тоді об'єкти виражають свою поведінку таким чином:
Інший спосіб обробки наслідування об'єктів — використання *композиції*. Тоді об'єкти виражають свою поведінку так:
```javascript
//create a constant gameObject
@ -145,17 +145,17 @@ const tree = createStatic(0,0, 'Tree');
Ще один шаблон, поширений у розробці ігор, вирішує проблему управління користувацьким досвідом гри та її продуктивністю.
## Шаблон Pub/Sub
## Шаблон Pub/sub
✅ Pub/Sub означає 'publish-subscribe' (публікація-підписка)
Цей шаблон вирішує ідею, що різні частини вашого додатка не повинні знати одна про одну. Чому це важливо? Це значно спрощує загальне розуміння того, що відбувається, якщо різні частини розділені. Це також полегшує раптову зміну поведінки, якщо це необхідно. Як ми можемо це реалізувати? Ми встановлюємо кілька концепцій:
Цей шаблон вирішує ідею, що різні частини вашого додатка не повинні знати одна про одну. Чому це важливо? Це значно спрощує розуміння загальної картини, якщо різні частини відокремлені. Це також полегшує раптову зміну поведінки, якщо це необхідно. Як це реалізувати? Ми робимо це, встановлюючи кілька концепцій:
- **повідомлення**: Повідомлення зазвичай є текстовим рядком, доповненим необов'язковим корисним навантаженням (частиною даних, яка уточнює, про що йдеться у повідомленні). Типове повідомлення в грі може бути `KEY_PRESSED_ENTER`.
- **видавець**: Цей елемент *публікує* повідомлення і надсилає його всім підписникам.
- **підписник**: Цей елемент *слухає* конкретні повідомлення і виконує певне завдання в результаті отримання цього повідомлення, наприклад, стріляє лазером.
- **видавець**: Цей елемент *публікує* повідомлення та надсилає його всім підписникам.
- **підписник**: Цей елемент *слухає* конкретні повідомлення та виконує певне завдання в результаті отримання цього повідомлення, наприклад, стріляє лазером.
Реалізація досить невелика за розміром, але це дуже потужний шаблон. Ось як його можна реалізувати:
Реалізація досить компактна, але це дуже потужний шаблон. Ось як його можна реалізувати:
```javascript
//set up an EventEmitter class that contains listeners
@ -204,7 +204,7 @@ window.addEventListener('keyup', (evt) => {
});
```
У наведеному вище прикладі ми підключаємо подію клавіатури, `ArrowLeft`, і надсилаємо повідомлення `HERO_MOVE_LEFT`. Ми слухаємо це повідомлення і переміщуємо `hero` як результат. Сила цього шаблону полягає в тому, що слухач подій і герой не знають один про одного. Ви можете переназначити `ArrowLeft` на клавішу `A`. Крім того, можна зробити щось зовсім інше на `ArrowLeft`, зробивши кілька змін у функції `on` об'єкта eventEmitter:
У наведеному вище прикладі ми підключаємо подію клавіатури `ArrowLeft` і надсилаємо повідомлення `HERO_MOVE_LEFT`. Ми слухаємо це повідомлення та переміщуємо `hero` як результат. Сила цього шаблону полягає в тому, що обробник подій і герой не знають один про одного. Ви можете переназначити `ArrowLeft` на клавішу `A`. Крім того, можна зробити щось зовсім інше на `ArrowLeft`, внісши кілька змін до функції `on` об'єкта eventEmitter:
```javascript
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
@ -218,7 +218,7 @@ eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
## 🚀 Виклик
Подумайте, як шаблон pub-sub може покращити гру. Які частини повинні надсилати події, і як гра повинна на них реагувати? Зараз у вас є шанс проявити творчість, придумуючи нову гру і те, як її частини можуть поводитися.
Подумайте, як шаблон pub-sub може покращити гру. Які частини повинні надсилати події, і як гра повинна на них реагувати? Зараз у вас є шанс проявити творчість, придумуючи нову гру та те, як її частини можуть поводитися.
## Тест після лекції

@ -1,21 +1,21 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "41be8d35e7f30aa9dad10773c35e89c4",
"translation_date": "2025-08-27T22:24:08+00:00",
"original_hash": "056641280211e52fd0adb81b6058ec55",
"translation_date": "2025-08-28T18:15:01+00:00",
"source_file": "6-space-game/2-drawing-to-canvas/README.md",
"language_code": "uk"
}
-->
# Створення космічної гри, частина 2: Малюємо героя та монстрів на Canvas
## Передлекційний тест
## Тест перед лекцією
[Передлекційний тест](https://ff-quizzes.netlify.app/web/quiz/31)
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/31)
## Canvas
Canvas — це HTML-елемент, який за замовчуванням не має вмісту; це чистий аркуш. Ви повинні додати до нього вміст, малюючи на ньому.
Canvas — це HTML-елемент, який за замовчуванням не має вмісту; це чистий аркуш. Ви повинні додати до нього елементи, малюючи на ньому.
✅ Прочитайте [більше про Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) на MDN.
@ -25,24 +25,24 @@ Canvas — це HTML-елемент, який за замовчуванням н
<canvas id="myCanvas" width="200" height="100"></canvas>
```
У наведеному вище прикладі ми встановлюємо `id`, `width` і `height`.
Вищезазначений код встановлює `id`, `width` і `height`.
- `id`: задайте це, щоб отримати посилання, коли вам потрібно буде взаємодіяти з елементом.
- `id`: встановіть це, щоб отримати посилання, коли вам потрібно взаємодіяти з елементом.
- `width`: це ширина елемента.
- `height`: це висота елемента.
## Малювання простих геометричних фігур
Canvas використовує декартову систему координат для малювання. Таким чином, він використовує осі x та y для визначення розташування об'єктів. Точка `0,0` знаходиться у верхньому лівому куті, а нижній правий кут відповідає значенням WIDTH і HEIGHT Canvas.
Canvas використовує декартову систему координат для малювання. Таким чином, він використовує осі x і y для визначення місця розташування об'єкта. Точка `0,0` — це верхній лівий кут, а нижній правий кут відповідає значенням WIDTH і HEIGHT Canvas.
![сітка Canvas](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.uk.png)
![сітка Canvas](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.uk.png)
> Зображення з [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes)
Щоб малювати на Canvas, потрібно виконати наступні кроки:
Щоб малювати на елементі Canvas, потрібно виконати наступні кроки:
1. **Отримати посилання** на елемент Canvas.
2. **Отримати посилання** на елемент Context, який знаходиться на Canvas.
3. **Виконати операцію малювання** за допомогою елемента Context.
1. **Отримати посилання** на елемент Context, який знаходиться на Canvas.
1. **Виконати операцію малювання** за допомогою елемента Context.
Код для виконання цих кроків зазвичай виглядає так:
@ -61,19 +61,19 @@ ctx.fillStyle = 'red';
ctx.fillRect(0,0, 200, 200) // x,y,width, height
```
✅ Canvas API здебільшого зосереджений на 2D-фігурах, але ви також можете малювати 3D-елементи на вебсайті; для цього можна використовувати [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API).
✅ Canvas API здебільшого зосереджений на 2D-фігурах, але ви також можете малювати 3D-елементи на веб-сторінці; для цього можна використовувати [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API).
За допомогою Canvas API можна малювати різноманітні речі, наприклад:
За допомогою Canvas API можна малювати різні елементи, такі як:
- **Геометричні фігури**: ми вже показали, як намалювати прямокутник, але є ще багато іншого, що можна намалювати.
- **Текст**: ви можете малювати текст із будь-яким шрифтом і кольором.
- **Зображення**: ви можете малювати зображення на основі ресурсів, таких як .jpg або .png.
- **Геометричні фігури**. Ми вже показали, як намалювати прямокутник, але є багато інших форм, які можна створити.
- **Текст**. Ви можете малювати текст із будь-яким шрифтом і кольором.
- **Зображення**. Ви можете малювати зображення на основі графічних файлів, таких як .jpg або .png.
✅ Спробуйте! Ви вже знаєте, як намалювати прямокутник, чи зможете ви намалювати коло на сторінці? Подивіться на цікаві приклади малюнків Canvas на CodePen. Ось [особливо вражаючий приклад](https://codepen.io/dissimulate/pen/KrAwx).
✅ Спробуйте! Ви знаєте, як намалювати прямокутник, чи можете ви намалювати коло на сторінці? Подивіться на цікаві приклади малюнків Canvas на CodePen. Ось [особливо вражаючий приклад](https://codepen.io/dissimulate/pen/KrAwx).
## Завантаження та малювання зображень
## Завантаження та малювання графічного ресурсу
Щоб завантажити зображення, потрібно створити об'єкт `Image` і встановити його властивість `src`. Потім потрібно прослухати подію `load`, щоб дізнатися, коли зображення готове до використання. Код виглядає так:
Щоб завантажити графічний ресурс, потрібно створити об'єкт `Image` і встановити його властивість `src`. Потім потрібно слухати подію `load`, щоб дізнатися, коли зображення готове до використання. Код виглядає так:
### Завантаження ресурсу
@ -87,7 +87,7 @@ img.onload = () => {
### Шаблон завантаження ресурсу
Рекомендується обгорнути наведений вище код у конструкцію, щоб його було легше використовувати, і ви могли маніпулювати зображенням лише тоді, коли воно повністю завантажене:
Рекомендується обгорнути вищезазначений код у конструкцію, як показано нижче, щоб було легше використовувати ресурс і маніпулювати ним лише тоді, коли він повністю завантажений:
```javascript
function loadAsset(path) {
@ -128,7 +128,7 @@ async function run() {
### Що створювати
Ви створите вебсторінку з елементом Canvas. Вона повинна відображати чорний екран розміром `1024*768`. Ми надали вам два зображення:
Ви створите веб-сторінку з елементом Canvas. Вона повинна відображати чорний екран розміром `1024*768`. Ми надали вам два зображення:
- Корабель героя
@ -151,7 +151,7 @@ async function run() {
-| package.json
```
Відкрийте копію цієї папки у Visual Studio Code. Вам потрібно налаштувати локальне середовище розробки, бажано з Visual Studio Code, NPM і Node. Якщо у вас не налаштований `npm` на комп'ютері, [ось як це зробити](https://www.npmjs.com/get-npm).
Відкрийте копію цієї папки у Visual Studio Code. Вам потрібно налаштувати локальне середовище розробки, бажано з Visual Studio Code, NPM і Node. Якщо у вас не встановлено `npm`, [ось як це зробити](https://www.npmjs.com/get-npm).
Розпочніть ваш проєкт, перейшовши до папки `your_work`:
@ -160,7 +160,7 @@ cd your-work
npm start
```
Це запустить HTTP-сервер за адресою `http://localhost:5000`. Відкрийте браузер і введіть цю адресу. Зараз це порожня сторінка, але це зміниться.
Вищезазначений код запустить HTTP-сервер за адресою `http://localhost:5000`. Відкрийте браузер і введіть цю адресу. Зараз це порожня сторінка, але це зміниться.
> Примітка: щоб побачити зміни на екрані, оновіть браузер.
@ -168,16 +168,16 @@ npm start
Додайте необхідний код до `your-work/app.js`, щоб виконати наступне:
1. **Намалюйте** Canvas із чорним фоном
> Порада: додайте два рядки під відповідним TODO у `/app.js`, встановивши елемент `ctx` чорним, а верхні/ліві координати — 0,0, а висоту та ширину — рівними Canvas.
2. **Завантажте** текстури
> Порада: додайте зображення гравця та ворога, використовуючи `await loadTexture` і передаючи шлях до зображення. Ви поки що не побачите їх на екрані!
3. **Намалюйте** героя в центрі екрана в нижній половині
1. **Намалюйте** Canvas із чорним фоном.
> Порада: додайте два рядки під відповідним TODO у `/app.js`, встановивши елемент `ctx` чорним, а верхні/ліві координати — 0,0, а висоту та ширину — рівними розмірам Canvas.
2. **Завантажте** текстури.
> Порада: додайте зображення гравця та ворога, використовуючи `await loadTexture` і передаючи шлях до зображення. Ви поки не побачите їх на екрані!
3. **Намалюйте** героя в центрі екрана в нижній половині.
> Порада: використовуйте API `drawImage`, щоб намалювати heroImg на екрані, встановивши `canvas.width / 2 - 45` і `canvas.height - canvas.height / 4)`.
4. **Намалюйте** 5*5 монстрів
> Порада: тепер ви можете розкоментувати код для малювання ворогів на екрані. Далі перейдіть до функції `createEnemies` і реалізуйте її.
4. **Намалюйте** 5*5 монстрів.
> Порада: тепер ви можете розкоментувати код для малювання ворогів на екрані. Далі перейдіть до функції `createEnemies` і розробіть її.
Спочатку задайте кілька констант:
Спочатку налаштуйте кілька констант:
```javascript
const MONSTER_TOTAL = 5;
@ -186,7 +186,7 @@ npm start
const STOP_X = START_X + MONSTER_WIDTH;
```
Потім створіть цикл для малювання масиву монстрів на екрані:
потім створіть цикл для малювання масиву монстрів на екрані:
```javascript
for (let x = START_X; x < STOP_X; x += 98) {
@ -200,11 +200,11 @@ npm start
Готовий результат повинен виглядати так:
![Чорний екран із героєм і 5*5 монстрами](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.uk.png)
![Чорний екран із героєм та 5*5 монстрами](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.uk.png)
## Рішення
Спробуйте вирішити завдання самостійно, але якщо у вас виникнуть труднощі, перегляньте [рішення](../../../../6-space-game/2-drawing-to-canvas/solution/app.js).
Спробуйте вирішити завдання самостійно, але якщо ви застрягли, перегляньте [рішення](../../../../6-space-game/2-drawing-to-canvas/solution/app.js).
---
@ -212,9 +212,9 @@ npm start
Ви дізналися про малювання за допомогою Canvas API, орієнтованого на 2D; ознайомтеся з [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) і спробуйте намалювати 3D-об'єкт.
## Післялекційний тест
## Тест після лекції
[Післялекційний тест](https://ff-quizzes.netlify.app/web/quiz/32)
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/32)
## Огляд і самостійне навчання

@ -1,30 +1,30 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "23f088add24f0f1fa51014a9e27ea280",
"translation_date": "2025-08-27T22:19:29+00:00",
"original_hash": "a9a161871de7706cb0e23b1bd0c74559",
"translation_date": "2025-08-28T18:13:28+00:00",
"source_file": "6-space-game/3-moving-elements-around/README.md",
"language_code": "uk"
}
-->
# Створення космічної гри, частина 3: Додавання руху
## Тест перед лекцією
## Передлекційна вікторина
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/33)
[Передлекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/33)
Ігри стають цікавішими, коли на екрані з'являються інопланетяни! У цій грі ми використаємо два типи руху:
Ігри стають цікавими, коли на екрані починають рухатися прибульці! У цій грі ми використаємо два типи руху:
- **Рух за допомогою клавіатури/миші**: коли користувач взаємодіє з клавіатурою або мишею для переміщення об'єкта на екрані.
- **Рух за допомогою клавіатури/миші**: коли користувач взаємодіє з клавіатурою або мишею, щоб перемістити об'єкт на екрані.
- **Рух, викликаний грою**: коли гра переміщує об'єкт через певний інтервал часу.
Отже, як ми можемо переміщувати об'єкти на екрані? Все залежить від декартових координат: ми змінюємо місцезнаходження (x, y) об'єкта, а потім перерисовуємо екран.
Отже, як ми можемо переміщувати об'єкти на екрані? Все зводиться до декартових координат: ми змінюємо розташування (x, y) об'єкта, а потім перемальовуємо екран.
Зазвичай для реалізації *руху* на екрані потрібні наступні кроки:
Зазвичай для реалізації *руху* на екрані потрібні такі кроки:
1. **Встановити нове місцезнаходження** для об'єкта; це необхідно, щоб створити враження, що об'єкт перемістився.
2. **Очистити екран**, екран потрібно очищати між перерисовками. Ми можемо очистити його, намалювавши прямокутник, заповнений кольором фону.
3. **Перерисувати об'єкт** у новому місцезнаходженні. Таким чином ми досягаємо переміщення об'єкта з одного місця в інше.
1. **Встановити нове розташування** об'єкта; це необхідно, щоб створити враження, що об'єкт перемістився.
2. **Очистити екран**, оскільки екран потрібно очищати між малюваннями. Ми можемо очистити його, намалювавши прямокутник із фоновим кольором.
3. **Перемалювати об'єкт** у новому розташуванні. Таким чином ми досягаємо переміщення об'єкта з одного місця в інше.
Ось як це може виглядати в коді:
@ -39,13 +39,13 @@ ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
```
✅ Чи можете ви придумати причину, чому перерисовка вашого героя багато кадрів на секунду може призводити до витрат продуктивності? Прочитайте про [альтернативи цьому підходу](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
✅ Чи можете ви придумати причину, чому перемальовування вашого героя багато разів на секунду може призводити до витрат продуктивності? Прочитайте про [альтернативи цьому підходу](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
## Обробка подій клавіатури
Ви обробляєте події, прив'язуючи конкретні події до коду. Події клавіатури викликаються для всього вікна, тоді як події миші, наприклад `click`, можуть бути прив'язані до натискання на конкретний елемент. Ми будемо використовувати події клавіатури протягом цього проєкту.
Події обробляються шляхом прив'язки певних подій до коду. Події клавіатури викликаються для всього вікна, тоді як події миші, наприклад `click`, можуть бути прив'язані до натискання на конкретний елемент. У цьому проєкті ми будемо використовувати події клавіатури.
Для обробки події потрібно використати метод `addEventListener()` вікна і надати йому два параметри. Перший параметр — це назва події, наприклад `keyup`. Другий параметр — це функція, яка має бути викликана в результаті виникнення події.
Щоб обробити подію, потрібно використати метод `addEventListener()` вікна і передати йому два параметри. Перший параметр — це назва події, наприклад `keyup`. Другий параметр — це функція, яка має бути викликана в результаті події.
Ось приклад:
@ -58,16 +58,16 @@ window.addEventListener('keyup', (evt) => {
})
```
Для подій клавіш є дві властивості події, які можна використовувати, щоб дізнатися, яка клавіша була натиснута:
Для подій клавіатури є дві властивості події, які можна використовувати, щоб дізнатися, яка клавіша була натиснута:
- `key` — це текстове представлення натиснутої клавіші, наприклад `ArrowUp`.
- `key` — це рядкове представлення натиснутої клавіші, наприклад `ArrowUp`.
- `keyCode` — це числове представлення, наприклад `37`, що відповідає `ArrowLeft`.
✅ Маніпуляція подіями клавіш корисна не лише для розробки ігор. Які ще застосування цього підходу ви можете придумати?
✅ Маніпуляція подіями клавіатури корисна не лише в розробці ігор. Які ще застосування цього підходу ви можете придумати?
### Спеціальні клавіші: застереження
Є деякі *спеціальні* клавіші, які впливають на вікно. Це означає, що якщо ви слухаєте подію `keyup` і використовуєте ці спеціальні клавіші для переміщення вашого героя, це також викличе горизонтальне прокручування. З цієї причини ви можете захотіти *вимкнути* цю вбудовану поведінку браузера під час створення вашої гри. Вам потрібен код, як цей:
Деякі *спеціальні* клавіші впливають на вікно. Це означає, що якщо ви слухаєте подію `keyup` і використовуєте ці спеціальні клавіші для переміщення героя, це також викликатиме горизонтальну прокрутку. З цієї причини ви можете захотіти *вимкнути* цю вбудовану поведінку браузера під час створення гри. Для цього потрібен такий код:
```javascript
let onKeyDown = function (e) {
@ -88,11 +88,11 @@ let onKeyDown = function (e) {
window.addEventListener('keydown', onKeyDown);
```
Вищезазначений код забезпечить вимкнення *за замовчуванням* поведінки для клавіш зі стрілками та пробілу. Механізм *вимкнення* відбувається, коли ми викликаємо `e.preventDefault()`.
Цей код забезпечить вимкнення *за замовчуванням* поведінки для клавіш зі стрілками та пробілу. Механізм *вимкнення* спрацьовує, коли ми викликаємо `e.preventDefault()`.
## Рух, викликаний грою
Ми можемо змусити об'єкти рухатися самостійно, використовуючи таймери, такі як функції `setTimeout()` або `setInterval()`, які оновлюють місцезнаходження об'єкта на кожному такті або інтервалі часу. Ось як це може виглядати:
Ми можемо змусити об'єкти рухатися самостійно, використовуючи таймери, такі як функції `setTimeout()` або `setInterval()`, які оновлюють розташування об'єкта на кожному такті або інтервалі часу. Ось як це може виглядати:
```javascript
let id = setInterval(() => {
@ -119,18 +119,18 @@ let gameLoopId = setInterval(() =>
}, 200);
```
Вищезазначений цикл викликається кожні `200` мілісекунд для перерисовки полотна. Ви можете вибрати найкращий інтервал, який має сенс для вашої гри.
Цей цикл викликається кожні `200` мілісекунд для перемальовування полотна. Ви можете вибрати інтервал, який найкраще підходить для вашої гри.
## Продовження космічної гри
Ви візьмете існуючий код і розширите його. Або почніть з коду, який ви завершили під час частини I, або використовуйте код із [частини II - стартовий](../../../../6-space-game/3-moving-elements-around/your-work).
Ви візьмете існуючий код і розширите його. Або почніть із коду, який ви завершили в частині I, або використовуйте код із [Part II- starter](../../../../6-space-game/3-moving-elements-around/your-work).
- **Рух героя**: ви додасте код, щоб забезпечити можливість переміщення героя за допомогою клавіш зі стрілками.
- **Рух ворогів**: вам також потрібно буде додати код, щоб забезпечити рух ворогів зверху вниз із заданою швидкістю.
- **Рух ворогів**: вам також потрібно буде додати код, щоб вороги рухалися зверху вниз із заданою швидкістю.
## Рекомендовані кроки
Знайдіть файли, які були створені для вас у підпапці `your-work`. Вона повинна містити наступне:
Знайдіть файли, які були створені для вас у підпапці `your-work`. Вона має містити наступне:
```bash
-| assets
@ -141,20 +141,20 @@ let gameLoopId = setInterval(() =>
-| package.json
```
Ви починаєте свій проєкт у папці `your_work`, ввівши:
Запустіть ваш проєкт у папці `your_work`, ввівши:
```bash
cd your-work
npm start
```
Вищезазначене запустить HTTP-сервер за адресою `http://localhost:5000`. Відкрийте браузер і введіть цю адресу, зараз він повинен відобразити героя та всіх ворогів; поки що нічого не рухається!
Це запустить HTTP-сервер за адресою `http://localhost:5000`. Відкрийте браузер і введіть цю адресу. Зараз має відображатися герой і всі вороги; поки що нічого не рухається!
### Додайте код
1. **Додайте спеціальні об'єкти** для `hero`, `enemy` та `game object`, вони повинні мати властивості `x` та `y`. (Згадайте розділ про [Спадкування або композицію](../README.md)).
1. **Додайте окремі об'єкти** для `hero`, `enemy` і `game object`, які повинні мати властивості `x` і `y`. (Згадайте розділ про [Спадкування або композицію](../README.md)).
*ПІДКАЗКА*: `game object` має бути тим, що має `x` та `y` і здатність малювати себе на полотні.
*ПІДКАЗКА*: `game object` має бути тим, що має `x` і `y`, а також здатність малювати себе на полотні.
>порада: почніть із додавання нового класу GameObject із його конструктором, як показано нижче, а потім намалюйте його на полотні:
@ -177,7 +177,7 @@ npm start
}
```
Тепер розширте цей GameObject, щоб створити Hero та Enemy.
Тепер розширте цей GameObject, щоб створити Hero і Enemy.
```javascript
class Hero extends GameObject {
@ -205,9 +205,9 @@ npm start
}
```
2. **Додайте обробники подій клавіш** для обробки навігації клавішами (переміщення героя вгору/вниз, вліво/вправо).
2. **Додайте обробники подій клавіш**, щоб обробляти навігацію клавішами (переміщення героя вгору/вниз, вліво/вправо).
*ПАМ'ЯТАЙТЕ*: це декартова система, верхній лівий кут — `0,0`. Також не забудьте додати код для зупинки *поведінки за замовчуванням*.
*ПАМ'ЯТАЙТЕ*: це декартова система, верхній лівий кут — це `0,0`. Також не забудьте додати код для зупинки *поведінки за замовчуванням*.
>порада: створіть свою функцію onKeyDown і прив'яжіть її до вікна:
@ -221,13 +221,13 @@ npm start
window.addEventListener("keydown", onKeyDown);
```
Перевірте консоль вашого браузера на цьому етапі та спостерігайте за реєстрацією натискань клавіш.
Перевірте консоль браузера на цьому етапі та спостерігайте за реєстрацією натискань клавіш.
3. **Реалізуйте** [патерн Pub-Sub](../README.md), це допоможе зберегти ваш код чистим, коли ви будете виконувати наступні частини.
3. **Реалізуйте** [Шаблон публікації-підписки](../README.md), щоб ваш код залишався чистим у міру виконання наступних частин.
Для виконання цього останнього пункту ви можете:
Для цього останнього кроку ви можете:
1. **Додати слухач подій** у вікно:
1. **Додати слухача подій** у вікно:
```javascript
window.addEventListener("keyup", (evt) => {
@ -311,9 +311,9 @@ npm start
}
```
1. **Налаштувати ігровий цикл**
1. **Налаштуйте ігровий цикл**
Переробіть функцію window.onload, щоб ініціалізувати гру та налаштувати ігровий цикл із хорошим інтервалом. Ви також додасте лазерний промінь:
Рефакторизуйте функцію window.onload, щоб ініціалізувати гру та налаштувати ігровий цикл із відповідним інтервалом. Ви також додасте лазерний промінь:
```javascript
window.onload = async () => {
@ -334,9 +334,9 @@ npm start
};
```
5. **Додайте код** для переміщення ворогів через певний інтервал
5. **Додайте код** для руху ворогів із певним інтервалом
Переробіть функцію `createEnemies()`, щоб створити ворогів і додати їх до нового класу gameObjects:
Рефакторизуйте функцію `createEnemies()`, щоб створити ворогів і додати їх до нового класу gameObjects:
```javascript
function createEnemies() {
@ -376,27 +376,27 @@ npm start
}
```
Ваші вороги повинні почати наступати на ваш космічний корабель героя!
Ваші вороги мають почати наступати на ваш космічний корабель героя!
---
## 🚀 Виклик
Як ви бачите, ваш код може перетворитися на "спагетті-код", коли ви починаєте додавати функції, змінні та класи. Як ви можете краще організувати свій код, щоб він був більш читабельним? Накресліть систему для організації вашого коду, навіть якщо він все ще знаходиться в одному файлі.
Як ви бачите, ваш код може перетворитися на "спагеті-код", коли ви починаєте додавати функції, змінні та класи. Як ви можете краще організувати свій код, щоб він був більш читабельним? Накресліть систему для організації вашого коду, навіть якщо він все ще знаходиться в одному файлі.
## Тест після лекції
## Післялекційна вікторина
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/34)
[Післялекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/34)
## Огляд і самостійне навчання
Хоча ми пишемо нашу гру без використання фреймворків, існує багато фреймворків на основі JavaScript для розробки ігор на полотні. Приділіть час для [читання про них](https://github.com/collections/javascript-game-engines).
Хоча ми пишемо нашу гру без використання фреймворків, існує багато фреймворків на основі JavaScript для розробки ігор із використанням canvas. Приділіть час для [ознайомлення з ними](https://github.com/collections/javascript-game-engines).
## Завдання
[Коментуйте ваш код](assignment.md)
[Коментуйте свій код](assignment.md)
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, зверніть увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2e83e38c35dc003f046d7cc0bbfd4920",
"translation_date": "2025-08-27T22:22:15+00:00",
"original_hash": "a6ce295ff03bb49df7a3e17e6e7100a0",
"translation_date": "2025-08-28T18:14:25+00:00",
"source_file": "6-space-game/4-collision-detection/README.md",
"language_code": "uk"
}
@ -13,16 +13,16 @@ CO_OP_TRANSLATOR_METADATA:
[Передлекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/35)
У цьому уроці ви навчитеся стріляти лазерами за допомогою JavaScript! Ми додамо до нашої гри дві речі:
У цьому уроці ви навчитеся стріляти лазерами за допомогою JavaScript! Ми додамо дві речі до нашої гри:
- **Лазер**: цей лазер стріляє з корабля героя вертикально вгору.
- **Виявлення зіткнень**: у рамках реалізації можливості *стріляти* ми також додамо кілька цікавих правил гри:
- **Лазер**: цей лазер випускається з корабля героя і рухається вертикально вгору.
- **Виявлення зіткнень**: як частина реалізації можливості *стріляти*, ми також додамо кілька цікавих правил гри:
- **Лазер влучає в ворога**: ворог знищується, якщо його вразив лазер.
- **Лазер досягає верхньої частини екрану**: лазер знищується, якщо досягає верхньої частини екрану.
- **Зіткнення ворога та героя**: ворог і герой знищуються, якщо стикаються.
- **Лазер досягає верхньої частини екрану**: лазер знищується, якщо він досягає верхньої частини екрану.
- **Зіткнення ворога і героя**: ворог і герой знищуються, якщо вони стикаються.
- **Ворог досягає нижньої частини екрану**: ворог і герой знищуються, якщо ворог досягає нижньої частини екрану.
Коротко кажучи, ви — *герой* — повинні вразити всіх ворогів лазером, перш ніж вони досягнуть нижньої частини екрану.
Коротко кажучи, ви — *герой* — повинні знищити всіх ворогів лазером, перш ніж вони зможуть дістатися до нижньої частини екрану.
✅ Проведіть невелике дослідження про першу комп'ютерну гру, яка була створена. Яка була її функціональність?
@ -30,9 +30,9 @@ CO_OP_TRANSLATOR_METADATA:
## Виявлення зіткнень
Як ми можемо виявляти зіткнення? Нам потрібно уявляти наші ігрові об'єкти як прямокутники, що рухаються. Чому саме так? Тому що зображення, яке використовується для відображення ігрового об'єкта, є прямокутником: воно має `x`, `y`, `width` і `height`.
Як ми можемо виявляти зіткнення? Нам потрібно уявити наші ігрові об'єкти як прямокутники, що рухаються. Чому саме так? Тому що зображення, яке використовується для відображення ігрового об'єкта, є прямокутником: воно має `x`, `y`, `width` і `height`.
Якщо два прямокутники, наприклад, герой і ворог, *перетинаються*, це означає зіткнення. Що має відбутися далі, залежить від правил гри. Для реалізації виявлення зіткнень вам потрібно наступне:
Якщо два прямокутники, наприклад, герой і ворог, *перетинаються*, це означає зіткнення. Що має статися далі, залежить від правил гри. Для реалізації виявлення зіткнень вам потрібно наступне:
1. Спосіб отримати прямокутне представлення ігрового об'єкта, щось на кшталт цього:
@ -60,14 +60,14 @@ CO_OP_TRANSLATOR_METADATA:
## Як знищувати об'єкти
Щоб знищити об'єкт у грі, потрібно повідомити грі, що цей об'єкт більше не потрібно відображати в ігровому циклі, який викликається через певний інтервал. Один із способів зробити це — позначити ігровий об'єкт як *мертвий*, коли щось відбувається, наприклад:
Щоб знищити об'єкт у грі, потрібно повідомити грі, що цей об'єкт більше не потрібно відображати в ігровому циклі, який запускається через певний інтервал. Один зі способів зробити це — позначити ігровий об'єкт як *мертвий*, коли щось трапляється, наприклад:
```javascript
// collision happened
enemy.dead = true
```
Потім можна видалити *мертві* об'єкти перед повторним відображенням екрану, наприклад:
Потім можна видалити *мертві* об'єкти перед перерисовкою екрану, наприклад:
```javascript
gameObjects = gameObject.filter(go => !go.dead);
@ -83,7 +83,7 @@ gameObjects = gameObject.filter(go => !go.dead);
## Затримка для лазера
Лазер повинен стріляти щоразу, коли ви натискаєте клавішу, наприклад, *пробіл*. Щоб запобігти створенню занадто великої кількості лазерів за короткий час, потрібно це виправити. Виправлення полягає у впровадженні так званої *затримки* — таймера, який гарантує, що лазер можна стріляти лише через певний інтервал. Це можна реалізувати наступним чином:
Лазер має стріляти кожного разу, коли ви натискаєте клавішу, наприклад, *пробіл*. Щоб запобігти створенню занадто великої кількості лазерів за короткий час, потрібно це виправити. Виправлення полягає у впровадженні так званої *затримки* — таймера, який забезпечує, що лазер може стріляти лише через певний інтервал часу. Це можна реалізувати наступним чином:
```javascript
class Cooldown {
@ -109,23 +109,23 @@ class Weapon {
}
```
Перегляньте урок 1 із серії про космічну гру, щоб нагадати собі про *затримки*.
Зверніться до уроку 1 у серії про космічну гру, щоб нагадати собі про *затримки*.
## Що створити
## Що потрібно створити
Ви візьмете існуючий код (який ви повинні були очистити та рефакторити) з попереднього уроку та розширите його. Або почніть із коду з частини II, або використовуйте код із [Part III- starter](../../../../../../../../../your-work).
Ви візьмете існуючий код (який ви мали очистити та рефакторити) з попереднього уроку та розширите його. Або почніть з коду з частини II, або використовуйте код із [Part III- starter](../../../../../../../../../your-work).
> підказка: лазер, з яким ви працюватимете, вже знаходиться у вашій папці з ресурсами та підключений до вашого коду.
- **Додайте виявлення зіткнень**, коли лазер стикається з чимось, повинні застосовуватися наступні правила:
- **Додайте виявлення зіткнень**, коли лазер стикається з чимось, мають застосовуватися наступні правила:
1. **Лазер влучає в ворога**: ворог знищується, якщо його вразив лазер.
2. **Лазер досягає верхньої частини екрану**: лазер знищується, якщо досягає верхньої частини екрану.
3. **Зіткнення ворога та героя**: ворог і герой знищуються, якщо стикаються.
2. **Лазер досягає верхньої частини екрану**: лазер знищується, якщо він досягає верхньої частини екрану.
3. **Зіткнення ворога і героя**: ворог і герой знищуються, якщо вони стикаються.
4. **Ворог досягає нижньої частини екрану**: ворог і герой знищуються, якщо ворог досягає нижньої частини екрану.
## Рекомендовані кроки
Знайдіть файли, які були створені для вас у підпапці `your-work`. Вона повинна містити наступне:
Знайдіть файли, які були створені для вас у підпапці `your-work`. Вона має містити наступне:
```bash
-| assets
@ -144,7 +144,7 @@ cd your-work
npm start
```
Це запустить HTTP-сервер за адресою `http://localhost:5000`. Відкрийте браузер і введіть цю адресу, зараз він повинен відображати героя та всіх ворогів, але нічого ще не рухається :).
Це запустить HTTP-сервер за адресою `http://localhost:5000`. Відкрийте браузер і введіть цю адресу, зараз він має відображати героя та всіх ворогів, але нічого ще не рухається :).
### Додайте код
@ -161,7 +161,7 @@ npm start
}
```
2. **Додайте код, який перевіряє зіткнення**. Це буде нова функція, яка перевіряє, чи перетинаються два прямокутники:
2. **Додайте код для перевірки зіткнень**. Це буде нова функція, яка перевіряє, чи перетинаються два прямокутники:
```javascript
function intersectRect(r1, r2) {
@ -175,7 +175,7 @@ npm start
```
3. **Додайте можливість стріляти лазером**
1. **Додайте повідомлення про подію натискання клавіші**. Клавіша *пробіл* повинна створювати лазер прямо над кораблем героя. Додайте три константи в об'єкт Messages:
1. **Додайте повідомлення про подію натискання клавіші**. Клавіша *пробіл* має створювати лазер прямо над кораблем героя. Додайте три константи до об'єкта Messages:
```javascript
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
@ -191,7 +191,7 @@ npm start
}
```
1. **Додайте слухачі подій**. Відредагуйте функцію `initGame()`, щоб герой міг стріляти, коли натискається пробіл:
1. **Додайте слухачів подій**. Відредагуйте функцію `initGame()`, щоб забезпечити можливість героя стріляти при натисканні пробілу:
```javascript
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
@ -200,7 +200,7 @@ npm start
}
```
і додайте нову функцію `eventEmitter.on()`, щоб забезпечити поведінку, коли ворог стикається з лазером:
і додайте нову функцію `eventEmitter.on()`, щоб забезпечити поведінку при зіткненні ворога з лазером:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -209,8 +209,8 @@ npm start
})
```
1. **Рух об'єкта**. Переконайтеся, що лазер поступово рухається до верхньої частини екрану. Ви створите новий клас Laser, який розширює `GameObject`, як ви робили раніше:
1. **Рух об'єкта**. Забезпечте, щоб лазер поступово рухався до верхньої частини екрану. Ви створите новий клас Laser, який розширює `GameObject`, як ви робили раніше:
```javascript
class Laser extends GameObject {
constructor(x, y) {
@ -230,7 +230,7 @@ npm start
}
```
1. **Обробіть зіткнення**. Реалізуйте правила зіткнень для лазера. Додайте функцію `updateGameObjects()`, яка перевіряє об'єкти, що стикаються:
1. **Обробка зіткнень**. Реалізуйте правила зіткнень для лазера. Додайте функцію `updateGameObjects()`, яка перевіряє зіткнення об'єктів:
```javascript
function updateGameObjects() {
@ -252,11 +252,11 @@ npm start
}
```
Переконайтеся, що ви додали `updateGameObjects()` у ваш ігровий цикл у `window.onload`.
Переконайтеся, що ви додали `updateGameObjects()` до вашого ігрового циклу у `window.onload`.
4. **Реалізуйте затримку** для лазера, щоб його можна було стріляти лише через певний інтервал.
4. **Реалізуйте затримку** для лазера, щоб він міг стріляти лише через певний інтервал часу.
Нарешті, відредагуйте клас Hero, щоб він міг мати затримку:
Нарешті, відредагуйте клас Hero, щоб він міг використовувати затримку:
```javascript
class Hero extends GameObject {
@ -285,13 +285,13 @@ npm start
}
```
На цьому етапі ваша гра має певну функціональність! Ви можете керувати героєм за допомогою стрілок, стріляти лазером за допомогою пробілу, і вороги зникають, коли ви їх вражаєте. Чудова робота!
На цьому етапі ваша гра має певну функціональність! Ви можете керувати героєм за допомогою стрілок, стріляти лазером за допомогою пробілу, і вороги зникають, коли ви їх вражаєте. Молодці!
---
## 🚀 Виклик
Додайте вибух! Перегляньте ігрові ресурси в [репозиторії Space Art](../../../../6-space-game/solution/spaceArt/readme.txt) і спробуйте додати вибух, коли лазер влучає в прибульця.
Додайте вибух! Ознайомтеся з ігровими ресурсами у [репозиторії Space Art](../../../../6-space-game/solution/spaceArt/readme.txt) і спробуйте додати вибух, коли лазер влучає в прибульця.
## Післялекційна вікторина

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4e8250db84b027c9ff816b4e4c093457",
"translation_date": "2025-08-27T22:20:46+00:00",
"original_hash": "adda95e02afa3fbee67b6e385b1109e1",
"translation_date": "2025-08-28T18:14:05+00:00",
"source_file": "6-space-game/5-keeping-score/README.md",
"language_code": "uk"
}
@ -17,7 +17,7 @@ CO_OP_TRANSLATOR_METADATA:
## Відображення тексту на екрані
Щоб показати очки гри на екрані, потрібно знати, як розміщувати текст на екрані. Для цього використовується метод `fillText()` об'єкта canvas. Ви також можете контролювати інші аспекти, такі як шрифт, колір тексту та його вирівнювання (ліворуч, праворуч, по центру). Нижче наведено код, який малює текст на екрані.
Щоб показати очки гри на екрані, потрібно знати, як розміщувати текст на екрані. Відповідь — використання методу `fillText()` об'єкта canvas. Ви також можете контролювати інші аспекти, такі як шрифт, колір тексту та навіть його вирівнювання (ліворуч, праворуч, по центру). Нижче наведено код, який малює текст на екрані.
```javascript
ctx.font = "30px Arial";
@ -36,8 +36,8 @@ ctx.fillText("show this on the screen", 0, 0);
Додайте наступне до вашої гри:
- **Очки гри**: За кожен знищений ворожий корабель герой має отримувати очки, ми пропонуємо 100 очок за корабель. Очки гри повинні відображатися внизу ліворуч.
- **Життя**: Ваш корабель має три життя. Ви втрачаєте одне життя кожного разу, коли ворожий корабель стикається з вами. Кількість життів повинна відображатися внизу праворуч у вигляді наступного графічного елемента ![зображення життя](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.uk.png).
- **Очки гри**: За кожен знищений ворожий корабель герой повинен отримувати очки, ми пропонуємо 100 очок за корабель. Очки гри повинні відображатися внизу ліворуч.
- **Життя**: Ваш корабель має три життя. Ви втрачаєте життя кожного разу, коли ворожий корабель стикається з вами. Кількість життів повинна відображатися внизу праворуч у вигляді наступного графічного елемента ![зображення життя](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.uk.png).
## Рекомендовані кроки
@ -64,7 +64,7 @@ npm start
### Додайте код
1. **Скопіюйте необхідні ресурси** з папки `solution/assets/` у папку `your-work`; ви додасте ресурс `life.png`. Додайте `lifeImg` до функції window.onload:
1. **Скопіюйте необхідні ресурси** з папки `solution/assets/` у папку `your-work`; ви додасте ресурс `life.png`. Додайте lifeImg до функції window.onload:
```javascript
lifeImg = await loadTexture("assets/life.png");
@ -80,7 +80,7 @@ npm start
eventEmitter = new EventEmitter();
```
2. **Додайте змінні**. Додайте код, який представляє ваш загальний рахунок (0) і кількість життів (3), відображайте ці значення на екрані.
2. **Додайте змінні**. Додайте код, який представляє ваш загальний рахунок (0) і кількість залишених життів (3), відображайте ці значення на екрані.
3. **Розширте функцію `updateGameObjects()`**. Розширте функцію `updateGameObjects()` для обробки зіткнень з ворогами:
@ -160,7 +160,7 @@ npm start
}
```
Додайте ці функції до ваших Collision Event Emitters:
Додайте ці функції до ваших обробників подій зіткнень:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -191,7 +191,7 @@ npm start
## Огляд і самостійне навчання
Дослідіть способи, за допомогою яких можна збільшувати та зменшувати очки гри та кількість життів. Існують цікаві ігрові рушії, такі як [PlayFab](https://playfab.com). Як використання одного з них може покращити вашу гру?
Дослідіть способи, за допомогою яких можна збільшувати та зменшувати очки гри та життя. Існують цікаві ігрові рушії, такі як [PlayFab](https://playfab.com). Як використання одного з них може покращити вашу гру?
## Завдання

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "01336cddd638242e99b133614111ea40",
"translation_date": "2025-08-27T22:25:26+00:00",
"original_hash": "05be6c37791668e3719c4fba94566367",
"translation_date": "2025-08-28T18:15:24+00:00",
"source_file": "6-space-game/6-end-condition/README.md",
"language_code": "uk"
}
@ -13,25 +13,25 @@ CO_OP_TRANSLATOR_METADATA:
[Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/39)
Існують різні способи визначення *умови завершення* гри. Як творець гри, ви вирішуєте, чому гра завершується. Ось кілька причин, якщо припустити, що ми говоримо про космічну гру, яку ви створювали до цього:
Існує багато способів визначити *умову завершення* гри. Як творець гри, ви вирішуєте, чому гра закінчується. Ось кілька причин, якщо припустити, що ми говоримо про космічну гру, яку ви створювали до цього:
- **Знищено `N` ворожих кораблів**: Це досить поширено, якщо гра поділена на рівні, і для завершення рівня потрібно знищити `N` ворожих кораблів.
- **Ваш корабель знищено**: У багатьох іграх ви програєте, якщо ваш корабель знищено. Інший поширений підхід — це концепція життів. Кожного разу, коли ваш корабель знищено, у вас віднімається одне життя. Коли всі життя втрачені, гра завершується.
- **Ви зібрали `N` очок**: Ще одна поширена умова завершення — це збирання очок. Як саме ви отримуєте очки, залежить від вас, але зазвичай очки нараховуються за різні дії, наприклад, знищення ворожого корабля або збирання предметів, які випадають після їх знищення.
- **Знищено `N` ворожих кораблів**: Це досить поширено, якщо гра розділена на рівні, де потрібно знищити `N` ворожих кораблів, щоб завершити рівень.
- **Ваш корабель знищено**: У багатьох іграх ви програєте, якщо ваш корабель знищено. Інший поширений підхід — це концепція життів. Кожного разу, коли ваш корабель знищено, віднімається одне життя. Коли всі життя втрачені, гра завершується.
- **Зібрано `N` очок**: Ще одна поширена умова завершення — це збирання очок. Як саме ви отримуєте очки — залежить від вас, але часто очки присвоюються за різні дії, наприклад, знищення ворожого корабля або збирання предметів, які випадають після їх знищення.
- **Завершення рівня**: Це може включати кілька умов, таких як знищення `X` ворожих кораблів, збирання `Y` очок або, можливо, збирання певного предмета.
## Перезапуск
Якщо людям подобається ваша гра, вони, ймовірно, захочуть зіграти знову. Коли гра завершується з будь-якої причини, ви повинні запропонувати можливість перезапустити її.
Якщо людям подобається ваша гра, вони, ймовірно, захочуть зіграти в неї знову. Коли гра завершується з будь-якої причини, ви повинні запропонувати можливість перезапустити її.
✅ Подумайте, за яких умов гра завершується, і як вас зазвичай спонукають до її перезапуску.
✅ Подумайте, за яких умов гра завершується, і як вам пропонують її перезапустити.
## Що потрібно створити
## Що створити
Ви додасте ці правила до своєї гри:
1. **Перемога в грі**. Коли всі ворожі кораблі знищено, ви виграєте гру. Додатково відобразіть повідомлення про перемогу.
1. **Перезапуск**. Коли всі ваші життя втрачені або гра виграна, ви повинні запропонувати спосіб перезапустити гру. Пам'ятайте! Вам потрібно буде ініціалізувати гру заново, і попередній стан гри має бути очищений.
1. **Перезапуск**. Коли всі ваші життя втрачені або гра виграна, ви повинні запропонувати спосіб перезапустити гру. Пам’ятайте! Вам потрібно буде реініціалізувати гру, і попередній стан гри має бути очищений.
## Рекомендовані кроки
@ -55,9 +55,9 @@ cd your-work
npm start
```
Це запустить HTTP-сервер за адресою `http://localhost:5000`. Відкрийте браузер і введіть цю адресу. Ваша гра має бути в ігровому стані.
Це запустить HTTP-сервер за адресою `http://localhost:5000`. Відкрийте браузер і введіть цю адресу. Ваша гра повинна бути готова до гри.
> порада: щоб уникнути попереджень у Visual Studio Code, відредагуйте функцію `window.onload`, щоб викликати `gameLoopId` як є (без `let`), і оголосіть `gameLoopId` на початку файлу окремо: `let gameLoopId;`
> підказка: щоб уникнути попереджень у Visual Studio Code, змініть функцію `window.onload`, щоб викликати `gameLoopId` без `let`, і оголосіть `gameLoopId` на початку файлу окремо: `let gameLoopId;`
### Додайте код
@ -74,7 +74,7 @@ npm start
}
```
1. **Додайте логіку до обробників повідомлень**. Відредагуйте `eventEmitter`, щоб обробляти ці умови:
1. **Додайте логіку до обробників повідомлень**. Змініть `eventEmitter`, щоб обробляти ці умови:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -108,7 +108,7 @@ npm start
});
```
1. **Додайте нові типи повідомлень**. Додайте ці повідомлення до об'єкта constants:
1. **Додайте нові типи повідомлень**. Додайте ці повідомлення до обєкта constants:
```javascript
GAME_END_LOSS: "GAME_END_LOSS",
@ -117,7 +117,7 @@ npm start
2. **Додайте код для перезапуску**. Додайте код, який перезапускає гру при натисканні вибраної кнопки.
1. **Слухайте натискання клавіші `Enter`**. Відредагуйте `eventListener` вашого вікна, щоб слухати це натискання:
1. **Слухайте натискання клавіші `Enter`**. Змініть eventListener вашого вікна, щоб слухати це натискання:
```javascript
else if(evt.key === "Enter") {
@ -125,7 +125,7 @@ npm start
}
```
1. **Додайте повідомлення про перезапуск**. Додайте це повідомлення до вашого об'єкта Messages:
1. **Додайте повідомлення про перезапуск**. Додайте це повідомлення до вашого обєкта Messages:
```javascript
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
@ -171,7 +171,7 @@ npm start
}
```
1. **Логіка перезапуску**. Коли всі життя втрачені або гравець виграв гру, відобразіть, що гру можна перезапустити. Додатково перезапустіть гру, коли натиснуто клавішу для перезапуску (ви можете вирішити, яка клавіша буде відповідати за перезапуск).
1. **Логіка перезапуску**. Коли всі життя втрачені або гравець виграв гру, відобразіть, що гру можна перезапустити. Додатково перезапустіть гру, коли натиснуто клавішу *перезапуску* (ви можете вирішити, яка клавіша буде відповідати за перезапуск).
1. Створіть функцію `resetGame()`:
@ -194,7 +194,7 @@ npm start
}
```
1. Додайте виклик до `eventEmitter` для скидання гри у `initGame()`:
1. Додайте виклик до `eventEmitter`, щоб скинути гру в `initGame()`:
```javascript
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
@ -216,7 +216,7 @@ npm start
## 🚀 Виклик
Додайте звук! Чи можете ви додати звук, щоб покращити ігровий процес, наприклад, коли лазер влучає, герой гине або виграє? Ознайомтеся з цим [прикладом](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play), щоб дізнатися, як відтворювати звук за допомогою JavaScript.
Додайте звук! Чи можете ви додати звук, щоб покращити ігровий процес, наприклад, коли лазер влучає, герой гине або перемагає? Ознайомтеся з цим [прикладом](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play), щоб дізнатися, як відтворювати звук за допомогою JavaScript.
## Тест після лекції
@ -233,4 +233,4 @@ npm start
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ було перекладено за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, звертаємо вашу увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.

@ -1,31 +1,31 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "8da1b5e2c63f749808858c53f37b8ce7",
"translation_date": "2025-08-27T22:07:19+00:00",
"original_hash": "8a07db14e75ac62f013b7de5df05981d",
"translation_date": "2025-08-28T18:09:09+00:00",
"source_file": "7-bank-project/1-template-route/README.md",
"language_code": "uk"
}
-->
# Створення банківського додатку Частина 1: HTML-шаблони та маршрути у веб-додатку
## Передлекційна вікторина
## Передлекційний тест
[Передлекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/41)
[Передлекційний тест](https://ff-quizzes.netlify.app/web/quiz/41)
### Вступ
З появою JavaScript у браузерах вебсайти стали більш інтерактивними та складними, ніж будь-коли. Веб-технології тепер часто використовуються для створення повноцінних додатків, які працюють безпосередньо у браузері, і які ми називаємо [веб-додатками](https://en.wikipedia.org/wiki/Web_application). Оскільки веб-додатки є дуже інтерактивними, користувачі не хочуть чекати повного перезавантаження сторінки кожного разу, коли виконується якась дія. Саме тому JavaScript використовується для оновлення HTML безпосередньо через DOM, щоб забезпечити більш плавний досвід користувача.
З появою JavaScript у браузерах вебсайти стали більш інтерактивними та складними, ніж будь-коли. Вебтехнології тепер часто використовуються для створення повнофункціональних додатків, які працюють безпосередньо у браузері, і які ми називаємо [веб-додатками](https://en.wikipedia.org/wiki/Web_application). Оскільки веб-додатки є дуже інтерактивними, користувачі не хочуть чекати повного перезавантаження сторінки щоразу, коли виконується якась дія. Саме тому JavaScript використовується для оновлення HTML безпосередньо через DOM, щоб забезпечити більш плавний користувацький досвід.
У цьому уроці ми закладемо основи для створення банківського веб-додатку, використовуючи HTML-шаблони для створення кількох екранів, які можна відображати та оновлювати без необхідності перезавантаження всієї HTML-сторінки.
### Передумови
Вам потрібен локальний веб-сервер для тестування веб-додатку, який ми створимо в цьому уроці. Якщо у вас його немає, ви можете встановити [Node.js](https://nodejs.org) і використовувати команду `npx lite-server` з вашої папки проекту. Це створить локальний веб-сервер і відкриє ваш додаток у браузері.
Вам потрібен локальний вебсервер для тестування веб-додатку, який ми створимо в цьому уроці. Якщо у вас його немає, ви можете встановити [Node.js](https://nodejs.org) і скористатися командою `npx lite-server` у папці вашого проєкту. Це створить локальний вебсервер і відкриє ваш додаток у браузері.
### Підготовка
На вашому комп'ютері створіть папку з назвою `bank` і файл `index.html` всередині неї. Ми почнемо з цього HTML [шаблону](https://en.wikipedia.org/wiki/Boilerplate_code):
На вашому комп'ютері створіть папку з назвою `bank` і файл `index.html` всередині неї. Ми почнемо з цього [шаблону HTML](https://en.wikipedia.org/wiki/Boilerplate_code):
```html
<!DOCTYPE html>
@ -45,26 +45,26 @@ CO_OP_TRANSLATOR_METADATA:
## HTML-шаблони
Якщо ви хочете створити кілька екранів для веб-сторінки, одним із рішень буде створення окремого HTML-файлу для кожного екрану, який ви хочете відобразити. Однак це рішення має певні незручності:
Якщо ви хочете створити кілька екранів для вебсторінки, одним із рішень буде створення окремого HTML-файлу для кожного екрану, який ви хочете відобразити. Однак це рішення має певні незручності:
- Ви повинні перезавантажувати весь HTML при перемиканні екрану, що може бути повільним.
- Потрібно перезавантажувати весь HTML при перемиканні екранів, що може бути повільним.
- Важко ділитися даними між різними екранами.
Інший підхід полягає в тому, щоб мати лише один HTML-файл і визначити кілька [HTML-шаблонів](https://developer.mozilla.org/docs/Web/HTML/Element/template) за допомогою елемента `<template>`. Шаблон — це багаторазовий HTML-блок, який не відображається браузером і має бути створений під час виконання за допомогою JavaScript.
Інший підхід полягає у використанні лише одного HTML-файлу та визначенні кількох [HTML-шаблонів](https://developer.mozilla.org/docs/Web/HTML/Element/template) за допомогою елемента `<template>`. Шаблон — це багаторазовий HTML-блок, який не відображається браузером і має бути створений під час виконання за допомогою JavaScript.
### Завдання
Ми створимо банківський додаток із двома екранами: сторінкою входу та панеллю управління. Спочатку додамо в HTML-тег `<body>` елемент-заповнювач, який ми будемо використовувати для створення різних екранів нашого додатку:
Ми створимо банківський додаток із двома екранами: сторінкою входу та панеллю керування. Спочатку додамо в тіло HTML елемент-заповнювач, який ми будемо використовувати для створення різних екранів нашого додатку:
```html
<div id="app">Loading...</div>
```
Ми надаємо йому `id`, щоб було легше знайти його за допомогою JavaScript пізніше.
Ми надаємо йому `id`, щоб пізніше було легше знайти його за допомогою JavaScript.
> Порада: оскільки вміст цього елемента буде замінено, ми можемо додати повідомлення про завантаження або індикатор, який буде показаний під час завантаження додатку.
> Порада: оскільки вміст цього елемента буде замінено, ми можемо додати повідомлення або індикатор завантаження, який буде відображатися, поки додаток завантажується.
Далі додамо HTML-шаблон для сторінки входу. Поки що ми просто додамо заголовок і секцію з посиланням, яке ми будемо використовувати для навігації.
Далі додамо нижче HTML-шаблон для сторінки входу. Поки що ми додамо лише заголовок і секцію з посиланням, яке ми будемо використовувати для навігації.
```html
<template id="login">
@ -75,7 +75,7 @@ CO_OP_TRANSLATOR_METADATA:
</template>
```
Потім додамо ще один HTML-шаблон для сторінки панелі управління. Ця сторінка міститиме різні секції:
Потім додамо ще один HTML-шаблон для сторінки панелі керування. Ця сторінка міститиме різні секції:
- Заголовок із назвою та посиланням для виходу
- Поточний баланс банківського рахунку
@ -106,25 +106,25 @@ CO_OP_TRANSLATOR_METADATA:
</template>
```
> Порада: створюючи HTML-шаблони, якщо ви хочете побачити, як вони виглядатимуть, ви можете закоментувати рядки `<template>` і `</template>`, обгорнувши їх у `<!-- -->`.
> Порада: під час створення HTML-шаблонів, якщо ви хочете побачити, як вони виглядатимуть, ви можете закоментувати рядки `<template>` і `</template>`, обгорнувши їх у `<!-- -->`.
Як ви думаєте, чому ми використовуємо атрибути `id` для шаблонів? Чи могли б ми використовувати щось інше, наприклад класи?
Чому, на вашу думку, ми використовуємо атрибути `id` у шаблонах? Чи могли б ми використати щось інше, наприклад класи?
## Відображення шаблонів за допомогою JavaScript
Якщо ви спробуєте ваш поточний HTML-файл у браузері, ви побачите, що він застряє на екрані з написом `Loading...`. Це тому, що нам потрібно додати трохи JavaScript-коду, щоб створити та відобразити HTML-шаблони.
Якщо ви спробуєте відкрити поточний HTML-файл у браузері, ви побачите, що він застряг на екрані з написом `Loading...`. Це тому, що нам потрібно додати трохи JavaScript-коду, щоб створити та відобразити HTML-шаблони.
Створення шаблону зазвичай виконується в 3 етапи:
Створення шаблону зазвичай виконується у 3 кроки:
1. Отримати елемент шаблону в DOM, наприклад, використовуючи [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById).
2. Клонувати елемент шаблону, використовуючи [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode).
1. Знайти елемент шаблону в DOM, наприклад, використовуючи [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById).
2. Клонувати елемент шаблону за допомогою [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode).
3. Прикріпити його до DOM під видимим елементом, наприклад, використовуючи [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild).
✅ Чому нам потрібно клонувати шаблон перед тим, як прикріпити його до DOM? Що, на вашу думку, станеться, якщо ми пропустимо цей крок?
✅ Чому нам потрібно клонувати шаблон перед тим, як прикріпити його до DOM? Що, на вашу думку, станеться, якщо пропустити цей крок?
### Завдання
Створіть новий файл із назвою `app.js` у вашій папці проекту та імпортуйте цей файл у секцію `<head>` вашого HTML:
Створіть новий файл із назвою `app.js` у папці вашого проєкту та імпортуйте цей файл у секцію `<head>` вашого HTML:
```html
<script src="app.js" defer></script>
@ -142,7 +142,7 @@ function updateRoute(templateId) {
}
```
Тут ми виконуємо саме ті 3 кроки, які описані вище. Ми створюємо шаблон із `id` `templateId` і поміщаємо його клонований вміст у наш елемент-заповнювач додатку. Зверніть увагу, що нам потрібно використовувати `cloneNode(true)`, щоб скопіювати весь піддерево шаблону.
Те, що ми робимо тут, — це саме ті 3 кроки, описані вище. Ми створюємо шаблон із `id` `templateId` і вставляємо його клонований вміст у наш елемент-заповнювач додатку. Зверніть увагу, що нам потрібно використовувати `cloneNode(true)`, щоб скопіювати весь піддерево шаблону.
Тепер викличте цю функцію з одним із шаблонів і подивіться на результат.
@ -154,7 +154,7 @@ updateRoute('login');
## Створення маршрутів
Коли ми говоримо про веб-додаток, ми називаємо *маршрутизацією* намір зіставити **URL-адреси** з конкретними екранами, які мають бути відображені. На вебсайті з кількома HTML-файлами це робиться автоматично, оскільки шляхи до файлів відображаються в URL-адресі. Наприклад, з такими файлами у вашій папці проекту:
Коли ми говоримо про веб-додаток, ми називаємо *маршрутизацією* процес зіставлення **URL-адрес** із конкретними екранами, які мають бути відображені. На вебсайті з кількома HTML-файлами це відбувається автоматично, оскільки шляхи до файлів відображаються в URL. Наприклад, з такими файлами у вашій папці проєкту:
```
mywebsite/index.html
@ -162,7 +162,7 @@ mywebsite/login.html
mywebsite/admin/index.html
```
Якщо ви створите веб-сервер із коренем `mywebsite`, зіставлення URL буде таким:
Якщо ви створите вебсервер із коренем `mywebsite`, відображення URL буде таким:
```
https://site.com --> mywebsite/index.html
@ -170,11 +170,11 @@ https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
```
Однак для нашого веб-додатку ми використовуємо один HTML-файл, що містить усі екрани, тому ця стандартна поведінка нам не допоможе. Ми повинні створити це зіставлення вручну та оновити відображений шаблон за допомогою JavaScript.
Однак для нашого веб-додатку ми використовуємо один HTML-файл, що містить усі екрани, тому ця поведінка за замовчуванням нам не допоможе. Ми повинні створити цю карту вручну та оновлювати відображуваний шаблон за допомогою JavaScript.
### Завдання
Ми використаємо простий об'єкт для реалізації [карти](https://en.wikipedia.org/wiki/Associative_array) між шляхами URL-адрес і нашими шаблонами. Додайте цей об'єкт на початку вашого файлу `app.js`.
Ми використаємо простий об'єкт для реалізації [карти](https://en.wikipedia.org/wiki/Associative_array) між шляхами URL і нашими шаблонами. Додайте цей об'єкт на початку вашого файлу `app.js`.
```js
const routes = {
@ -183,7 +183,7 @@ const routes = {
};
```
Тепер трохи змінимо функцію `updateRoute`. Замість того, щоб передавати безпосередньо `templateId` як аргумент, ми хочемо спочатку отримати його, подивившись на поточний URL, а потім використати нашу карту, щоб отримати відповідне значення `templateId`. Ми можемо використовувати [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname), щоб отримати лише секцію шляху з URL.
Тепер трохи змінимо функцію `updateRoute`. Замість того, щоб передавати безпосередньо `templateId` як аргумент, ми хочемо спочатку отримати поточний URL, а потім використати нашу карту, щоб отримати відповідне значення `templateId`. Ми можемо використовувати [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname), щоб отримати лише частину шляху з URL.
```js
function updateRoute() {
@ -198,26 +198,26 @@ function updateRoute() {
}
```
Тут ми зіставили маршрути, які ми оголосили, з відповідними шаблонами. Ви можете перевірити, що це працює правильно, змінивши URL вручну у вашому браузері.
Тут ми зіставили маршрути, які ми оголосили, із відповідними шаблонами. Ви можете перевірити, чи це працює правильно, змінивши URL вручну у вашому браузері.
✅ Що станеться, якщо ви введете невідомий шлях у URL? Як ми могли б це вирішити?
✅ Що станеться, якщо ви введете невідомий шлях у URL? Як ми могли б вирішити цю проблему?
## Додавання навігації
Наступний крок для нашого додатку — додати можливість переходу між сторінками без необхідності змінювати URL вручну. Це передбачає дві речі:
1. Оновлення поточного URL
2. Оновлення відображеного шаблону на основі нового URL
2. Оновлення відображуваного шаблону на основі нового URL
Ми вже подбали про другу частину за допомогою функції `updateRoute`, тому нам потрібно зрозуміти, як оновити поточний URL.
Ми будемо використовувати JavaScript, а точніше [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), який дозволяє оновлювати URL і створювати новий запис в історії перегляду без перезавантаження HTML.
Ми скористаємося JavaScript, а точніше [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), який дозволяє оновлювати URL і створювати новий запис в історії переглядів без перезавантаження HTML.
> Примітка: Хоча HTML-елемент прив'язки [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) можна використовувати самостійно для створення гіперпосилань на різні URL-адреси, він за замовчуванням змусить браузер перезавантажити HTML. Необхідно запобігти цій поведінці під час обробки маршрутизації за допомогою власного JavaScript, використовуючи функцію `preventDefault()` для події кліку.
> Примітка: Хоча HTML-елемент прив'язки [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) можна використовувати самостійно для створення гіперпосилань на різні URL, за замовчуванням він змусить браузер перезавантажити HTML. Необхідно запобігти цій поведінці під час обробки маршрутизації за допомогою власного JavaScript, використовуючи функцію `preventDefault()` для події кліку.
### Завдання
Давайте створимо нову функцію, яку ми можемо використовувати для навігації в нашому додатку:
Давайте створимо нову функцію, яку ми зможемо використовувати для навігації в нашому додатку:
```js
function navigate(path) {
@ -226,9 +226,9 @@ function navigate(path) {
}
```
Цей метод спочатку оновлює поточний URL на основі заданого шляху, а потім оновлює шаблон. Властивість `window.location.origin` повертає корінь URL, дозволяючи нам реконструювати повну URL-адресу з заданого шляху.
Цей метод спочатку оновлює поточний URL на основі заданого шляху, а потім оновлює шаблон. Властивість `window.location.origin` повертає корінь URL, що дозволяє нам реконструювати повний URL із заданого шляху.
Тепер, коли у нас є ця функція, ми можемо вирішити проблему, яка виникає, якщо шлях не відповідає жодному визначеному маршруту. Ми модифікуємо функцію `updateRoute`, додавши резервний варіант до одного з існуючих маршрутів, якщо ми не можемо знайти відповідність.
Тепер, коли у нас є ця функція, ми можемо вирішити проблему, яка виникає, якщо шлях не відповідає жодному визначеному маршруту. Ми змінимо функцію `updateRoute`, додавши резервний варіант для одного з існуючих маршрутів, якщо ми не можемо знайти відповідність.
```js
function updateRoute() {
@ -244,7 +244,7 @@ function updateRoute() {
Якщо маршрут не може бути знайдений, ми тепер перенаправимо на сторінку `login`.
Тепер давайте створимо функцію для отримання URL при кліку на посилання та запобігання стандартній поведінці браузера для посилань:
Тепер створимо функцію для отримання URL при кліку на посилання та запобігання стандартній поведінці браузера для посилань:
```js
function onLinkClick(event) {
@ -267,21 +267,21 @@ function onLinkClick(event) {
Спробуйте натиснути на ці посилання, тепер ви повинні мати можливість переходити між різними екранами вашого додатку.
✅ Метод `history.pushState` є частиною стандарту HTML5 і реалізований у [всіх сучасних браузерах](https://caniuse.com/?search=pushState). Якщо ви створюєте веб-додаток для старих браузерів, є трюк, який ви можете використовувати замість цього API: використовуючи [хеш (`#`)](https://en.wikipedia.org/wiki/URI_fragment) перед шляхом, ви можете реалізувати маршрутизацію, яка працює з регулярною навігацією за допомогою прив'язок і не перезавантажує сторінку, оскільки її метою було створення внутрішніх посилань на сторінці.
✅ Метод `history.pushState` є частиною стандарту HTML5 і реалізований у [всіх сучасних браузерах](https://caniuse.com/?search=pushState). Якщо ви створюєте веб-додаток для старих браузерів, є трюк, який можна використовувати замість цього API: використання [хешу (`#`)](https://en.wikipedia.org/wiki/URI_fragment) перед шляхом дозволяє реалізувати маршрутизацію, яка працює з регулярною навігацією за допомогою прив'язок і не перезавантажує сторінку, оскільки її метою було створення внутрішніх посилань на сторінці.
## Обробка кнопок "Назад" і "Вперед" у браузері
Використання `history.pushState` створює нові записи в історії навігації браузера. Ви можете перевірити це, утримуючи *кнопку назад* вашого браузера, вона повинна відображати щось на кшталт цього:
Використання `history.pushState` створює нові записи в історії навігації браузера. Ви можете перевірити це, утримуючи *кнопку назад* у вашому браузері, це має виглядати приблизно так:
![Скріншот історії навігації](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.uk.png)
![Знімок екрана історії навігації](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.uk.png)
Якщо ви спробуєте кілька разів натиснути кнопку назад, ви побачите, що поточний URL змінюється, а історія оновлюється, але той самий шаблон продовжує відображатися.
Якщо ви спробуєте натиснути кнопку назад кілька разів, ви побачите, що поточний URL змінюється, а історія оновлюється, але той самий шаблон продовжує відображатися.
Це тому, що додаток не знає, що нам потрібно викликати `updateRoute()` кожного разу, коли історія змінюється. Якщо ви подивитеся на [документацію `history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), ви побачите, що якщо стан змінюється - тобто ми перейшли до іншого URL - подія [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) викликається. Ми використаємо це, щоб виправити проблему.
Це тому, що додаток не знає, що нам потрібно викликати `updateRoute()` щоразу, коли історія змінюється. Якщо ви подивитеся на [документацію `history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), ви побачите, що якщо стан змінюється — тобто ми перейшли на інший URL — подія [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) викликається. Ми використаємо це, щоб виправити цю проблему.
### Завдання
Щоб переконатися, що відображений шаблон оновлюється, коли історія браузера змінюється, ми прив'яжемо нову функцію, яка викликає `updateRoute()`. Ми зробимо це внизу нашого файлу `app.js`:
Щоб переконатися, що відображуваний шаблон оновлюється, коли історія браузера змінюється, ми прив'яжемо нову функцію, яка викликає `updateRoute()`. Ми зробимо це внизу нашого файлу `app.js`:
```js
window.onpopstate = () => updateRoute();
@ -290,27 +290,27 @@ updateRoute();
> Примітка: ми використали [стрілкову функцію](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) для оголошення нашого обробника події `popstate` для стислості, але звичайна функція працювала б так само.
Ось відео для повторення про стрілкові функції:
Ось відео-нагадування про стрілкові функції:
[![Стрілкові функції](https://img.youtube.com/vi/OP6eEbOj2sc/0.jpg)](https://youtube.com/watch?v=OP6eEbOj2sc "Стрілкові функції")
> 🎥 Натисніть на зображення вище, щоб переглянути відео про стрілкові функції.
Тепер спробуйте використовувати кнопки "Назад" і "Вперед" вашого браузера та перевірте, що відображений маршрут тепер правильно оновлюється.
Тепер спробуйте скористатися кнопками "Назад" і "Вперед" у вашому браузері та перевірте, чи правильно оновлюється відображуваний маршрут цього разу.
---
## 🚀 Виклик
Додайте новий шаблон і маршрут для третьої сторінки, яка показує кредити для цього додатку.
Додайте новий шаблон і маршрут для третьої сторінки, яка показує авторів цього додатку.
## Післялекційна вікторина
## Післялекційний тест
[Післялекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/42)
[Післялекційний тест](https://ff-quizzes.netlify.app/web/quiz/42)
## Огляд і самостійне навчання
Маршрутизація є однією з несподівано складних частин веб-розробки, особливо коли веб переходить від поведінки оновлення сторінок до оновлень сторінок у додатках з однією сторінкою (SPA). Прочитайте трохи про [те, як служба Azure Static Web App](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) обробляє маршрутизацію. Чи можете ви пояснити, чому деякі з описаних у цьому документі рішень є необхідними?
Маршрутизація є однією з несподівано складних частин веброзробки, особливо коли веб переходить від поведінки з оновленням сторінок до оновлень у рамках односторінкових додатків. Прочитайте трохи про те, [як служба Azure Static Web App](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) обробляє маршрутизацію. Чи можете ви пояснити, чому деякі з описаних у цьому документі рішень є необхідними?
## Завдання

@ -1,34 +1,34 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b667b7d601e2ee19acb5aa9d102dc9f3",
"translation_date": "2025-08-27T22:02:21+00:00",
"original_hash": "8baca047d77a5f43fa4099c0578afa42",
"translation_date": "2025-08-28T18:07:19+00:00",
"source_file": "7-bank-project/2-forms/README.md",
"language_code": "uk"
}
-->
# Створення банківського додатку, частина 2: створення форми входу та реєстрації
# Створення банківського додатку, частина 2: Створення форми входу та реєстрації
## Передлекційний тест
## Попереднє опитування
[Передлекційний тест](https://ff-quizzes.netlify.app/web/quiz/43)
[Попереднє опитування](https://ff-quizzes.netlify.app/web/quiz/43)
### Вступ
У майже всіх сучасних веб-додатках ви можете створити обліковий запис, щоб мати свій власний приватний простір. Оскільки кілька користувачів можуть одночасно отримувати доступ до веб-додатку, потрібен механізм для зберігання персональних даних кожного користувача окремо та вибору інформації для відображення. Ми не будемо розглядати, як [безпечно керувати ідентифікацією користувачів](https://en.wikipedia.org/wiki/Authentication), оскільки це окрема велика тема, але ми забезпечимо можливість створення одного (або кількох) банківських рахунків у нашому додатку.
У майже всіх сучасних веб-додатках ви можете створити обліковий запис, щоб мати власний приватний простір. Оскільки кілька користувачів можуть одночасно отримувати доступ до веб-додатку, потрібен механізм для зберігання персональних даних кожного користувача окремо та вибору, яку інформацію відображати. Ми не будемо розглядати, як [безпечно керувати ідентифікацією користувачів](https://en.wikipedia.org/wiki/Authentication), оскільки це велика тема сама по собі, але ми забезпечимо можливість кожному користувачеві створити один (або кілька) банківських рахунків у нашому додатку.
У цій частині ми використаємо HTML-форми для додавання входу та реєстрації до нашого веб-додатку. Ми розглянемо, як програмно надсилати дані на серверний API, і зрештою визначимо базові правила валідації для введення користувачем даних.
У цій частині ми використаємо HTML-форми для додавання входу та реєстрації до нашого веб-додатку. Ми побачимо, як програмно надсилати дані на серверний API, і, зрештою, як визначати базові правила перевірки введених даних користувачем.
### Передумови
Вам потрібно завершити [шаблони HTML та маршрутизацію](../1-template-route/README.md) веб-додатку для цього уроку. Також необхідно встановити [Node.js](https://nodejs.org) і [запустити серверний API](../api/README.md) локально, щоб ви могли надсилати дані для створення облікових записів.
Вам потрібно завершити [HTML-шаблони та маршрутизацію](../1-template-route/README.md) веб-додатку для цього уроку. Також необхідно встановити [Node.js](https://nodejs.org) і [запустити серверний API](../api/README.md) локально, щоб мати можливість надсилати дані для створення рахунків.
**Зверніть увагу**
Ви будете використовувати два термінали одночасно, як зазначено нижче:
1. Для основного банківського додатку, який ми створили в уроці [шаблони HTML та маршрутизація](../1-template-route/README.md).
2. Для [серверного API банківського додатку](../api/README.md), який ми щойно налаштували вище.
**Зверніть увагу**
Ви будете використовувати два термінали одночасно, як зазначено нижче:
1. Для основного банківського додатку, який ми створили в уроці [HTML-шаблони та маршрутизація](../1-template-route/README.md).
2. Для [серверного API банківського додатку](../api/README.md), який ми щойно налаштували.
Вам потрібно, щоб обидва сервери працювали одночасно для подальшого проходження уроку. Вони слухають на різних портах (порт `3000` і порт `5000`), тому все має працювати без проблем.
Вам потрібно, щоб обидва сервери працювали, щоб продовжити урок. Вони слухають на різних портах (порт `3000` і порт `5000`), тому все має працювати без проблем.
Ви можете перевірити, чи сервер працює належним чином, виконавши цю команду в терміналі:
@ -39,26 +39,26 @@ curl http://localhost:5000/api
---
## Форма та елементи керування
## Форма та елементи управління
Елемент `<form>` інкапсулює розділ HTML-документа, де користувач може вводити та надсилати дані за допомогою інтерактивних елементів керування. Існує багато різних елементів інтерфейсу користувача (UI), які можна використовувати у формі, найпоширенішими з яких є елементи `<input>` і `<button>`.
Елемент `<form>` охоплює розділ HTML-документа, де користувач може вводити та надсилати дані за допомогою інтерактивних елементів управління. Існує багато різних елементів інтерфейсу користувача (UI), які можна використовувати у формі, найпоширенішими з яких є елементи `<input>` і `<button>`.
Існує багато різних [типів](https://developer.mozilla.org/docs/Web/HTML/Element/input) `<input>`. Наприклад, щоб створити поле, де користувач може ввести своє ім'я користувача, ви можете використати:
Існує багато різних [типів](https://developer.mozilla.org/docs/Web/HTML/Element/input) `<input>`. Наприклад, щоб створити поле, де користувач може ввести своє ім'я користувача, можна використати:
```html
<input id="username" name="username" type="text">
```
Атрибут `name` буде використовуватися як ім'я властивості, коли дані форми будуть надіслані. Атрибут `id` використовується для зв’язування `<label>` з елементом керування формою.
Атрибут `name` буде використовуватися як назва властивості, коли дані форми будуть надіслані. Атрибут `id` використовується для асоціації `<label>` з елементом управління формою.
> Ознайомтеся з повним списком [типів `<input>`](https://developer.mozilla.org/docs/Web/HTML/Element/input) і [інших елементів керування формами](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls), щоб отримати уявлення про всі доступні елементи інтерфейсу користувача, які ви можете використовувати під час створення вашого інтерфейсу.
> Ознайомтеся з повним списком [типів `<input>`](https://developer.mozilla.org/docs/Web/HTML/Element/input) і [інших елементів управління формами](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls), щоб отримати уявлення про всі вбудовані елементи інтерфейсу користувача, які можна використовувати під час створення вашого інтерфейсу.
✅ Зверніть увагу, що `<input>` є [порожнім елементом](https://developer.mozilla.org/docs/Glossary/Empty_element), до якого *не слід* додавати закриваючий тег. Ви можете використовувати самозакриваючий запис `<input/>`, але це не обов’язково.
✅ Зверніть увагу, що `<input>` є [порожнім елементом](https://developer.mozilla.org/docs/Glossary/Empty_element), для якого не потрібно додавати відповідний закриваючий тег. Ви можете використовувати самозакриваючу нотацію `<input/>`, але це не обов’язково.
Елемент `<button>` у формі має особливу поведінку. Якщо ви не вкажете його атрибут `type`, він автоматично надішле дані форми на сервер при натисканні. Ось можливі значення атрибута `type`:
Елемент `<button>` у формі має особливу поведінку. Якщо ви не вкажете його атрибут `type`, він автоматично надішле дані форми на сервер після натискання. Ось можливі значення атрибута `type`:
- `submit`: За замовчуванням у `<form>`, кнопка викликає дію надсилання форми.
- `reset`: Кнопка скидає всі елементи керування форми до їх початкових значень.
- `submit`: За замовчуванням у `<form>`, кнопка запускає дію надсилання форми.
- `reset`: Кнопка скидає всі елементи управління форми до їх початкових значень.
- `button`: Не призначає жодної поведінки за замовчуванням при натисканні кнопки. Ви можете призначити їй власні дії за допомогою JavaScript.
### Завдання
@ -79,14 +79,14 @@ curl http://localhost:5000/api
</template>
```
Якщо придивитися, ви помітите, що ми також додали елемент `<label>`. Елементи `<label>` використовуються для додавання назви до елементів керування інтерфейсу користувача, таких як наше поле для імені користувача. Мітки важливі для зручності читання ваших форм, а також мають додаткові переваги:
Якщо придивитися уважніше, можна помітити, що ми також додали елемент `<label>`. Елементи `<label>` використовуються для додавання назви до елементів управління інтерфейсу користувача, таких як наше поле для імені користувача. Мітки важливі для читабельності ваших форм, але також мають додаткові переваги:
- Зв’язуючи мітку з елементом керування формою, це допомагає користувачам, які використовують допоміжні технології (наприклад, екранний диктор), зрозуміти, які дані від них очікуються.
- Ви можете натиснути на мітку, щоб безпосередньо сфокусуватися на пов’язаному полі введення, що полегшує доступ на пристроях із сенсорним екраном.
- Асоціюючи мітку з елементом управління формою, це допомагає користувачам, які використовують допоміжні технології (наприклад, екранний диктор), зрозуміти, які дані від них очікуються.
- Ви можете натиснути на мітку, щоб безпосередньо сфокусуватися на пов’язаному введенні, що полегшує доступ на пристроях із сенсорним екраном.
> [Доступність](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) у вебі — це дуже важлива тема, яку часто ігнорують. Завдяки [семантичним HTML-елементам](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) створювати доступний контент не складно, якщо використовувати їх належним чином. Ви можете [дізнатися більше про доступність](https://developer.mozilla.org/docs/Web/Accessibility), щоб уникнути поширених помилок і стати відповідальним розробником.
> [Доступність](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) у вебі — це дуже важлива тема, яку часто ігнорують. Завдяки [семантичним HTML-елементам](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) створювати доступний контент не складно, якщо використовувати їх належним чином. Ви можете [прочитати більше про доступність](https://developer.mozilla.org/docs/Web/Accessibility), щоб уникнути поширених помилок і стати відповідальним розробником.
Тепер ми додамо другу форму для реєстрації, одразу під попередньою:
Тепер ми додамо другу форму для реєстрації, прямо під попередньою:
```html
<hr/>
@ -104,25 +104,26 @@ curl http://localhost:5000/api
</form>
```
Використовуючи атрибут `value`, ми можемо визначити значення за замовчуванням для певного поля введення. Зверніть увагу, що поле введення для `balance` має тип `number`. Чи виглядає воно інакше, ніж інші поля? Спробуйте взаємодіяти з ним.
Використовуючи атрибут `value`, ми можемо визначити значення за замовчуванням для певного введення.
Зверніть увагу, що введення для `balance` має тип `number`. Чи виглядає воно інакше, ніж інші введення? Спробуйте взаємодіяти з ним.
✅ Чи можете ви навігувати та взаємодіяти з формами, використовуючи лише клавіатуру? Як би ви це зробили?
## Надсилання даних на сервер
Тепер, коли у нас є функціональний інтерфейс, наступний крок — надіслати дані на сервер. Давайте швидко протестуємо наш поточний код: що відбувається, якщо ви натискаєте кнопку *Login* або *Register*?
Тепер, коли у нас є функціональний інтерфейс, наступним кроком буде надсилання даних на наш сервер. Давайте зробимо швидкий тест, використовуючи наш поточний код: що станеться, якщо ви натиснете кнопку *Login* або *Register*?
Чи помітили ви зміну в адресному рядку вашого браузера?
Чи помітили ви зміну в розділі URL вашого браузера?
![Знімок екрана зі зміною URL браузера після натискання кнопки Register](../../../../translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.uk.png)
![Скріншот зміни URL браузера після натискання кнопки Register](../../../../translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.uk.png)
Дія за замовчуванням для `<form>` — це надсилання форми на поточну URL-адресу сервера за допомогою [методу GET](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3), додаючи дані форми безпосередньо до URL. Однак цей метод має кілька недоліків:
Дія за замовчуванням для `<form>` — це надсилання форми на поточний URL сервера за допомогою [методу GET](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3), додаючи дані форми безпосередньо до URL. Однак цей метод має деякі недоліки:
- Обсяг даних, що надсилаються, дуже обмежений (приблизно 2000 символів).
- Дані безпосередньо видно в URL (що не дуже добре для паролів).
- Дані, що надсилаються, мають обмежений розмір (близько 2000 символів).
- Дані безпосередньо видно в URL (не дуже добре для паролів).
- Він не працює з завантаженням файлів.
Саме тому ви можете змінити його на використання [методу POST](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5), який надсилає дані форми на сервер у тілі HTTP-запиту, без жодних попередніх обмежень.
Ось чому ви можете змінити його, щоб використовувати [метод POST](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5), який надсилає дані форми на сервер у тілі HTTP-запиту, без жодних попередніх обмежень.
> Хоча POST є найпоширенішим методом для надсилання даних, [у деяких конкретних сценаріях](https://www.w3.org/2001/tag/doc/whenToUseGet.html) краще використовувати метод GET, наприклад, під час реалізації поля пошуку.
@ -138,19 +139,19 @@ curl http://localhost:5000/api
![Вікно браузера на адресі localhost:5000/api/accounts, що показує JSON-рядок із даними користувача](../../../../translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.uk.png)
Якщо все працює правильно, сервер повинен відповісти на ваш запит [JSON](https://www.json.org/json-en.html)-відповіддю, що містить дані створеного облікового запису.
Якщо все пройде добре, сервер відповість на ваш запит [JSON](https://www.json.org/json-en.html)-відповіддю, що містить дані створеного рахунку.
✅ Спробуйте зареєструватися знову з тим самим ім’ям. Що відбувається?
✅ Спробуйте зареєструватися знову з тим самим ім’ям. Що станеться?
## Надсилання даних без перезавантаження сторінки
Як ви, мабуть, помітили, є невелика проблема з підходом, який ми щойно використали: під час надсилання форми ми виходимо з нашого додатку, і браузер перенаправляє на URL сервера. Ми намагаємося уникнути всіх перезавантажень сторінок у нашому веб-додатку, оскільки створюємо [односторінковий додаток (SPA)](https://en.wikipedia.org/wiki/Single-page_application).
Щоб надіслати дані форми на сервер без примусового перезавантаження сторінки, нам потрібно використовувати JavaScript. Замість того, щоб вказувати URL у властивості `action` елемента `<form>`, ви можете використовувати будь-який JavaScript-код, додавши перед ним рядок `javascript:`, щоб виконати власну дію. Це також означає, що вам доведеться реалізувати деякі завдання, які раніше автоматично виконував браузер:
Щоб надіслати дані форми на сервер без примусового перезавантаження сторінки, нам потрібно використовувати код JavaScript. Замість того, щоб вказувати URL у властивості `action` елемента `<form>`, ви можете використовувати будь-який код JavaScript, додавши перед ним рядок `javascript:`, щоб виконати власну дію. Використовуючи це, вам також доведеться реалізувати деякі завдання, які раніше виконувалися автоматично браузером:
- Отримання даних форми.
- Конвертація та кодування даних форми у відповідний формат.
- Створення HTTP-запиту та його надсилання на сервер.
- Отримати дані форми.
- Перетворити та закодувати дані форми у відповідний формат.
- Створити HTTP-запит і надіслати його на сервер.
### Завдання
@ -171,7 +172,7 @@ function register() {
}
```
Тут ми отримуємо елемент форми за допомогою `getElementById()` і використовуємо помічник [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData), щоб витягти значення з елементів керування форми у вигляді набору пар ключ/значення. Потім ми конвертуємо дані у звичайний об’єкт за допомогою [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) і, нарешті, серіалізуємо дані у формат [JSON](https://www.json.org/json-en.html), який зазвичай використовується для обміну даними в Інтернеті.
Тут ми отримуємо елемент форми за допомогою `getElementById()` і використовуємо помічник [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData), щоб витягти значення з елементів управління форми як набір пар ключ/значення. Потім ми перетворюємо дані на звичайний об’єкт за допомогою [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) і, нарешті, серіалізуємо дані у формат [JSON](https://www.json.org/json-en.html), який часто використовується для обміну даними в вебі.
Дані тепер готові до надсилання на сервер. Створіть нову функцію з назвою `createAccount`:
@ -190,20 +191,20 @@ async function createAccount(account) {
}
```
Що робить ця функція? По-перше, зверніть увагу на ключове слово `async`. Це означає, що функція містить код, який виконуватиметься [**асинхронно**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Коли використовується разом із ключовим словом `await`, це дозволяє чекати виконання асинхронного коду — наприклад, очікування відповіді сервера — перед продовженням.
Що робить ця функція? Спочатку зверніть увагу на ключове слово `async`. Це означає, що функція містить код, який буде виконуватися [**асинхронно**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Використовуючи ключове слово `await`, ми можемо чекати виконання асинхронного коду — наприклад, очікувати відповіді сервера — перед тим, як продовжити.
Ось коротке відео про використання `async/await`:
[![Async і Await для керування промісами](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "Async і Await для керування промісами")
[![Async і Await для управління обіцянками](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "Async і Await для управління обіцянками")
> 🎥 Натисніть на зображення вище, щоб переглянути відео про async/await.
Ми використовуємо API `fetch()` для надсилання JSON-даних на сервер. Цей метод приймає 2 параметри:
- URL сервера, тому ми вказуємо `//localhost:5000/api/accounts`.
- Налаштування запиту. Тут ми встановлюємо метод `POST` і надаємо `body` для запиту. Оскільки ми надсилаємо JSON-дані на сервер, нам також потрібно встановити заголовок `Content-Type` у значення `application/json`, щоб сервер знав, як інтерпретувати вміст.
- URL сервера, тому ми повертаємо `//localhost:5000/api/accounts`.
- Налаштування запиту. Тут ми встановлюємо метод `POST` і надаємо `body` для запиту. Оскільки ми надсилаємо JSON-дані на сервер, нам також потрібно встановити заголовок `Content-Type` як `application/json`, щоб сервер знав, як інтерпретувати вміст.
Оскільки сервер відповість на запит JSON-даними, ми можемо використовувати `await response.json()`, щоб розібрати JSON-вміст і повернути отриманий об’єкт. Зверніть увагу, що цей метод є асинхронним, тому ми використовуємо ключове слово `await`, щоб переконатися, що будь-які помилки під час розбору також будуть враховані.
Оскільки сервер відповість на запит JSON-даними, ми можемо використовувати `await response.json()`, щоб розібрати JSON-вміст і повернути отриманий об’єкт. Зверніть увагу, що цей метод асинхронний, тому ми використовуємо ключове слово `await`, щоб переконатися, що будь-які помилки під час розбору також будуть враховані.
Тепер додайте трохи коду до функції `register`, щоб викликати `createAccount()`:
@ -211,7 +212,7 @@ async function createAccount(account) {
const result = await createAccount(jsonData);
```
Оскільки ми використовуємо ключове слово `await`, нам потрібно додати ключове слово `async` перед функцією `register`:
Оскільки ми використовуємо ключове слово `await`, нам потрібно додати ключове слово `async` перед функцією register:
```js
async function register() {
@ -234,27 +235,27 @@ async function register() {
}
```
Це було трохи довго, але ми впоралися! Якщо ви відкриєте [інструменти розробника браузера](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) і спробуєте зареєструвати новий обліковий запис, ви не побачите жодних змін на веб-сторінці, але в консолі з’явиться повідомлення, яке підтверджує, що все працює.
Це було трохи довго, але ми дійшли до кінця! Якщо ви відкриєте [інструменти розробника браузера](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) і спробуєте зареєструвати новий обліковий запис, ви не побачите жодних змін на веб-сторінці, але в консолі з’явиться повідомлення, яке підтверджує, що все працює.
![Знімок екрана з повідомленням у консолі браузера](../../../../translated_images/browser-console.efaf0b51aaaf67782a29e1a0bb32cc063f189b18e894eb5926e02f1abe864ec2.uk.png)
![Скріншот, що показує повідомлення в консолі браузера](../../../../translated_images/browser-console.efaf0b51aaaf67782a29e1a0bb32cc063f189b18e894eb5926e02f1abe864ec2.uk.png)
✅ Як ви думаєте, чи дані надсилаються на сервер безпечно? Що, якщо хтось зможе перехопити запит? Ви можете прочитати про [HTTPS](https://en.wikipedia.org/wiki/HTTPS), щоб дізнатися більше про безпечну передачу даних.
## Валідація даних
## Перевірка даних
Якщо ви спробуєте зареєструвати новий обліковий запис, не вказавши спочатку ім’я користувача, ви побачите, що сервер повертає помилку зі статус-кодом [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).).
Якщо ви спробуєте зареєструвати новий обліковий запис, не вказавши спочатку ім’я користувача, ви побачите, що сервер повертає помилку зі статусом [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).).
Перед надсиланням даних на сервер гарною практикою є [перевірка даних форми](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) заздалегідь, щоб переконатися, що ви надсилаєте дійсний запит. HTML5 елементи керування формами забезпечують вбудовану валідацію за допомогою різних атрибутів:
Перед надсиланням даних на сервер гарною практикою є [перевірка даних форми](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) заздалегідь, коли це можливо, щоб переконатися, що ви надсилаєте дійсний запит. Елементи управління формами HTML5 забезпечують вбудовану перевірку за допомогою різних атрибутів:
- `required`: поле має бути заповнене, інакше форму не можна надіслати.
- `minlength` і `maxlength`: визначають мінімальну та максимальну кількість символів у текстових полях.
- `min` і `max`: визначають мінімальне та максимальне значення числового поля.
- `type`: визначає тип очікуваних даних, наприклад, `number`, `email`, `file` або [інші вбудовані типи](https://developer.mozilla.org/docs/Web/HTML/Element/input). Цей атрибут також може змінювати візуальне відображення елемента керування.
- `pattern`: дозволяє визначити [регулярний вираз](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) для перевірки, чи введені дані є дійсними.
Порада: ви можете налаштувати вигляд елементів керування формою залежно від того, чи вони є валідними, чи ні, використовуючи псевдокласи CSS `:valid` та `:invalid`.
- `type`: визначає тип очікуваних даних, наприклад, `number`, `email`, `file` або [інші вбудовані типи](https://developer.mozilla.org/docs/Web/HTML/Element/input). Цей атрибут також може змінити візуальне відображення елемента управління формою.
- `pattern`: дозволяє визначити [регулярний вираз](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions), щоб перевірити, чи введені дані є дійсними.
> Порада: ви можете налаштувати вигляд елементів керування формою залежно від того, чи вони є валідними, чи ні, використовуючи псевдокласи CSS `:valid` та `:invalid`.
### Завдання
Для створення нового облікового запису необхідно заповнити два обов’язкові поля: ім’я користувача та валюту. Інші поля є необов’язковими. Оновіть HTML форми, використовуючи атрибут `required` і текст у мітці поля, щоб це виглядало так:
Для створення нового облікового запису необхідно заповнити два обов’язкові поля: ім’я користувача та валюту. Інші поля є необов’язковими. Оновіть HTML форми, використовуючи як атрибут `required`, так і текст у мітці поля, щоб:
```html
<label for="user">Username (required)</label>
@ -264,7 +265,7 @@ async function register() {
<input id="currency" name="currency" type="text" value="$" required>
```
Хоча ця конкретна серверна реалізація не накладає жорстких обмежень на максимальну довжину полів, завжди є гарною практикою визначати розумні межі для будь-якого текстового вводу користувача.
Хоча ця конкретна серверна реалізація не накладає обмежень на максимальну довжину полів, завжди є гарною практикою визначати розумні межі для будь-якого текстового вводу користувача.
Додайте атрибут `maxlength` до текстових полів:
@ -276,19 +277,19 @@ async function register() {
<input id="description" name="description" type="text" maxlength="100">
```
Тепер, якщо ви натиснете кнопку *Зареєструватися*, і якесь поле не відповідатиме визначеним нами правилам валідації, ви побачите щось подібне:
Тепер, якщо ви натиснете кнопку *Зареєструватися*, і якесь поле не відповідатиме визначеним правилам валідації, ви побачите щось подібне:
![Знімок екрана, що показує помилку валідації при спробі надіслати форму](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.uk.png)
![Знімок екрана, що показує помилку валідації при спробі відправити форму](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.uk.png)
Валідація, яка виконується *до* надсилання будь-яких даних на сервер, називається **клієнтською валідацією**. Але зверніть увагу, що не завжди можливо виконати всі перевірки без надсилання даних. Наприклад, ми не можемо перевірити тут, чи існує вже обліковий запис із таким самим ім’ям користувача, без запиту до сервера. Додаткова валідація, яка виконується на сервері, називається **серверною валідацією**.
Валідація, яка виконується *до* відправки будь-яких даних на сервер, називається **клієнтською валідацією**. Але варто зазначити, що не завжди можливо виконати всі перевірки без відправки даних. Наприклад, ми не можемо перевірити тут, чи існує вже обліковий запис із таким самим ім’ям користувача, без запиту до сервера. Додаткова валідація, яка виконується на сервері, називається **серверною валідацією**.
Зазвичай потрібно реалізовувати обидва типи валідації. Клієнтська валідація покращує взаємодію з користувачем, надаючи миттєвий зворотний зв’язок, але серверна валідація є критично важливою для забезпечення коректності та безпеки даних користувача.
Зазвичай необхідно реалізувати обидва типи валідації. Клієнтська валідація покращує взаємодію з користувачем, надаючи миттєвий зворотний зв’язок, але серверна валідація є критично важливою для забезпечення того, щоб дані користувача, які ви обробляєте, були коректними та безпечними.
---
## 🚀 Виклик
Показуйте повідомлення про помилку в HTML, якщо користувач уже існує.
Показати повідомлення про помилку в HTML, якщо користувач уже існує.
Ось приклад того, як може виглядати фінальна сторінка входу після невеликого стилізування:
@ -300,7 +301,7 @@ async function register() {
## Огляд і самостійне навчання
Розробники проявляють неабияку креативність у створенні форм, особливо щодо стратегій валідації. Дізнайтеся про різні підходи до створення форм, переглядаючи [CodePen](https://codepen.com); чи зможете ви знайти цікаві та надихаючі приклади форм?
Розробники проявляють неабияку креативність у створенні форм, особливо у стратегіях валідації. Дізнайтеся про різні підходи до створення форм, переглядаючи [CodePen](https://codepen.com); чи зможете ви знайти цікаві та надихаючі приклади форм?
## Завдання
@ -309,4 +310,4 @@ async function register() {
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ було перекладено за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, звертаємо вашу увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f587e913e3f7c0b1c549a05dd74ee8e5",
"translation_date": "2025-08-27T21:58:48+00:00",
"original_hash": "89d0df9854ed020f155e94882ae88d4c",
"translation_date": "2025-08-28T18:06:32+00:00",
"source_file": "7-bank-project/3-data/README.md",
"language_code": "uk"
}
@ -15,15 +15,15 @@ CO_OP_TRANSLATOR_METADATA:
### Вступ
У центрі кожного веб-додатку знаходяться *дані*. Дані можуть мати різні форми, але їх основна мета — показувати інформацію користувачеві. З розвитком веб-додатків, які стають все більш інтерактивними та складними, спосіб доступу користувача до інформації та взаємодії з нею став ключовою частиною веб-розробки.
У центрі кожного веб-додатку знаходяться *дані*. Дані можуть мати різні форми, але їх основна мета — показувати інформацію користувачеві. З розвитком веб-додатків, які стають все більш інтерактивними та складними, спосіб доступу користувача до інформації та взаємодії з нею стає ключовою частиною веб-розробки.
У цьому уроці ми розглянемо, як асинхронно отримувати дані з сервера та використовувати ці дані для відображення інформації на веб-сторінці без перезавантаження HTML.
### Передумови
Вам потрібно створити [Форму входу та реєстрації](../2-forms/README.md) як частину веб-додатку для цього уроку. Також необхідно встановити [Node.js](https://nodejs.org) і [запустити сервер API](../api/README.md) локально, щоб отримати дані облікового запису.
Для цього уроку вам потрібно створити [Форму входу та реєстрації](../2-forms/README.md) як частину веб-додатку. Також необхідно встановити [Node.js](https://nodejs.org) і [запустити сервер API](../api/README.md) локально, щоб отримати дані облікових записів.
Ви можете перевірити, чи сервер працює правильно, виконавши цю команду в терміналі:
Ви можете перевірити, чи сервер працює належним чином, виконавши цю команду в терміналі:
```sh
curl http://localhost:5000/api
@ -34,17 +34,17 @@ curl http://localhost:5000/api
## AJAX та отримання даних
Традиційні веб-сайти оновлюють відображений контент, коли користувач вибирає посилання або надсилає дані через форму, шляхом перезавантаження повної HTML-сторінки. Кожного разу, коли потрібно завантажити нові дані, веб-сервер повертає абсолютно нову HTML-сторінку, яку потрібно обробити браузером, перериваючи поточну дію користувача та обмежуючи взаємодії під час перезавантаження. Цей робочий процес також називається *багатосторінковим додатком* або *MPA*.
Традиційні веб-сайти оновлюють вміст, що відображається, коли користувач вибирає посилання або надсилає дані через форму, шляхом перезавантаження повної HTML-сторінки. Кожного разу, коли потрібно завантажити нові дані, веб-сервер повертає абсолютно нову HTML-сторінку, яку потрібно обробити браузером, перериваючи поточну дію користувача та обмежуючи взаємодії під час перезавантаження. Цей робочий процес також називається *багатосторінковим додатком* або *MPA*.
![Робочий процес оновлення в багатосторінковому додатку](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.uk.png)
Коли веб-додатки стали більш складними та інтерактивними, з'явилася нова техніка під назвою [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Ця техніка дозволяє веб-додаткам асинхронно надсилати та отримувати дані з сервера за допомогою JavaScript, без необхідності перезавантаження HTML-сторінки, що забезпечує швидше оновлення та плавнішу взаємодію з користувачем. Коли нові дані отримані з сервера, поточна HTML-сторінка також може бути оновлена за допомогою JavaScript через [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. З часом цей підхід еволюціонував у те, що зараз називається [*односторінковим додатком* або *SPA*](https://en.wikipedia.org/wiki/Single-page_application).
Коли веб-додатки стали більш складними та інтерактивними, з'явилася нова техніка під назвою [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Ця техніка дозволяє веб-додаткам асинхронно надсилати та отримувати дані з сервера за допомогою JavaScript, без необхідності перезавантаження HTML-сторінки, що забезпечує швидше оновлення та плавнішу взаємодію з користувачем. Коли нові дані отримуються з сервера, поточна HTML-сторінка також може бути оновлена за допомогою API [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model). З часом цей підхід еволюціонував у те, що зараз називається [*односторінковим додатком* або *SPA*](https://en.wikipedia.org/wiki/Single-page_application).
![Робочий процес оновлення в односторінковому додатку](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.uk.png)
Коли AJAX вперше був представлений, єдиним API для асинхронного отримання даних був [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Але сучасні браузери тепер також реалізують більш зручний і потужний [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), який використовує проміси та краще підходить для роботи з даними у форматі JSON.
> Хоча всі сучасні браузери підтримують `Fetch API`, якщо ви хочете, щоб ваш веб-додаток працював на старих браузерах, завжди варто перевірити [таблицю сумісності на caniuse.com](https://caniuse.com/fetch).
> Хоча всі сучасні браузери підтримують `Fetch API`, якщо ви хочете, щоб ваш веб-додаток працював на застарілих або старих браузерах, завжди варто перевірити [таблицю сумісності на caniuse.com](https://caniuse.com/fetch).
### Завдання
@ -57,7 +57,7 @@ async function login() {
}
```
Спочатку ми отримуємо елемент форми за допомогою `getElementById()`, а потім отримуємо ім'я користувача з введення через `loginForm.user.value`. Кожен елемент форми можна отримати за його ім'ям (встановленим у HTML через атрибут `name`) як властивість форми.
Спочатку ми отримуємо елемент форми за допомогою `getElementById()`, а потім отримуємо ім'я користувача з введення через `loginForm.user.value`. Кожен елемент форми можна отримати за його ім'ям (встановленим у HTML за допомогою атрибута `name`) як властивість форми.
Аналогічно до того, що ми зробили для реєстрації, ми створимо ще одну функцію для виконання запиту до сервера, але цього разу для отримання даних облікового запису:
@ -72,7 +72,7 @@ async function getAccount(user) {
}
```
Ми використовуємо `fetch` API для асинхронного запиту даних із сервера, але цього разу нам не потрібні додаткові параметри, окрім URL, оскільки ми лише запитуємо дані. За замовчуванням `fetch` створює HTTP-запит типу [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), що нам і потрібно.
Ми використовуємо `fetch` API для асинхронного запиту даних із сервера, але цього разу нам не потрібні додаткові параметри, окрім URL, оскільки ми лише запитуємо дані. За замовчуванням `fetch` створює HTTP-запит типу [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), що саме нам і потрібно.
`encodeURIComponent()` — це функція, яка екранує спеціальні символи для URL. Які проблеми можуть виникнути, якщо ми не викличемо цю функцію і використаємо значення `user` безпосередньо в URL?
@ -95,7 +95,7 @@ async function login() {
Оскільки `getAccount` є асинхронною функцією, нам потрібно використовувати ключове слово `await`, щоб дочекатися результату сервера. Як і у випадку з будь-яким запитом до сервера, ми також повинні обробляти помилки. Поки що ми просто додамо повідомлення в лог для відображення помилки, а пізніше повернемося до цього.
Потім нам потрібно зберегти дані десь, щоб пізніше використовувати їх для відображення інформації на панелі управління. Оскільки змінна `account` ще не існує, ми створимо глобальну змінну для неї на початку нашого файлу:
Потім нам потрібно зберегти дані десь, щоб пізніше використовувати їх для відображення інформації на панелі управління. Оскільки змінна `account` ще не існує, ми створимо глобальну змінну для неї у верхній частині нашого файлу:
```js
let account = null;
@ -103,7 +103,7 @@ let account = null;
Після того, як дані користувача збережені у змінній, ми можемо перейти зі сторінки *login* на *dashboard* за допомогою функції `navigate()`, яку ми вже маємо.
Нарешті, нам потрібно викликати нашу функцію `login`, коли форма входу буде надіслана, змінивши HTML:
Нарешті, нам потрібно викликати нашу функцію `login`, коли форма входу надсилається, модифікувавши HTML:
```html
<form id="loginForm" action="javascript:login()">
@ -118,23 +118,23 @@ account = result;
navigate('/dashboard');
```
✅ Чи знали ви, що за замовчуванням ви можете викликати серверні API лише з *того ж домену та порту*, що й веб-сторінка, яку ви переглядаєте? Це механізм безпеки, який забезпечують браузери. Але зачекайте, наш веб-додаток працює на `localhost:3000`, тоді як сервер API працює на `localhost:5000`. Чому це працює? Використовуючи техніку під назвою [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS), можна виконувати HTTP-запити між різними доменами, якщо сервер додає спеціальні заголовки до відповіді, дозволяючи виключення для конкретних доменів.
✅ Чи знали ви, що за замовчуванням ви можете викликати серверні API лише з *того ж домену та порту*, що й веб-сторінка, яку ви переглядаєте? Це механізм безпеки, який реалізують браузери. Але зачекайте, наш веб-додаток працює на `localhost:3000`, тоді як сервер API працює на `localhost:5000`. Чому це працює? Використовуючи техніку під назвою [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS), можна виконувати HTTP-запити між різними доменами, якщо сервер додає спеціальні заголовки до відповіді, дозволяючи виключення для конкретних доменів.
> Дізнайтеся більше про API, пройшовши цей [урок](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon).
> Дізнайтеся більше про API, пройшовши цей [урок](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon)
## Оновлення HTML для відображення даних
Тепер, коли у нас є дані користувача, нам потрібно оновити існуючий HTML, щоб відобразити їх. Ми вже знаємо, як отримати елемент із DOM, наприклад, за допомогою `document.getElementById()`. Після того, як у вас є базовий елемент, ось кілька API, які ви можете використовувати для його зміни або додавання дочірніх елементів:
Тепер, коли ми маємо дані користувача, нам потрібно оновити існуючий HTML, щоб їх відобразити. Ми вже знаємо, як отримати елемент із DOM, наприклад, за допомогою `document.getElementById()`. Після того, як у вас є базовий елемент, ось деякі API, які ви можете використовувати для його модифікації або додавання дочірніх елементів:
- Використовуючи властивість [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent), ви можете змінити текст елемента. Зверніть увагу, що зміна цього значення видаляє всіх дочірніх елементів (якщо вони є) і замінює їх на наданий текст. Таким чином, це також ефективний метод для видалення всіх дочірніх елементів даного елемента, присвоюючи йому порожній рядок `''`.
- Використовуючи [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) разом із методом [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append), ви можете створювати та прикріплювати один або кілька нових дочірніх елементів.
- Використовуючи [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) разом із методом [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append), ви можете створювати та додавати один або кілька нових дочірніх елементів.
✅ Використовуючи властивість [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) елемента, також можна змінювати його HTML-вміст, але цей метод слід уникати, оскільки він вразливий до атак [міжсайтового скриптингу (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting).
### Завдання
Перед тим як перейти до екрану панелі управління, є ще одна річ, яку ми повинні зробити на сторінці *login*. Зараз, якщо ви спробуєте увійти з ім'ям користувача, яке не існує, повідомлення показується в консолі, але для звичайного користувача нічого не змінюється, і він не знає, що відбувається.
Перед тим як перейти до екрану панелі управління, є ще одна річ, яку ми повинні зробити на сторінці *login*. Зараз, якщо ви спробуєте увійти з ім'ям користувача, яке не існує, повідомлення з'являється в консолі, але для звичайного користувача нічого не змінюється, і ви не знаєте, що відбувається.
Додамо елемент-заповнювач у форму входу, де ми можемо відображати повідомлення про помилку, якщо це необхідно. Хорошим місцем буде розташування перед кнопкою входу `<button>`:
@ -145,7 +145,7 @@ navigate('/dashboard');
...
```
Цей елемент `<div>` порожній, тобто нічого не буде відображатися на екрані, поки ми не додамо до нього якийсь вміст. Ми також надаємо йому `id`, щоб легко отримати його за допомогою JavaScript.
Цей елемент `<div>` порожній, тобто нічого не буде відображатися на екрані, поки ми не додамо до нього вміст. Ми також надаємо йому `id`, щоб легко отримати його за допомогою JavaScript.
Поверніться до файлу `app.js` і створіть нову допоміжну функцію `updateElement`:
@ -156,7 +156,7 @@ function updateElement(id, text) {
}
```
Ця функція досить проста: за заданим *id* елемента та *текстом* вона оновлює текстовий вміст DOM-елемента з відповідним `id`. Використаємо цей метод замість попереднього повідомлення про помилку у функції `login`:
Ця функція досить проста: отримавши *id* елемента та *текст*, вона оновлює текстовий вміст DOM-елемента з відповідним `id`. Використаємо цей метод замість попереднього повідомлення про помилку у функції `login`:
```js
if (data.error) {
@ -164,11 +164,11 @@ if (data.error) {
}
```
Тепер, якщо ви спробуєте увійти з недійсним обліковим записом, ви побачите щось на зразок цього:
Тепер, якщо ви спробуєте увійти з недійсним обліковим записом, ви побачите щось на кшталт цього:
![Скріншот, що показує повідомлення про помилку під час входу](../../../../translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.uk.png)
Тепер у нас є текст помилки, який відображається візуально, але якщо ви спробуєте це з екранним читачем, ви помітите, що нічого не оголошується. Щоб текст, який динамічно додається на сторінку, оголошувався екранними читачами, він повинен використовувати так звану [живу область (Live Region)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Тут ми будемо використовувати специфічний тип живої області, який називається сповіщенням:
Тепер у нас є текст помилки, який відображається візуально, але якщо ви спробуєте це з екранним читачем, ви помітите, що нічого не оголошується. Щоб текст, який динамічно додається на сторінку, оголошувався екранними читачами, він повинен використовувати щось, що називається [Live Region](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Тут ми використаємо конкретний тип live region, який називається alert:
```html
<div id="loginError" role="alert"></div>
@ -214,9 +214,9 @@ if (data.error) {
<h2 id="description"></h2>
```
✅ Оскільки опис облікового запису функціонує як заголовок для контенту під ним, він семантично позначений як заголовок. Дізнайтеся більше про те, чому [структура заголовків](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) важлива для доступності, і критично оцініть сторінку, щоб визначити, що ще може бути заголовком.
✅ Оскільки опис облікового запису функціонує як заголовок для вмісту під ним, він семантично позначений як заголовок. Дізнайтеся більше про те, чому [структура заголовків](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) важлива для доступності, і критично оцініть сторінку, щоб визначити, що ще може бути заголовком.
Далі ми створимо нову функцію в `app.js`, щоб заповнити заповнювачі:
Далі ми створимо нову функцію в `app.js`, щоб заповнити елементи-заповнювачі:
```js
function updateDashboard() {
@ -230,7 +230,7 @@ function updateDashboard() {
}
```
Спочатку ми перевіряємо, чи є у нас необхідні дані облікового запису, перш ніж продовжувати. Потім ми використовуємо функцію `updateElement()`, яку створили раніше, щоб оновити HTML.
Спочатку ми перевіряємо, чи маємо необхідні дані облікового запису, перш ніж продовжувати. Потім ми використовуємо функцію `updateElement()`, яку створили раніше, для оновлення HTML.
> Щоб зробити відображення балансу більш привабливим, ми використовуємо метод [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed), щоб примусово відображати значення з 2 цифрами після десяткової точки.
@ -297,7 +297,7 @@ function createTransactionRow(transaction) {
}
```
Ця функція робить саме те, що її назва передбачає: використовуючи шаблон, який ми створили раніше, вона створює новий рядок таблиці та заповнює його вміст даними транзакції. Ми використаємо це у функції `updateDashboard()`, щоб заповнити таблицю:
Ця функція робить саме те, що її назва передбачає: використовуючи шаблон, який ми створили раніше, вона створює новий рядок таблиці та заповнює його вміст даними транзакції. Ми використаємо це у функції `updateDashboard()` для заповнення таблиці:
```js
const transactionsRows = document.createDocumentFragment();
@ -310,7 +310,7 @@ updateElement('transactions', transactionsRows);
Тут ми використовуємо метод [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment), який створює новий фрагмент DOM, з яким ми можемо працювати, перш ніж остаточно прикріпити його до нашої HTML-таблиці.
Є ще одна річ, яку ми повинні зробити, перш ніж цей код запрацює, оскільки наша функція `updateElement()` наразі підтримує лише текстовий вміст. Змінімо її код трохи:
Є ще одна річ, яку ми повинні зробити, перш ніж цей код зможе працювати, оскільки наша функція `updateElement()` наразі підтримує лише текстовий вміст. Змінімо її код трохи:
```js
function updateElement(id, textOrNode) {
@ -320,26 +320,26 @@ function updateElement(id, textOrNode) {
}
```
Ми використовуємо метод [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append), оскільки він дозволяє прикріплювати як текст, так і [DOM-вузли](https://developer.mozilla.org/docs/Web/API/Node) до батьківського елемента, що ідеально підходить для всіх наших випадків використання.
Ми використовуємо метод [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append), оскільки він дозволяє прикріплювати як текст, так і [DOM-вузли](https://developer.mozilla.org/docs/Web/API/Node) до батьківського елемента, що ідеально підходить для всіх наших випадків
Якщо ви спробуєте увійти за допомогою облікового запису `test`, тепер ви повинні побачити список транзакцій на панелі управління 🎉.
---
## 🚀 Виклик
Працюйте разом, щоб зробити сторінку панелі управління схожою на справжній банківський додаток. Якщо ви вже стилізували свій додаток, спробуйте використати [медіа-запити](https://developer.mozilla.org/docs/Web/CSS/Media_Queries), щоб створити [адаптивний дизайн](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks), який добре працює як на настільних комп’ютерах, так і на мобільних пристроях.
Працюйте разом, щоб зробити сторінку панелі управління схожою на справжній додаток для банкінгу. Якщо ви вже стилізували свій додаток, спробуйте використати [медіа-запити](https://developer.mozilla.org/docs/Web/CSS/Media_Queries), щоб створити [адаптивний дизайн](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks), який добре працює як на настільних комп’ютерах, так і на мобільних пристроях.
Ось приклад стилізованої сторінки панелі управління:
![Скріншот прикладу результату панелі управління після стилізації](../../../../translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.uk.png)
## Тест після лекції
## Вікторина після лекції
[Тест після лекції](https://ff-quizzes.netlify.app/web/quiz/46)
[Вікторина після лекції](https://ff-quizzes.netlify.app/web/quiz/46)
## Завдання
[Рефакторизуйте та прокоментуйте свій код](assignment.md)
[Рефакторизуйте та прокоментуйте ваш код](assignment.md)
---

@ -1,17 +1,17 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4fa20c513e367e9cdd401bf49ae16e33",
"translation_date": "2025-08-27T22:04:35+00:00",
"original_hash": "5d2efabbc8f94d89f4317ee8646c3ce9",
"translation_date": "2025-08-28T18:08:21+00:00",
"source_file": "7-bank-project/4-state-management/README.md",
"language_code": "uk"
}
-->
# Створення банківського додатку, частина 4: Концепції управління станом
## Передлекційна вікторина
## Попереднє опитування
[Передлекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/47)
[Попереднє опитування](https://ff-quizzes.netlify.app/web/quiz/47)
### Вступ
@ -21,7 +21,7 @@ CO_OP_TRANSLATOR_METADATA:
### Передумови
Вам потрібно завершити частину [отримання даних](../3-data/README.md) веб-додатку для цього уроку. Також необхідно встановити [Node.js](https://nodejs.org) і [запустити сервер API](../api/README.md) локально, щоб ви могли управляти даними облікового запису.
Вам потрібно завершити [отримання даних](../3-data/README.md) у веб-додатку для цього уроку. Також необхідно встановити [Node.js](https://nodejs.org) і [запустити сервер API](../api/README.md) локально, щоб ви могли управляти даними облікового запису.
Ви можете перевірити, чи сервер працює належним чином, виконавши цю команду в терміналі:
@ -40,9 +40,9 @@ curl http://localhost:5000/api
- Стан не зберігається, оскільки оновлення браузера повертає вас на сторінку входу.
- Є кілька функцій, які змінюють стан. Зі зростанням додатку це може ускладнити відстеження змін, і легко забути оновити одну з них.
- Стан не очищується, тому коли ви натискаєте *Вийти*, дані облікового запису все ще залишаються, хоча ви перебуваєте на сторінці входу.
- Стан не очищається, тому коли ви натискаєте *Вийти*, дані облікового запису все ще залишаються, навіть якщо ви перебуваєте на сторінці входу.
Ми могли б оновити наш код, щоб вирішити ці проблеми по черзі, але це створило б більше дублювання коду і зробило додаток складнішим для підтримки. Або ми могли б зупинитися на кілька хвилин і переосмислити нашу стратегію.
Ми могли б оновити наш код, щоб вирішити ці проблеми по одному, але це створило б більше дублювання коду і зробило додаток більш складним і важким для підтримки. Або ми могли б зупинитися на кілька хвилин і переосмислити нашу стратегію.
> Які проблеми ми насправді намагаємося вирішити?
@ -51,7 +51,7 @@ curl http://localhost:5000/api
- Як зробити потоки даних у додатку зрозумілими?
- Як забезпечити синхронізацію даних стану з інтерфейсом користувача (і навпаки)?
Як тільки ви вирішите ці проблеми, будь-які інші проблеми, які можуть виникнути, або вже будуть вирішені, або стануть легшими для вирішення. Існує багато можливих підходів для вирішення цих проблем, але ми скористаємося загальним рішенням, яке полягає у **централізації даних і способів їх зміни**. Потоки даних виглядатимуть так:
Як тільки ви вирішите ці проблеми, будь-які інші проблеми, які можуть виникнути, або вже будуть вирішені, або стануть легшими для вирішення. Існує багато можливих підходів для вирішення цих проблем, але ми оберемо загальне рішення, яке полягає у **централізації даних і способів їх зміни**. Потоки даних виглядатимуть так:
![Схема, що показує потоки даних між HTML, діями користувача і станом](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.uk.png)
@ -91,7 +91,7 @@ const account = state.account;
Тепер, коли ми створили об'єкт `state` для зберігання наших даних, наступним кроком є централізація оновлень. Мета полягає у тому, щоб зробити легшим відстеження будь-яких змін і моментів, коли вони відбуваються.
Щоб уникнути внесення змін до об'єкта `state`, також хорошою практикою є вважати його [*незмінним*](https://en.wikipedia.org/wiki/Immutable_object), тобто таким, який взагалі не можна змінювати. Це також означає, що вам потрібно створити новий об'єкт стану, якщо ви хочете щось у ньому змінити. Роблячи це, ви створюєте захист від потенційно небажаних [побічних ефектів](https://en.wikipedia.org/wiki/Side_effect_(computer_science)), і відкриваєте можливості для нових функцій у вашому додатку, таких як реалізація undo/redo, а також спрощуєте налагодження. Наприклад, ви могли б реєструвати кожну зміну стану і зберігати історію змін, щоб зрозуміти джерело помилки.
Щоб уникнути змін у об'єкті `state`, також хорошою практикою є вважати його [*незмінним*](https://en.wikipedia.org/wiki/Immutable_object), тобто таким, який взагалі не можна змінювати. Це також означає, що вам потрібно створити новий об'єкт стану, якщо ви хочете щось у ньому змінити. Роблячи це, ви створюєте захист від потенційно небажаних [побічних ефектів](https://en.wikipedia.org/wiki/Side_effect_(computer_science)), і відкриваєте можливості для нових функцій у вашому додатку, таких як реалізація undo/redo, а також спрощуєте налагодження. Наприклад, ви могли б реєструвати кожну зміну стану і зберігати історію змін, щоб зрозуміти джерело помилки.
У JavaScript ви можете використовувати [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) для створення незмінної версії об'єкта. Якщо ви спробуєте внести зміни до незмінного об'єкта, буде викликано виняток.
@ -99,7 +99,7 @@ const account = state.account;
### Завдання
Створимо нову функцію `updateState()`:
Давайте створимо нову функцію `updateState()`:
```js
function updateState(property, newData) {
@ -110,7 +110,7 @@ function updateState(property, newData) {
}
```
У цій функції ми створюємо новий об'єкт стану і копіюємо дані з попереднього стану за допомогою [*оператора розпакування (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Потім ми перевизначаємо конкретну властивість об'єкта стану новими даними, використовуючи [нотацію з квадратними дужками](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` для присвоєння. Нарешті, ми блокуємо об'єкт, щоб запобігти модифікаціям, використовуючи `Object.freeze()`. Зараз у стані зберігається лише властивість `account`, але з таким підходом ви можете додати стільки властивостей, скільки вам потрібно.
У цій функції ми створюємо новий об'єкт стану і копіюємо дані з попереднього стану за допомогою [*оператора розгортання (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Потім ми перевизначаємо конкретну властивість об'єкта стану новими даними, використовуючи [нотацію квадратних дужок](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` для присвоєння. Нарешті, ми блокуємо об'єкт, щоб запобігти модифікаціям, використовуючи `Object.freeze()`. Зараз у стані зберігається лише властивість `account`, але з таким підходом ви можете додати стільки властивостей, скільки вам потрібно.
Також оновимо ініціалізацію `state`, щоб переконатися, що початковий стан також заморожений:
@ -132,7 +132,7 @@ updateState('account', result);
updateState('account', data);
```
Тепер скористаємося можливістю вирішити проблему, коли дані облікового запису не очищуються, коли користувач натискає *Вийти*.
Тепер скористаємося можливістю вирішити проблему з даними облікового запису, які не очищаються, коли користувач натискає *Вийти*.
Створіть нову функцію `logout()`:
@ -143,22 +143,22 @@ function logout() {
}
```
У `updateDashboard()` замініть перенаправлення `return navigate('/login');` на `return logout();`;
У `updateDashboard()` замініть перенаправлення `return navigate('/login');` на `return logout();`
Спробуйте зареєструвати новий обліковий запис, вийти і знову увійти, щоб переконатися, що все працює правильно.
Спробуйте зареєструвати новий обліковий запис, вийти і знову увійти, щоб перевірити, чи все працює правильно.
> Порада: ви можете переглянути всі зміни стану, додавши `console.log(state)` в кінці `updateState()` і відкривши консоль у засобах розробки вашого браузера.
## Збереження стану
Більшість веб-додатків потребують збереження даних для коректної роботи. Усі критичні дані зазвичай зберігаються в базі даних і доступні через серверний API, як у випадку з даними облікового запису користувача. Але іноді також цікаво зберігати деякі дані в клієнтському додатку, який працює у вашому браузері, для покращення досвіду користувача або підвищення продуктивності завантаження.
Більшість веб-додатків потребують збереження даних для коректної роботи. Усі критичні дані зазвичай зберігаються в базі даних і доступні через серверний API, як у нашому випадку з даними облікового запису користувача. Але іноді також цікаво зберігати деякі дані в клієнтському додатку, який працює у вашому браузері, для покращення досвіду користувача або підвищення продуктивності завантаження.
Коли ви хочете зберігати дані у вашому браузері, є кілька важливих питань, які варто задати собі:
- *Чи є дані конфіденційними?* Ви повинні уникати зберігання будь-яких конфіденційних даних на клієнті, таких як паролі користувачів.
- *Як довго вам потрібно зберігати ці дані?* Ви плануєте отримувати доступ до цих даних лише протягом поточного сеансу чи хочете, щоб вони зберігалися назавжди?
Існує кілька способів зберігання інформації всередині веб-додатку, залежно від того, що ви хочете досягти. Наприклад, ви можете використовувати URL-адреси для зберігання пошукового запиту і зробити його доступним для інших користувачів. Ви також можете використовувати [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies), якщо дані потрібно передавати на сервер, наприклад, інформацію про [автентифікацію](https://en.wikipedia.org/wiki/Authentication).
Існує кілька способів зберігання інформації всередині веб-додатку, залежно від того, що ви хочете досягти. Наприклад, ви можете використовувати URL-адреси для зберігання пошукового запиту і зробити його доступним для спільного використання між користувачами. Ви також можете використовувати [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies), якщо дані потрібно передавати на сервер, наприклад, інформацію для [автентифікації](https://en.wikipedia.org/wiki/Authentication).
Ще один варіант — використовувати один із багатьох API браузера для зберігання даних. Два з них особливо цікаві:
@ -167,7 +167,7 @@ function logout() {
Зверніть увагу, що обидва ці API дозволяють зберігати лише [рядки](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Якщо ви хочете зберігати складні об'єкти, вам потрібно буде серіалізувати їх у формат [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) за допомогою [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
✅ Якщо ви хочете створити веб-додаток, який не працює з сервером, також можливо створити базу даних на клієнті за допомогою API [`IndexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Цей варіант зарезервований для складних випадків використання або якщо вам потрібно зберігати значну кількість даних, оскільки він складніший у використанні.
✅ Якщо ви хочете створити веб-додаток, який не працює з сервером, також можливо створити базу даних на клієнті, використовуючи API [`IndexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Цей варіант зарезервований для складних випадків використання або якщо вам потрібно зберігати значну кількість даних, оскільки він складніший у використанні.
### Завдання
@ -221,7 +221,7 @@ curl --request POST \
http://localhost:5000/api/accounts/test/transactions
```
Спробуйте оновити сторінку інформаційної панелі у браузері зараз. Що відбувається? Ви бачите нову транзакцію?
Тепер спробуйте оновити сторінку інформаційної панелі у браузері. Що відбувається? Ви бачите нову транзакцію?
Стан зберігається безстроково завдяки `localStorage`, але це також означає, що він ніколи не оновлюється, поки ви не вийдете з додатку і знову не увійдете!
@ -247,7 +247,7 @@ async function updateAccountData() {
}
```
Цей метод перевіряє, чи ми зараз увійшли в систему, а потім перезавантажує дані облікового запису з сервера.
Цей метод перевіряє, чи ви зараз увійшли в систему, а потім перезавантажує дані облікового запису з сервера.
Створіть ще одну функцію під назвою `refresh`:
@ -267,26 +267,22 @@ const routes = {
};
```
Спробуйте оновити інформаційну панель зараз, вона повинна відображати оновлені дані облікового запису.
Тепер спробуйте оновити інформаційну панель, вона повинна відображати оновлені дані облікового запису.
---
## 🚀 Виклик
Тепер, коли ми перезавантажуємо дані облікового запису кожного разу, коли завантажується інформаційна панель, як ви думаєте, чи нам все ще потрібно зберігати *всі дані облікового запису*?
Спробуйте раз
[Післялекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/48)
## Завдання
Тепер, коли ми перезавантажуємо дані облікового запису кожного разу, коли завантажується інформаційна панель, як ви думаєте, чи потрібно нам все ще зберігати *всі дані облікового запису*?
Спробуйте разом зм
[Реалізуйте діалогове вікно "Додати транзакцію"](assignment.md)
Ось приклад результату після виконання завдання:
![Знімок екрана, що показує приклад діалогового вікна "Додати транзакцію"](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.uk.png)
![Скріншот, що показує приклад діалогового вікна "Додати транзакцію"](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.uk.png)
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ було перекладено за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, зверніть увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ мовою оригіналу слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний переклад людиною. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "7aa6e4f270d38d9cb17f2b5bd86b863d",
"translation_date": "2025-08-27T22:40:45+00:00",
"original_hash": "1ba61d96a11309a2a6ea507496dcf7e5",
"translation_date": "2025-08-28T18:19:57+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/README.md",
"language_code": "uk"
}
@ -11,7 +11,7 @@ CO_OP_TRANSLATOR_METADATA:
Цей урок охоплює основи використання [VSCode.dev](https://vscode.dev), веб-редактора коду, щоб ви могли вносити зміни до свого коду та брати участь у проєкті без необхідності встановлювати щось на свій комп'ютер.
## Навчальні цілі
## Цілі навчання
У цьому уроці ви навчитеся:
@ -19,7 +19,7 @@ CO_OP_TRANSLATOR_METADATA:
- Відстежувати зміни за допомогою системи контролю версій
- Налаштовувати редактор для розробки
### Передумови
### Попередні вимоги
Перед початком вам потрібно створити обліковий запис на [GitHub](https://github.com). Перейдіть на [GitHub](https://github.com/) і створіть обліковий запис, якщо у вас його ще немає.
@ -55,21 +55,21 @@ CO_OP_TRANSLATOR_METADATA:
![Open remote repository](../../../../translated_images/open-remote-repository.bd9c2598b8949e7fc283cdfc8f4050c6205a7c7c6d3f78c4b135115d037d6fa2.uk.png)
Ви також можете скористатися командною палітрою. Командна палітра — це поле введення, де ви можете ввести будь-яке слово, яке є частиною команди або дії, щоб знайти потрібну команду для виконання. Використовуйте меню у верхньому лівому куті, потім виберіть _View_, а потім _Command Palette_, або скористайтеся наступним сполученням клавіш: Ctrl-Shift-P (на MacOS — Command-Shift-P).
Ви також можете скористатися командною палітрою. Командна палітра — це поле введення, де ви можете ввести будь-яке слово, яке є частиною команди або дії, щоб знайти потрібну команду для виконання. Використовуйте меню у верхньому лівому куті, потім виберіть _View_, а потім _Command Palette_, або скористайтеся наступним комбінацією клавіш: Ctrl-Shift-P (на MacOS — Command-Shift-P).
![Palette Menu](../../../../translated_images/palette-menu.4946174e07f426226afcdad707d19b8d5150e41591c751c45b5dee213affef91.uk.png)
Після відкриття меню введіть _open remote repository_, а потім виберіть перший варіант. З'являться кілька репозиторіїв, до яких ви належите або які відкривали раніше. Ви також можете використати повну URL-адресу GitHub, щоб вибрати один із них. Використайте наступну URL-адресу та вставте її у поле:
Після відкриття меню введіть _open remote repository_, а потім виберіть перший варіант. З'являться кілька репозиторіїв, до яких ви належите або які ви відкривали раніше. Ви також можете використати повну URL-адресу GitHub, щоб вибрати один із них. Використайте наступну URL-адресу та вставте її у поле:
```
https://github.com/microsoft/Web-Dev-For-Beginners
```
✅ Якщо все успішно, ви побачите всі файли цього репозиторію, завантажені у текстовий редактор.
✅ Якщо все пройшло успішно, ви побачите всі файли цього репозиторію, завантажені у текстовий редактор.
### 2. Використовуючи URL-адресу
### 2. Використання URL-адреси
Ви також можете використовувати URL-адресу для завантаження репозиторію. Наприклад, повна URL-адреса поточного репозиторію — [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners), але ви можете замінити домен GitHub на `VSCode.dev/github` і завантажити репозиторій безпосередньо. Отримана URL-адреса буде [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners).
Ви також можете використовувати URL-адресу безпосередньо для завантаження репозиторію. Наприклад, повна URL-адреса поточного репозиторію — [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners), але ви можете замінити домен GitHub на `VSCode.dev/github` і завантажити репозиторій безпосередньо. Отримана URL-адреса буде [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners).
## Редагування файлів
@ -83,21 +83,21 @@ https://github.com/microsoft/Web-Dev-For-Beginners
### 2. Редагування та збереження файлу в репозиторії
Використання vscode.dev корисне, коли вам потрібно швидко оновити свій проєкт без необхідності завантажувати будь-яке програмне забезпечення локально.
Використання vscode.dev корисне, коли вам потрібно швидко оновити свій проєкт без завантаження будь-якого програмного забезпечення локально.
Щоб оновити код, натисніть іконку 'Explorer', також розташовану на панелі активності, щоб переглянути файли та папки в репозиторії.
Виберіть файл, щоб відкрити його в області коду, внесіть зміни та збережіть.
![Edit a file](../../../../translated_images/edit-a-file.52c0ee665ef19f08119d62d63f395dfefddc0a4deb9268d73bfe791f52c5807a.uk.png)
Після завершення оновлення проєкту виберіть іконку _`source control`_, яка містить усі нові зміни, внесені до вашого репозиторію.
Після завершення оновлення проєкту виберіть іконку _`source control`_, яка містить усі нові зміни, які ви внесли до репозиторію.
Щоб переглянути зміни, внесені до вашого проєкту, виберіть файл(и) у папці `Changes` на розширеній панелі активності. Це відкриє 'Робоче дерево', де ви зможете візуально побачити зміни, внесені до файлу. Червоний колір показує видалення з проєкту, а зелений — додавання.
Щоб переглянути зміни, які ви внесли до проєкту, виберіть файл(и) у папці `Changes` на розширеній панелі активності. Це відкриє 'Робоче дерево', де ви зможете візуально побачити зміни, внесені до файлу. Червоний колір показує видалення з проєкту, а зелений — додавання.
![View changes](../../../../translated_images/working-tree.c58eec08e6335c79cc708c0c220c0b7fea61514bd3c7fb7471905a864aceac7c.uk.png)
Якщо вас задовольняють внесені зміни, наведіть курсор на папку `Changes` і натисніть кнопку `+`, щоб підготувати зміни до коміту. Підготовка означає підготовку ваших змін для їхнього коміту до GitHub.
Якщо ви задоволені внесеними змінами, наведіть курсор на папку `Changes` і натисніть кнопку `+`, щоб підготувати зміни до коміту. Підготовка означає підготовку ваших змін для їхнього коміту до GitHub.
Якщо ж вас не влаштовують деякі зміни і ви хочете їх скасувати, наведіть курсор на папку `Changes` і виберіть іконку `undo`.
Якщо ж ви не задоволені деякими змінами і хочете їх скасувати, наведіть курсор на папку `Changes` і виберіть іконку `undo`.
Потім введіть `commit message` _(Опис змін, які ви внесли до проєкту)_, натисніть іконку `check`, щоб закомітити та відправити зміни.
@ -114,7 +114,7 @@ https://github.com/microsoft/Web-Dev-For-Beginners
![Extension details](../../../../translated_images/extension-details.9f8f1fd4e9eb2de5069ae413119eb8ee43172776383ebe2f7cf640e11df2e106.uk.png)
Ви також можете переглянути всі раніше встановлені розширення, розширення, популярні серед розробників, у папці _`Popular`_, а також рекомендовані розширення для вас — або користувачами у тому ж робочому просторі, або на основі ваших нещодавно відкритих файлів — у папці _`Recommended`_.
Ви також можете переглянути всі раніше встановлені розширення, розширення, популярні серед більшості розробників, у папці _`Popular`_, а також рекомендовані розширення для вас — або від користувачів у тому ж робочому просторі, або на основі ваших нещодавно відкритих файлів — у папці _`Recommended`_.
![View extensions](../../../../translated_images/extensions.eca0e0c7f59a10b5c88be7fe24b3e32cca6b6058b35a49026c3a9d80b1813b7c.uk.png)
@ -136,11 +136,11 @@ https://github.com/microsoft/Web-Dev-For-Beginners
Після встановлення та використання розширення vscode.dev пропонує варіанти управління розширенням залежно від різних потреб. Наприклад, ви можете:
- **Вимкнути:** _(Тимчасово вимкнути розширення, якщо воно вам більше не потрібне, але ви не хочете повністю його видаляти)_
- **Вимкнути:** _(Ви тимчасово вимикаєте розширення, коли більше не потребуєте його, але не хочете повністю видаляти)_
Виберіть встановлене розширення на розширеній панелі активності > натисніть на Gear icon > виберіть 'Disable' або 'Disable (Workspace)' **АБО** відкрийте розширення в області коду та натисніть синю кнопку Disable.
Виберіть встановлене розширення на розширеній панелі активності > натисніть Gear icon > виберіть 'Disable' або 'Disable (Workspace)' **АБО** відкрийте розширення в області коду та натисніть синю кнопку Disable.
- **Видалити:** Виберіть встановлене розширення на розширеній панелі активності > натисніть на Gear icon > виберіть 'Uninstall' **АБО** відкрийте розширення в області коду та натисніть синю кнопку Uninstall.
- **Видалити:** Виберіть встановлене розширення на розширеній панелі активності > натисніть Gear icon > виберіть 'Uninstall' **АБО** відкрийте розширення в області коду та натисніть синю кнопку Uninstall.
---
@ -155,4 +155,4 @@ https://github.com/microsoft/Web-Dev-For-Beginners
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

@ -1,29 +1,40 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2fcb983b8dbadadb1bc2e97f8c12dac5",
"translation_date": "2025-08-27T22:42:09+00:00",
"original_hash": "bd3aa6d2b879c30ea496c43aec1c49ed",
"translation_date": "2025-08-28T18:20:39+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/assignment.md",
"language_code": "uk"
}
-->
# Створення резюме-сайту за допомогою vscode.dev
_Як круто було б, якщо рекрутер попросить ваше резюме, а ви надішлете їм посилання?_ 😎
_Як круто було б, якби рекрутер попросив ваше резюме, а ви просто надіслали йому посилання?_ 😎
<!----
TODO: додати необов'язкове зображення
![Використання редактора коду](../../../../translated_images/webdev101-vscode-dev.f53c14e8dad231ea09d9e07a2db4a01551d2dc6cdf21225038389e11156af023.uk.png)
> Скечнот від [Ім'я автора](https://example.com)
---->
<!---
## Передлекційна вікторина
[Передлекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/3)
---->
## Цілі
Після виконання цього завдання ви навчитеся:
Після цього завдання ви навчитеся:
- Створювати вебсайт для демонстрації вашого резюме
### Попередні вимоги
1. Обліковий запис GitHub. Перейдіть на [GitHub](https://github.com/) і створіть обліковий запис, якщо у вас його ще немає.
1. Обліковий запис на GitHub. Перейдіть на [GitHub](https://github.com/) і створіть обліковий запис, якщо у вас його ще немає.
## Кроки
**Крок 1:** Створіть новий репозиторій на GitHub і назвіть його `my-resume`.
**Крок 1:** Створіть новий репозиторій на GitHub і дайте йому назву `my-resume`
**Крок 2:** Створіть файл `index.html` у вашому репозиторії. Ми додамо хоча б один файл безпосередньо на github.com, оскільки ви не можете відкрити порожній репозиторій у vscode.dev.
@ -33,7 +44,7 @@ _Як круто було б, якщо рекрутер попросить ва
**Крок 3:** Відкрийте [VSCode.dev](https://vscode.dev) і виберіть кнопку `Open Remote Repository`.
Скопіюйте URL-адресу репозиторію, який ви щойно створили для вашого сайту резюме, і вставте її в поле вводу:
Скопіюйте URL-адресу репозиторію, який ви щойно створили для вашого сайту-резюме, і вставте її у вхідне поле:
_Замініть `your-username` на ваше ім'я користувача GitHub._
@ -41,14 +52,14 @@ _Замініть `your-username` на ваше ім'я користувача G
https://github.com/your-username/my-resume
```
✅ Якщо все успішно, ви побачите ваш проект і файл index.html, відкритий у текстовому редакторі в браузері.
✅ Якщо все вдалося, ви побачите ваш проєкт і файл index.html, відкритий у текстовому редакторі у браузері.
![Створення нового файлу](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.uk.png)
**Крок 4:** Відкрийте файл `index.html`, вставте код нижче у ваш кодовий простір і збережіть.
<details>
<summary><b>HTML-код, який відповідає за контент вашого сайту резюме.</b></summary>
<summary><b>HTML-код, відповідальний за вміст вашого сайту-резюме.</b></summary>
<html>
@ -62,25 +73,25 @@ https://github.com/your-username/my-resume
<!-- заголовок резюме з вашим ім'ям і посадою -->
<h1>Ваше ім'я тут!</h1>
<hr>
Ваша роль!
Ваша посада!
<hr>
</header>
<main>
<article id="mainLeft">
<section>
<h2>КОНТАКТИ</h2>
<!-- контактна інформація, включаючи соціальні мережі -->
<!-- контактна інформація, включаючи соцмережі -->
<p>
<i class="fa fa-envelope" aria-hidden="true"></i>
<a href="mailto:username@domain.top-level domain">Введіть вашу електронну пошту тут</a>
<a href="mailto:username@domain.top-level domain">Вкажіть ваш email тут</a>
</p>
<p>
<i class="fab fa-github" aria-hidden="true"></i>
<a href="github.com/yourGitHubUsername">Введіть ваше ім'я користувача тут!</a>
<a href="github.com/yourGitHubUsername">Вкажіть ваше ім'я користувача тут!</a>
</p>
<p>
<i class="fab fa-linkedin" aria-hidden="true"></i>
<a href="linkedin.com/yourLinkedInUsername">Введіть ваше ім'я користувача тут!</a>
<a href="linkedin.com/yourLinkedInUsername">Вкажіть ваше ім'я користувача тут!</a>
</p>
</section>
<section>
@ -96,9 +107,9 @@ https://github.com/your-username/my-resume
<section>
<h2>ОСВІТА</h2>
<!-- ваша освіта -->
<h3>Введіть ваш курс тут!</h3>
<h3>Вкажіть ваш курс тут!</h3>
<p>
Введіть ваш навчальний заклад тут!
Вкажіть ваш навчальний заклад тут!
</p>
<p>
Початок - Кінець
@ -108,8 +119,8 @@ https://github.com/your-username/my-resume
<article id="mainRight">
<section>
<h2>ПРО МЕНЕ</h2>
<!-- про вас -->
<p>Напишіть коротко про себе!</p>
<!-- інформація про вас -->
<p>Напишіть кілька слів про себе!</p>
</section>
<section>
<h2>ДОСВІД РОБОТИ</h2>
@ -119,9 +130,9 @@ https://github.com/your-username/my-resume
Назва організації тут | Місяць початку Місяць закінчення
</p>
<ul>
<li>Завдання 1 - Напишіть, що ви робили!</li>
<li>Завдання 2 - Напишіть, що ви робили!</li>
<li>Напишіть результати/вплив вашого внеску</li>
<li>Завдання 1 - Опишіть, що ви робили!</li>
<li>Завдання 2 - Опишіть, що ви робили!</li>
<li>Опишіть результати/вплив вашого внеску</li>
</ul>
<h3>Посада 2</h3>
@ -129,9 +140,9 @@ https://github.com/your-username/my-resume
Назва організації тут | Місяць початку Місяць закінчення
</p>
<ul>
<li>Завдання 1 - Напишіть, що ви робили!</li>
<li>Завдання 2 - Напишіть, що ви робили!</li>
<li>Напишіть результати/вплив вашого внеску</li>
<li>Завдання 1 - Опишіть, що ви робили!</li>
<li>Завдання 2 - Опишіть, що ви робили!</li>
<li>Опишіть результати/вплив вашого внеску</li>
</ul>
</section>
@ -143,12 +154,12 @@ https://github.com/your-username/my-resume
Додайте деталі вашого резюме, замінивши екст-заповнювач_ у HTML-коді.
**Крок 5:** Наведіть курсор на папку My-Resume, натисніть на іконку `New File ...` і створіть 2 нові файли у вашому проекті: `style.css` і `codeswing.json`.
**Крок 5:** Наведіть курсор на папку My-Resume, натисніть іконку `New File ...` і створіть 2 нові файли у вашому проєкті: `style.css` і `codeswing.json`.
**Крок 6:** Відкрийте файл `style.css`, вставте код нижче і збережіть.
<details>
<summary><b>CSS-код для форматування макету сайту.</b></summary>
<summary><b>CSS-код для форматування макета сайту.</b></summary>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
@ -170,7 +181,7 @@ https://github.com/your-username/my-resume
h3 {
font-size: 1em;
padding-bottom: 1em;
padding-bottom: 1ем;
}
main {
display: grid;
@ -217,31 +228,36 @@ https://github.com/your-username/my-resume
"styles": []
}
**Крок 7:** Встановіть розширення `Codeswing`, щоб візуалізувати сайт резюме у кодовому просторі.
**Крок 7:** Встановіть розширення `Codeswing`, щоб візуалізувати сайт-резюме у кодовому просторі.
Натисніть на іконку _`Extensions`_ на панелі активності та введіть Codeswing. Натисніть _синю кнопку встановлення_ на розширеній панелі активності або використайте кнопку встановлення, яка з'явиться у кодовому просторі після вибору розширення для завантаження додаткової інформації. Після встановлення розширення спостерігайте за змінами у вашому проекті 😃.
Натисніть іконку _`Extensions`_ на панелі активності та введіть Codeswing. Натисніть _синю кнопку встановлення_ на розширеній панелі активності або використайте кнопку встановлення, яка з'явиться у кодовому просторі після вибору розширення. Після встановлення розширення спостерігайте за змінами у вашому проєкті 😃.
![Встановлення розширень](../../../../8-code-editor/images/install-extension.gif)
Ось що ви побачите на екрані після встановлення розширення.
![Розширення Codeswing в дії](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.uk.png)
![Розширення Codeswing у дії](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.uk.png)
Якщо ви задоволені внесеними змінами, наведіть курсор на папку `Changes` і натисніть кнопку `+`, щоб зафіксувати зміни.
Якщо ви задоволені внесеними змінами, наведіть курсор на папку `Changes` і натисніть кнопку `+`, щоб додати зміни.
Введіть повідомлення про коміт _(Опис змін, які ви внесли до проекту)_ і зафіксуйте зміни, натиснувши на `check`. Після завершення роботи над проектом виберіть іконку меню гамбургер у верхньому лівому куті, щоб повернутися до репозиторію на GitHub.
Введіть повідомлення коміту _(Опис змін, які ви внесли до проєкту)_ і зафіксуйте зміни, натиснувши `check`. Після завершення роботи над проєктом виберіть іконку меню-гамбургер у верхньому лівому куті, щоб повернутися до репозиторію на GitHub.
Вітаємо 🎉 Ви щойно створили сайт резюме за допомогою vscode.dev у кілька кроків.
Вітаємо 🎉 Ви щойно створили свій сайт-резюме за допомогою vscode.dev у кілька кроків.
## 🚀 Виклик
Відкрийте віддалений репозиторій, до якого у вас є права на внесення змін, і оновіть кілька файлів. Далі спробуйте створити нову гілку зі своїми змінами та зробити Pull Request.
Відкрийте віддалений репозиторій, до якого у вас є права на внесення змін, і оновіть деякі файли. Далі спробуйте створити нову гілку зі своїми змінами та зробити Pull Request.
<!----
## Післялекційна вікторина
[Післялекційна вікторина](https://ff-quizzes.netlify.app/web/quiz/4)
---->
## Огляд і самостійне навчання
Дізнайтеся більше про [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) та його інші функції.
Дізнайтеся більше про [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) та інші його функції.
---
**Відмова від відповідальності**:
Цей документ було перекладено за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, зверніть увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ мовою оригіналу слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний переклад людиною. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

@ -0,0 +1,389 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "cf15ff7770c5a484349383bb27d1131f",
"translation_date": "2025-08-28T18:54:59+00:00",
"source_file": "9-chat-project/README.md",
"language_code": "uk"
}
-->
# Проєкт чату
Цей проєкт чату демонструє, як створити Чат-асистента за допомогою GitHub Models.
Ось як виглядає готовий проєкт:
<div>
<img src="./assets/screenshot.png" alt="Додаток чату" width="600">
</div>
Трохи контексту: створення чат-асистентів за допомогою генеративного ШІ — це чудовий спосіб почати вивчати штучний інтелект. У цьому уроці ви навчитеся інтегрувати генеративний ШІ у веб-додаток. Почнемо.
## Підключення до генеративного ШІ
Для бекенду ми використовуємо GitHub Models. Це чудовий сервіс, який дозволяє безкоштовно використовувати ШІ. Перейдіть до його "пісочниці" (playground) і скопіюйте код, що відповідає вашій обраній мові програмування для бекенду. Ось як це виглядає: [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground)
<div>
<img src="./assets/playground.png" alt="Пісочниця GitHub Models AI" with="600">
</div>
Як ми вже зазначали, оберіть вкладку "Code" і ваш обраний runtime.
<div>
<img src="./assets/playground-choice.png" alt="вибір у пісочниці" with="600">
</div>
У цьому випадку ми обираємо Python, що означає, що ми використовуємо цей код:
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
# Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "",
},
{
"role": "user",
"content": "What is the capital of France?",
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
print(response.choices[0].message.content)
```
Давайте трохи очистимо цей код, щоб зробити його більш зручним для повторного використання:
```python
def call_llm(prompt: str, system_message: str):
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": system_message,
},
{
"role": "user",
"content": prompt,
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
return response.choices[0].message.content
```
З цією функцією `call_llm` ми тепер можемо передати підказку (prompt) і системну підказку, а функція поверне результат.
### Налаштування ШІ-асистента
Якщо ви хочете налаштувати ШІ-асистента, ви можете вказати, як саме він має поводитися, заповнивши системну підказку ось так:
```python
call_llm("Tell me about you", "You're Albert Einstein, you only know of things in the time you were alive")
```
## Відкриття через Web API
Чудово, ми завершили частину з ШІ, тепер подивимося, як інтегрувати це у Web API. Для Web API ми обираємо Flask, але підійде будь-який веб-фреймворк. Ось код:
```python
# api.py
from flask import Flask, request, jsonify
from llm import call_llm
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
@app.route("/", methods=["GET"])
def index():
return "Welcome to this API. Call POST /hello with 'message': 'my message' as JSON payload"
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
```
Тут ми створюємо API на Flask і визначаємо маршрути "/" та "/chat". Останній призначений для використання нашим фронтендом для передачі запитань.
Щоб інтегрувати *llm.py*, ось що потрібно зробити:
- Імпортувати функцію `call_llm`:
```python
from llm import call_llm
from flask import Flask, request
```
- Викликати її з маршруту "/chat":
```python
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
```
Тут ми розбираємо вхідний запит, щоб отримати властивість `message` з JSON-тіла. Після цього ми викликаємо LLM за допомогою цього виклику:
```python
response = call_llm(message, "You are a helpful assistant")
# return the response as JSON
return jsonify({
"response": response
})
```
Чудово, тепер ми зробили все необхідне.
### Налаштування Cors
Варто зазначити, що ми налаштували щось на кшталт CORS (Cross-Origin Resource Sharing). Це означає, що оскільки наш бекенд і фронтенд працюватимуть на різних портах, нам потрібно дозволити фронтенду звертатися до бекенду. У файлі *api.py* є код, який це налаштовує:
```python
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
```
Зараз це налаштовано для дозволу "*" (усіх джерел), що є трохи небезпечним. Ми повинні обмежити це, коли перейдемо до продакшну.
## Запуск проєкту
Отже, у нас є *llm.py* і *api.py*. Як це запустити з бекендом? Є два кроки:
- Встановити залежності:
```sh
cd backend
python -m venv venv
source ./venv/bin/activate
pip install openai flask flask-cors openai
```
- Запустити API:
```sh
python api.py
```
Якщо ви працюєте в Codespaces, потрібно перейти до Ports у нижній частині редактора, клацнути правою кнопкою миші та вибрати "Port Visibility", а потім "Public".
### Робота над фронтендом
Тепер, коли наш API працює, створимо фронтенд. Мінімальний фронтенд, який ми будемо покращувати поступово. У папці *frontend* створіть наступне:
```text
backend/
frontend/
index.html
app.js
styles.css
```
Почнемо з **index.html**:
```html
<html>
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<form>
<textarea id="messages"></textarea>
<input id="input" type="text" />
<button type="submit" id="sendBtn">Send</button>
</form>
<script src="app.js" />
</body>
</html>
```
Це мінімум, необхідний для підтримки вікна чату. Він складається з текстової області, де відображатимуться повідомлення, поля вводу для введення повідомлення та кнопки для надсилання вашого повідомлення на бекенд. Тепер подивимося на JavaScript у файлі *app.js*.
**app.js**
```js
// app.js
(function(){
// 1. set up elements
const messages = document.getElementById("messages");
const form = document.getElementById("form");
const input = document.getElementById("input");
const BASE_URL = "change this";
const API_ENDPOINT = `${BASE_URL}/hello`;
// 2. create a function that talks to our backend
async function callApi(text) {
const response = await fetch(API_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: text })
});
let json = await response.json();
return json.response;
}
// 3. add response to our textarea
function appendMessage(text, role) {
const el = document.createElement("div");
el.className = `message ${role}`;
el.innerHTML = text;
messages.appendChild(el);
}
// 4. listen to submit events
form.addEventListener("submit", async(e) => {
e.preventDefault();
// someone clicked the button in the form
// get input
const text = input.value.trim();
appendMessage(text, "user")
// reset it
input.value = '';
const reply = await callApi(text);
// add to messages
appendMessage(reply, "assistant");
})
})();
```
Розглянемо код по секціях:
- 1) Тут ми отримуємо посилання на всі елементи, до яких будемо звертатися пізніше в коді.
- 2) У цій секції ми створюємо функцію, яка використовує вбудований метод `fetch` для виклику нашого бекенду.
- 3) `appendMessage` допомагає додавати відповіді, а також те, що ви вводите як користувач.
- 4) Тут ми слухаємо подію submit, читаємо поле вводу, розміщуємо повідомлення користувача в текстовій області, викликаємо API і відображаємо відповідь у текстовій області.
Тепер подивимося на стилізацію. Тут ви можете проявити креативність і зробити все, як вам подобається, але ось кілька пропозицій:
**styles.css**
```
.message {
background: #222;
box-shadow: 0 0 0 10px orange;
padding: 10px:
margin: 5px;
}
.message.user {
background: blue;
}
.message.assistant {
background: grey;
}
```
З цими трьома класами ви зможете стилізувати повідомлення залежно від того, звідки вони надходять — від асистента чи від вас як користувача. Якщо вам потрібне натхнення, перегляньте папку `solution/frontend/styles.css`.
### Зміна базової URL-адреси
Є одна річ, яку ми ще не налаштували, — це `BASE_URL`. Вона стане відомою лише після запуску вашого бекенду. Щоб налаштувати її:
- Якщо ви запускаєте API локально, вона має виглядати приблизно так: `http://localhost:5000`.
- Якщо ви запускаєте в Codespaces, вона має виглядати приблизно так: "[name]app.github.dev".
## Завдання
Створіть власну папку *project* з таким вмістом:
```text
project/
frontend/
index.html
app.js
styles.css
backend/
api.py
llm.py
```
Скопіюйте вміст із вказівок вище, але не соромтеся налаштовувати його на свій смак.
## Рішення
[Рішення](./solution/README.md)
## Бонус
Спробуйте змінити особистість ШІ-асистента. Коли ви викликаєте `call_llm` у файлі *api.py*, ви можете змінити другий аргумент на те, що вам потрібно, наприклад:
```python
call_llm(message, "You are Captain Picard")
```
Також змініть CSS і текст на свій смак, тобто внесіть зміни у *index.html* і *styles.css*.
## Підсумок
Чудово, ви навчилися з нуля створювати персонального асистента за допомогою ШІ. Ми зробили це, використовуючи GitHub Models, бекенд на Python і фронтенд на HTML, CSS і JavaScript.
## Налаштування в Codespaces
- Перейдіть до: [Web Dev For Beginners repo](https://github.com/microsoft/Web-Dev-For-Beginners)
- Створіть із шаблону (переконайтеся, що ви увійшли в GitHub) у верхньому правому куті:
![Створити з шаблону](../../../translated_images/template.67ad477109d29a2b04599a83c964c87fcde041256d4f04d3589cbb00c696f76c.uk.png)
- Як тільки ви опинитеся у своєму репозиторії, створіть Codespace:
![Створити Codespace](../../../translated_images/codespace.bcecbdf5d2747d3d17da67a78ad911c8853d68102e34748ec372cde1e9236e1d.uk.png)
Це має запустити середовище, з яким ви тепер можете працювати.
---
**Відмова від відповідальності**:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save