Merge pull request #146 from silverskyvicto/translate-ja/3-terrarium

translate 3-terrarium into japanese
pull/148/head
Jen Looper 4 years ago committed by GitHub
commit 9ccd6e3f2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,231 @@
# テラリウムプロジェクト その1: HTML 入門
![Introduction to HTML](images/webdev101-html.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
[レクチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/15)
### イントロダクション
HTML (HyperText Markup Language) は、Web の「骨格」です。CSS が HTML を「ドレスアップ」し、JavaScript が HTML に命を吹き込むとすれば、HTML は Web アプリケーションの本体となります。HTML の構文は、「head」、「body」、「footer」タグを含むため、この考えを反映しています。
このレッスンでは、HTML を使ってバーチャルテラリウムのインターフェースの「骨格」をレイアウトします。タイトルと3つのカラムがあります。右と左のカラムにはドラッグ可能な植物を配置し、中央のエリアには実際のガラス張りのテラリウムを配置します。このレッスンが終わる頃には、列の中に植物が見えるようになると思いますが、インターフェースが少し変な感じになっているかもしれません。
### タスク
コンピュータ上に 'terrarium' というフォルダを作成し、その中に 'index.html' というファイルを作成します。テラリウムのフォルダを作成した後、Visual Studio Code で新しい VS Code ウィンドウを開き、「フォルダを開く」をクリックして新しいフォルダに移動することで、この作業を行うことができます。エクスプローラペインの「ファイル」ボタンをクリックして、新しいファイルを作成してください。
![explorer in VS Code](images/vs-code-index.png)
もしくは
git bash 上でこれらのコマンドを使用します。
* `mkdir terrarium`
* `cd terrarium`
* `touch index.html`
* `code index.html` または `nano index.html`
> index.html ファイルはブラウザに対して、それがフォルダ内のデフォルトファイルであることを示します。`https://anysite.com/test` のような URL は、`test` というフォルダを含むフォルダ構造を用いて構築され、その中に `index.html` が含まれているかもしれません。
---
## DocType と html タグ
HTML ファイルの最初の行は、その doctype です。ファイルの一番上にこの行が必要なのは少し意外ですが、これはブラウザが現在の HTML 仕様に従った標準モードでページをレンダリングする必要があることを古いブラウザに伝えています。
> ヒント: VS Code では、タグの上にカーソルを置くと MDN リファレンスガイドからタグの使用に関する情報を得ることができます。
2行目は `<html>` タグのオープニングタグであり、それに続くのがクロージングタグ `</html>` です。これらのタグはインターフェイスのルート要素です。
### タスク
これらの行を `index.html` ファイルの先頭に追加します。
```HTML
<!DOCTYPE html>
<html></html>
```
✅ DocType をクエリ文字列で設定することで決定できるモードがいくつかあります。[Quirks モードと Standards モード](https://developer.mozilla.org/ja/docs/Web/HTML/Quirks_Mode_and_Standards_Mode)です。これらのモードは、現在では通常使用されていない本当に古いブラウザ (Netscape Navigator 4 と Internet Explorer 5) をサポートしていました。標準の doctype 宣言に固執することができます。
---
## ドキュメントの 'head'
HTML ドキュメントの 'head' 領域には、Web ページに関する重要な情報が含まれており、[メタデータ](https://developer.mozilla.org/ja/docs/Web/HTML/Element/meta)としても知られています。私たちの場合、このページがレンダリングされるために送信される Web サーバーに、以下の4つのことを伝えます。
- ページタイトル
- 次を含むページのメタデータ:
- 'character set' で、ページで使われている文字エンコーディングを表します
- IE=edge ブラウザがサポートされていることを示す `x-ua-compatible` などのブラウザ情報
- viewport が読み込まれたときにどのように振る舞うかについての情報を提供します。viewport の初期スケールを 1 に設定すると、ページが最初に読み込まれたときのズームレベルを制御します
### タスク
ドキュメントに 'head' ブロックを `<html>` の開始タグと終了タグの間に追加します。
```html
<head>
<title>Welcome to my Virtual Terrarium</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
```
✅ このように viewport の meta タグを設定するとどうなるでしょうか: `<meta name="viewport" content="width=600">`? [viewport](https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag) についてはこちらをご覧ください。
---
## ドキュメントの `body`
### HTML タグ
HTML では、.html ファイルにタグを追加して Web ページの要素を作成します。それぞれのタグには通常、次のような開閉タグがあります。段落を示す `<p>hello</p>` のように。`<html>` タグペアの中に `<body>` タグのセットを追加して、インターフェイスのボディを作成します。
### タスク
```html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to my Virtual Terrarium</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body></body>
</html>
```
これで、ページの構築を始めることができます。通常は `<div>` タグを使ってページ内の個別の要素を作成します。ここでは画像を含む一連の `<div>` 要素を作成します。
### 画像
閉じタグを必要としない html タグの一つに `<img>` タグがあります。なぜなら、ページがアイテムをレンダリングするために必要なすべての情報を含む `src` 要素を持っているからです。
アプリ内に `images` というフォルダを作成し、その中に[ソースコードフォルダ](../solution/images)内のすべての画像を追加します (植物の画像が14枚あります)。
### タスク
これらの植物の画像を `<body></body>` タグの間の2つのカラムに追加します。
```html
<div id="page">
<div id="left-container" class="container">
<div class="plant-holder">
<img class="plant" alt="plant" id="plant1" src="./images/plant1.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant2" src="./images/plant2.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant3" src="./images/plant3.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant4" src="./images/plant4.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant5" src="./images/plant5.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant6" src="./images/plant6.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant7" src="./images/plant7.png" />
</div>
</div>
<div id="right-container" class="container">
<div class="plant-holder">
<img class="plant" alt="plant" id="plant8" src="./images/plant8.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant9" src="./images/plant9.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant10" src="./images/plant10.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant11" src="./images/plant11.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant12" src="./images/plant12.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant13" src="./images/plant13.png" />
</div>
<div class="plant-holder">
<img class="plant" alt="plant" id="plant14" src="./images/plant14.png" />
</div>
</div>
</div>
```
> 注: Span と Div。Div は「ブロック」要素とみなされ、Span は「インライン」要素とみなされます。これらの Div を Spans に変換するとどうなるでしょうか。
このマークアップで、植物が画面に表示されるようになりました。まだ CSS を使ったスタイリングがされていないので、かなり見栄えが悪いのですが、これは次のレッスンで行います。
それぞれの画像には、画像が見えなくてもレンダリングできなくても表示される alt テキストがあります。これはアクセシビリティのために重要な属性です。アクセシビリティについては、今後のレッスンで詳しく説明します。今のところ、alt 属性は、何らかの理由でユーザーが画像を見ることができない場合 (接続速度が遅い、src 属性のエラー、ユーザーがスクリーンリーダーを使用している場合) に、画像の代替情報を提供することを覚えておいてください。
✅ それぞれの画像に同じ alt タグが付いていることに気付きましたか?これは良い習慣ですか?なぜですか、それともなぜですか? このコードを改善できますか?
---
## セマンティックマークアップ
一般的に、HTML を書くときには、意味のある「セマンティックス」を使うことが望ましいとされています。これはどういう意味でしょうか? それは、HTML タグを使用して、データやインタラクションの種類を表すために設計されていることを意味します。例えば、ページのメインタイトルテキストには `<h1>` タグを使うべきです。
`<body>` の開始タグのすぐ下に次の行を追加します。
```html
<h1>My Terrarium</h1>
```
ヘッダーを `<h1>` としたり、順序のないリストを `<ul>` とするなど、セマンティックマークアップを使用することで、スクリーンリーダーがページをナビゲートするのに役立ちます。一般的に、ボタンは `<button>` と書き、リストは `<li>` と書くべきです。特別なスタイルの `<span>` 要素とクリックハンドラを使ってボタンを模擬することは可能ですが、障害のあるユーザにとっては、ボタンがページ上のどこにあるかを判断し、要素がボタンとして表示されている場合にそれと対話するための技術を使った方が良いでしょう。このため、できるだけセマンティックマークアップを使うようにしてください。
✅ スクリーンリーダーと[それがどのようにウェブページと相互作用するか](https://www.youtube.com/watch?v=OUDV1gqs9GA)を見てみましょう。意味のないマークアップがあると、なぜユーザーをイライラさせてしまうのかわかりますか?
## テラリウム
このインターフェイスの最後の部分では、テラリウムを作成するためのマークアップを作成します。
### タスク
このマークアップを最後の `</div>` タグの上に追加します。
```html
<div id="terrarium">
<div class="jar-top"></div>
<div class="jar-walls">
<div class="jar-glossy-long"></div>
<div class="jar-glossy-short"></div>
</div>
<div class="dirt"></div>
<div class="jar-bottom"></div>
</div>
```
✅ このマークアップを画面に追加したにもかかわらず、何も表示されません。なぜでしょうか?
---
## チャレンジ
HTMLに はまだ遊んで楽しいワイルドな「古い」タグがいくつかありますが、[これらのタグ](https://developer.mozilla.org/ja/docs/Web/HTML/Element#Obsolete_and_deprecated_elements)のような非推奨のタグをマークアップに使うべきではありません。それでも、古い `<marquee>` タグを使って h1 タイトルを水平方向にスクロールさせることはできますか?(もしそうする場合は、後から削除することを忘れないでください)
## レクチャー後クイズ
[レクチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/16)
## 復習と自己学習
HTML は、今日のウェブを構築するのに役立ってきた「試行錯誤された」ビルディングブロックシステムです。古いタグと新しいタグを研究することで、その歴史について少し学びましょう。あるタグが非推奨になり、あるタグが追加された理由がわかりますか?将来的にはどのようなタグが導入されるかもしれませんか?
Web やモバイル向けのサイト構築については、[Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=cxaall-4621-cxall) で詳しく解説しています。
## 課題
[HTML の練習: ブログのモックアップを構築する](assignment.ja.md)

@ -0,0 +1,11 @@
# HTML の練習: ブログのモックアップを構築する
## 説明書
個人的な Web サイトをデザインしたり、再デザインしたりしていると想像してみてください。サイトのグラフィカルなマークアップを作成し、サイトの様々な要素を構築するために使用する HTML マークアップを書き留めてください。紙に書いてスキャンしてもいいですし、お好みのソフトウェアを使ってもいいですが、HTML マークアップを手でコーディングして確認してください。
## ルーブリック
| 基準 | 模範的な例 | 適切な | 改善が必要 |
| -------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| | ブログのレイアウトは、少なくとも10個のマークアップ要素が表示された状態で視覚的に表現されます。 | ブログのレイアウトは、マークアップの要素を5つほど表示して視覚的に表現する | ブログのレイアウトは、最大でも3つのマークアップ要素が表示された状態で視覚的に表現されます。 |

@ -0,0 +1,264 @@
# テラリウムプロジェクト その2: CSS 入門
![Introduction to CSS](images/webdev101-css.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
[レクチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/17)
### イントロダクション
CSS (カスケードスタイルシート) は、Web 開発の重要な問題である、Web サイトの見栄えを良くする方法を解決します。また、CSS を使用してレスポンシブ ウェブ デザイン (RWD) を作成することもできます。CSS の仕様には、アプリケーションの洗練されたインタラクションを可能にするアニメーションや変換が含まれています。CSS Working Group は現在の CSS 仕様の維持を支援しており、[World Wide Web Consortium のサイト](https://www.w3.org/Style/CSS/members) でその活動を追うことができます。
> 注: CSS は Web 上のすべてのものと同様に進化する言語であり、すべてのブラウザが仕様の新しい部分をサポートしているわけではありません。常に [CanIUse.com](caniuse.com) に相談して実装を確認してください。
このレッスンでは、オンラインテラリウムにスタイルを追加し、カスケード、継承、セレクタの使用、配置、CSS を使ったレイアウトの作成など、CSS の概念について学びます。その過程で、テラリウムをレイアウトし、実際のテラリウムを作成していきます。
### 前提条件
テラリウムの HTML が完成し、スタイリングの準備が整っています。
### タスク
テラリウムのフォルダに `style.css` というファイルを作成します。そのファイルを `<head>` セクションにインポートしてください。
```html
<link rel="stylesheet" href="./style.css" />
```
---
## カスケード
カスケーディングスタイルシートは、スタイルの適用がその優先度によって導かれるように、スタイルが「カスケード」するという考えを取り入れています。Web サイトの作者によってセットされたスタイルはブラウザによってセットされたそれらより優先されます。「インライン」にセットされたスタイルは外部スタイルシートにセットされたものより優先されます。
### タスク
インラインスタイル "color: red" を `<h1>` タグに追加します。
```HTML
<h1 style="color: red">My Terrarium</h1>
```
次に、以下のコードを `style.css` ファイルに追加します。
```CSS
h1 {
color: blue;
}
```
✅ Web アプリではどの色が表示されますか? なぜですか? スタイルを上書きする方法を見つけることはできますか? いつ、またはなぜそうしたくないのですか?
---
## 継承
スタイルは、先祖のスタイルから子孫へと継承され、入れ子になった要素は親のスタイルを継承するようになっています。
### タスク
body のフォントを指定されたフォントに設定し、入れ子になっている要素のフォントを確認します。
```
body {
font-family: helvetica, arial, sans-serif;
}
```
ブラウザのコンソールから「要素」タブを開き、h1 のフォントを観察してください。ブラウザ内で述べられているように、フォントは body から継承されています。
![inherited font](images/1.png)
✅ 入れ子になったスタイルを別のプロパティを継承させることはできますか?
---
## CSS セレクタ
### タグ
これまでのところ、`style.css` ファイルにはいくつかのタグがスタイリングされているだけで、アプリはかなり変な感じになっています。
```
body {
font-family: helvetica, arial, sans-serif;
}
h1 {
color: #3a241d;
text-align: center;
}
```
このようにタグをスタイリングすることで、ユニークな要素をコントロールすることができますが、テラリウム内の多くの植物のスタイルをコントロールする必要があります。そのためには、CSS セレクタを利用する必要があります。
### Id
Add some style to layout the left and right containers. Since there is only one left container and only one right container, they are given ids in the markup. To style them, use `#`:
左と右のコンテナをレイアウトするためのスタイルを追加します。左のコンテナと右のコンテナは1つしかないので、マークアップでは id が与えられます。スタイルを設定するには、`#` を使用します。
```
#left-container {
background-color: #eee;
width: 15%;
left: 0px;
top: 0px;
position: absolute;
height: 100%;
padding: 10px;
}
#right-container {
background-color: #eee;
width: 15%;
right: 0px;
top: 0px;
position: absolute;
height: 100%;
padding: 10px;
}
```
ここでは、これらのコンテナを画面の左端と右端に絶対的な位置に配置し、それらが小さなモバイル画面のためにスケーリングできるように、それらの幅にパーセンテージを使用しています。
✅ このコードはかなり繰り返されているので、"DRY" (Don't Repeat Yourself) ではありません。マークアップを変更し、CSS をリファクタリングする必要があるでしょう。
```html
<div id="left-container" class="container"></div>
```
### クラス
上の例では、画面上の2つのユニークな要素にスタイルを設定しました。画面上の多くの要素にスタイルを適用したい場合は、CSS クラスを使用することができます。これを実行して、左右のコンテナに植物をレイアウトします。
HTML マークアップの各植物には、id とクラスの組み合わせがあることに注目してください。ここでの id は、テラリウムの植物の配置を操作するために後で追加する JavaScript によって使用されます。クラスはすべての植物にスタイルを与えています。
```html
<div class="plant-holder">
<img class="plant" alt="plant" id="plant1" src="./images/plant1.png" />
</div>
```
以下を `style.css` ファイルに追加します。
```css
.plant-holder {
position: relative;
height: 13%;
left: -10px;
}
.plant {
position: absolute;
max-width: 150%;
max-height: 150%;
z-index: 2;
}
```
このスニペットで注目すべきは、相対位置と絶対位置が混在していることです。高さをパーセンテージで処理する方法を見てみましょう。
プラントホルダーの高さを 13% に設定します。これは、すべての植物がスクロールせずに各垂直コンテナに表示されるようにするための良い数字です。
植物ホルダーを左に移動するように設定すると、植物がその容器の中でより中央に位置するようになります。画像は、それらをよりドラッグしやすいように、大量の透明な背景を持っているので、画面上でより良くフィットするように左に押される必要があります。
次に、植物自体には 150% の最大幅が与えられています。これにより、ブラウザのスケールダウンに合わせて植物を縮小することができます。ブラウザのサイズを変更してみてください。
また、注目すべきは、(植物が容器の上に座ってテラリウムの中に座っているように見えるように) 要素の相対的な高度を制御する z-index の使用です。
✅ なぜ、植物のホルダーと植物の CSS セレクターの両方が必要なのでしょうか?
## CSS ポジショニング
位置のプロパティ (静的位置、相対位置、固定位置、絶対位置、スティッキー位置があります) を混ぜるのは少し厄介ですが、適切に行うと、ページ上の要素をうまくコントロールすることができます。
絶対的な位置にある要素は、最も近い位置にある祖先からの相対的な位置に配置され、存在しない場合は、ドキュメントの本文に従って配置されます。
相対的に配置された要素は、CSS の指示に基づいて初期位置から離れた位置に配置されます。
今回のサンプルでは、`plant-holder` は相対的に配置された要素であり、絶対的に配置されたコンテナの中に配置されている。その結果、サイドバーのコンテナは左右に固定され、植物ホルダーは入れ子になってサイドバー内で調整され、植物を縦に並べるためのスペースが与えられています。
> 次のレッスンで説明するように、`plant` 自体も絶対位置を持っており、ドラッグ可能にするために必要です。
✅ サイドコンテナとプランターホルダーの配置の種類を入れ替えて実験してみてください。どうなるでしょうか?
## CSS レイアウト
ここでは、学んだことを活かして、CSS を使ってテラリウムを作っていきます。
まず、CSS を使って `.terarium` div の子要素を丸みを帯びた四角形にします。
```css
.jar-walls {
height: 80%;
width: 60%;
background: #d1e1df;
border-radius: 10%;
position: absolute;
bottom: 0.5%;
left: 20%;
opacity: 0.5;
z-index: 1;
}
.jar-top {
width: 50%;
height: 5%;
background: #d1e1df;
position: absolute;
bottom: 80.5%;
left: 25%;
opacity: 0.7;
z-index: 1;
}
.jar-bottom {
width: 50%;
height: 1%;
background: #d1e1df;
position: absolute;
bottom: 0%;
left: 25%;
opacity: 0.7;
}
.dirt {
width: 58%;
height: 5%;
background: #3a241d;
position: absolute;
border-radius: 0 0 4rem 4rem;
bottom: 1%;
left: 21%;
opacity: 0.7;
z-index: -1;
}
```
ここでは `border-radius` にもパーセンテージを使用していることに注意してください。ブラウザを縮小すると、瓶のコーナーも拡大縮小されているのがわかります。また、ジャー要素の幅と高さのパーセンテージと、各要素がビューポートの下部に固定されていることにも注目してください。
✅ 瓶の色と不透明度を変えてみてください。どうなりましたか?なぜですか?
---
## 🚀チャレンジ
瓶の左下の部分に「泡」のような輝きを加えて、よりガラスのように見えるようにします。`.jar-glossy-long` と `.jar-glossy-short` は反射光のように見えるようにスタイリングします。このようになります。
![finished terrarium](./images/terrarium-final.png)
レクチャー後クイズを完成させるには、この Learn モジュールを通ってください: [HTML アプリを CSS でスタイルを整える](https://docs.microsoft.com/ja-jp/learn/modules/build-simple-website/4-css-basics)
## レクチャー後クイズ
[レクチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/18)
## 復習と自己学習
CSS は一見簡単そうに見えますが、アプリをすべてのブラウザとすべての画面サイズに完全に対応させようとすると、多くの課題があります。CSS グリッド と Flexbox は、この作業をもう少し構造化し、より信頼性の高いものにするために開発されたツールです。[Flexbox Froggy](https://flexboxfroggy.com/) と [Grid Garden](https://codepip.com/games/grid-garden/) をプレイして、これらのツールについて学びましょう。
## 課題
[CSS リファクタリング](assignment.ja.md)

@ -0,0 +1,11 @@
# CSS リファクタリング
## 説明
Flexbox または CSS グリッドを使ってテラリウムのスタイルを変更し、いくつかのブラウザでテストしたことを示すためにスクリーンショットを撮影してください。マークアップを変更する必要があるかもしれないので、リファクタリングのためにアートを配置した新しいバージョンのアプリを作成してください。要素をドラッグ可能にすることは気にしないで、今のところは HTML と CSS をリファクタリングするだけです。
## ルーブリック
| 基準 | 模範的な例 | 適切な | 改善が必要 |
| -------- | ----------------------------------------------------------------- | ----------------------------- | ------------------------------------ |
| | Flexbox や CSS グリッドを使ってテラリウムのスタイルを完全に変更したものを紹介します。 | いくつかの要素のスタイルを変更します。 | テラリウムのリスタイルに失敗します。 |

@ -0,0 +1,217 @@
# テラリウムプロジェクト その3: DOM の操作とクロージャ
![DOM and a closure](images/webdev101-js.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## レクチャー前クイズ
[レクチャー前クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/19)
### イントロダクション
DOM (Document Object Model) を操作することは、Web 開発の重要な要素です。[MDN](https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction) によると、"Document Object Model (DOM) は、Web 上のドキュメントの構造とコンテンツを構成するオブジェクトのデータ表現である" とのことです。Web 上での DOM 操作の難しさから、バニラ JavaScript ではなく、JavaScript のフレームワークを使って DOM を管理することが多くなっていますが、ここでは自分たちで管理していきましょう!
また、このレッスンでは、[JavaScript クロージャ](https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures)という考え方を紹介します。これは、関数を別の関数で囲んで、内側の関数が外側の関数のスコープにアクセスできるようにしたものと考えてください。
> JavaScript のクロージャは広大で複雑なトピックです。このレッスンでは、このテラリウムのコードの中にクロージャがある、すなわち内側の関数と外側の関数は、内側の関数が外側の関数のスコープにアクセスできるように構築されているという最も基本的な考え方に触れます。これがどのように動作するかについての詳細な情報は [詳細なドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures) を参照してください。
クロージャを使って DOM を操作します。
DOM をツリーと考え、Web ページのドキュメントを操作できるすべての方法を表しています。様々な API (Application Program Interfaces) が書かれており、プログラマーが自分の好きなプログラミング言語を使って DOM にアクセスし、編集、変更、再配置、その他の管理ができるようになっています。
![DOM tree representation](./images/dom-tree.png)
> DOM とそれを参照する HTML マークアップの表現。[Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites) より
このレッスンでは、ユーザーがページ上の植物を操作できるようにする JavaScript を作成して、インタラクティブなテラリウムプロジェクトを完成させます。
### 前提条件
テラリウムの HTML と CSS が完成しているはずです。このレッスンが終わる頃には、植物をドラッグしてテラリウムの中に入れたり出したりできるようになります。
### タスク
terrarium フォルダ内に `script.js` というファイルを作成します。このファイルを `<head>` セクションにインポートします。
```html
<script src="./script.js" defer></script>
```
> 注: HTML ファイルが完全に読み込まれた後にのみ JavaScript を実行できるようにするために、外部の JavaScript ファイルを HTML ファイルにインポートする際には `defer` を使用してください。また、`async` 属性を使用することもできます。これは HTML ファイルのパース中にスクリプトを実行できるようにしますが、私たちの場合は、ドラッグスクリプトを実行する前に HTML 要素を完全に利用できるようにしておくことが重要です。
---
## DOM 要素
まず最初に必要なのは、DOM で操作したい要素への参照を作成することです。私たちの場合、それらは現在サイドバーで待機している14個の植物です。
### タスク
```html
dragElement(document.getElementById('plant1'));
dragElement(document.getElementById('plant2'));
dragElement(document.getElementById('plant3'));
dragElement(document.getElementById('plant4'));
dragElement(document.getElementById('plant5'));
dragElement(document.getElementById('plant6'));
dragElement(document.getElementById('plant7'));
dragElement(document.getElementById('plant8'));
dragElement(document.getElementById('plant9'));
dragElement(document.getElementById('plant10'));
dragElement(document.getElementById('plant11'));
dragElement(document.getElementById('plant12'));
dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
```
何が起こっているのでしょうか? ドキュメントを参照し、特定の ID を持つ要素を見つけるために DOM を調べています。HTML の最初のレッスンで、各植物画像に個別の ID (`id="plant1"`) を与えたことを覚えていますか? 今度はその努力を利用してみましょう。各要素を識別した後、その項目を `dragElement` という関数に渡します。これで、HTML 内の要素がドラッグ可能になりました。
✅ なぜ Id で要素を参照するのか? なぜ CSS クラスではなく Id で要素を参照するのでしょうか? この質問に答えるには、前回の CSS のレッスンを参照してください。
---
## クロージャ
これで、内部の関数や関数 (ここでは3つの関数) を囲む外部関数である dragElement クロージャを作成する準備が整いました。
クロージャは、1つ以上の関数が外部関数のスコープにアクセスする必要がある場合に便利です。以下に例を示します。
```javascript
function displayCandy(){
let candy = ['jellybeans'];
function addCandy(candyType) {
candy.push(candyType)
}
addCandy('gumdrops');
}
displayCandy();
console.log(candy)
```
この例では、displayCandy 関数は、新しい candy 型を関数内に既に存在する配列にプッシュする関数を囲んでいます。このコードを実行した場合、`candy` 配列はローカル変数 (クロージャのローカル) であるため、未定義になってしまいます。
✅ 配列 `candy` にアクセスできるようにするにはどうすればよいでしょうか? クロージャの外に移動させてみてください。こうすることで、配列がグローバルになり、クロージャのローカルスコープでのみ利用できるようになります。
### タスク
`script.js` の要素宣言の下に、関数を作成します。
```javascript
function dragElement(terrariumElement) {
//スクリーン上の位置のための 4 つの位置を置きます
let pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
terrariumElement.onpointerdown = pointerDrag;
}
```
`dragElement` はスクリプトの先頭にある宣言から `terrariumElement` オブジェクトを取得します。そして、関数に渡されたオブジェクトのローカル位置を `0` に設定します。これらは、クロージャ内で各要素にドラッグ&ドロップ機能を追加する際に、各要素に対して操作されるローカル変数です。テラリウムにはこれらの要素がドラッグされて配置されるので、アプリケーションはこれらの要素がどこに配置されたかを把握しておく必要があります。
さらに、この関数に渡された terrariumElement には `pointerdown` イベントが割り当てられており、これは DOM の管理を支援するために設計された [Web API](https://developer.mozilla.org/ja/docs/Web/API) の一部です。`onpointerdown` は、ボタンが押されたとき、あるいはドラッグ可能な要素がタッチされたときに発生します。このイベントハンドラは、いくつかの例外を除いて、[Web ブラウザとモバイルブラウザ](https://caniuse.com/?search=onpointerdown)の両方で動作します。
✅ [イベントハンドラの `onclick`](https://developer.mozilla.org/ja/docs/Web/API/GlobalEventHandlers/onclick) はクロスブラウザに対応しています。ここで使用する理由は何でしょうか? ここで作成しようとしているスクリーンインタラクションの正確なタイプを考えてみてください。
---
## Pointerdrag 関数
テラリウム要素をドラッグする準備ができました。イベント `onpointerdown` が発生すると、関数 pointerDrag が呼び出されます。この行のすぐ下にこの関数を追加します: `terrariumElement.onpointerdown = pointerDrag;`
### Task
```javascript
function pointerDrag(e) {
e.preventDefault();
console.log(e);
pos3 = e.clientX;
pos4 = e.clientY;
}
```
いくつかのことが起こります。まず、`e.preventDefault();` を使用してポインタダウン時に通常発生するデフォルトのイベントが発生しないようにします。このようにして、インターフェイスの動作をより制御することができます。
> スクリプトファイルを完全にビルドした後、この行に戻って `e.preventDefault()` を使わずに試してみてください - どうなりますか?
次に、ブラウザのウィンドウで `index.html` を開き、インターフェイスを調べる。植物をクリックすると、'e' イベントがどのように捕捉されているかを確認することができます。イベントを掘り下げて、1つのポインタダウンイベントでどれだけの情報が集まっているかを確認してみましょう!
次に、ローカル変数 `pos3``pos4` が e.clientX に設定されていることに注目してください。`e` の値はインスペクションペインで見つけることができます。これらの値は、植物をクリックしたり触ったりした瞬間の x と y の座標を取得します。植物をクリックしたりドラッグしたりしたときの動作を細かく制御する必要があるので、その座標を把握しておく必要があります。
✅ なぜこのアプリ全体が1つの大きなクロージャで構築されているのかがより明確になってきていますか? そうでないとしたら、どのようにして14個のドラッグ可能な植物のそれぞれのスコープを維持するのでしょうか?
`pos4 = e.clientY` の下にポインタイベントの操作を2つ追加して、初期関数を完成させます。
```html
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
```
これで、植物を移動させる際にポインタに沿って植物をドラッグし、植物の選択を解除したときにドラッグジェスチャを停止させたいことを示していることになります。`onpointermove` と `onpointerup` はすべて `onpointerdown` と同じ API の一部である。まだ `elementDrag``stopElementDrag` 関数が定義されていないので、インターフェイスはエラーをスローします。
## elementDrag 関数と stopElementDrag 関数
植物をドラッグしてドラッグを停止したときに何が起こるかを処理する内部関数をさらに 2 つ追加して、クロージャを完成させます。あなたが望む動作は、任意の植物をいつでもドラッグして、画面上のどこにでも配置できるようにすることです。このインターフェイスは、植物を追加、削除、再配置することで、あなたが好きなように正確にあなたのテラリウムをデザインできるようにするために、かなり非オピニオン的です (例えば、ドロップゾーンはありません)。
### タスク
関数 `elementDrag``pointerDrag` の閉じ括弧の直後に追加する。
```javascript
function elementDrag(e) {
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
console.log(pos1, pos2, pos3, pos4);
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
}
```
この関数では、外部関数でローカル変数として設定した初期位置14の編集を多く行います。ここで何が起こっているのでしょうか?
ドラッグしながら `pos1``pos3` (先ほど `e.clientX` と設定したもの) から現在の `e.clientX` の値を引いた値に等しくすることで再指定します。同様の操作を `pos2` に行います。次に、`pos3` と `pos4` を要素の新しい X 座標と Y 座標にリセットします。これらの変更は、ドラッグしながらコンソールで見ることができます。次に、植物の css スタイルを操作して `pos1``pos2` の新しい位置をもとに植物の新しい位置を設定し、植物のオフセットと新しい位置を比較して植物の上下左右の X 座標を計算します。
> `offsetTop``offsetLeft` は CSS のプロパティで、要素の位置を親の位置に基づいて設定します。親は `static` として配置されていない要素であれば何でも構いません。
このように位置を再計算することで、テラリウムとその植物の挙動を微調整することができます。
### タスク
インターフェースを完成させるための最後のタスクは、`elementDrag` の中括弧を閉じた後に `stopElementDrag` 関数を追加することです。
```javascript
function stopElementDrag() {
document.onpointerup = null;
document.onpointermove = null;
}
```
この小さな関数は `onpointerup``onpointermove` イベントをリセットし、植物のドラッグを再開して植物の進行を再開するか、新しい植物のドラッグを開始するようにします。
✅ これらのイベントを null に設定しないとどうなるのでしょうか?
これでプロジェクトが完成しました!
🥇おめでとうございます。素敵なテラリウムが完成しましたね。 ![finished terrarium](./images/terrarium-final.png)
---
## チャレンジ
新しいイベントハンドラをクロージャに追加して、植物にもっと何かをするようにします。例えば、植物をダブルクリックして前の方に持ってきます。創造力を発揮してください。
## レクチャー後クイズ
[レクチャー後クイズ](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/20)
## 復習と自己学習
画面の周りに要素をドラッグすることは些細なことのように思えますが、これには多くの方法があり、求める効果に応じて多くの落とし穴があります。実際、試してみることができる[ドラッグ&ドロップ API](https://developer.mozilla.org/ja/docs/Web/API/HTML_Drag_and_Drop_API) があります。このモジュールでは使用しませんでしたが、自分のプロジェクトでこの API を試してみて、何ができるか見てみてください。
ポインタイベントの詳細は [W3C docs](https://www.w3.org/TR/pointerevents1/) や [MDN web docs](https://developer.mozilla.org/ja/docs/Web/API/Pointer_events) を参照してください。
常に [CanIUse.com](https://caniuse.com/) でブラウザの機能を確認してください。
## 課題
[DOM をもう少し使いこなす](assignment.ja.md)

@ -0,0 +1,11 @@
# DOM をもう少し使いこなす
## 説明書
DOM 要素を「採用」することで、もう少し DOM を研究してみましょう。MSDN の [DOM インターフェイス一覧](https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model)にアクセスして、一つ選びます。それが Web 上の Web サイトで使われているのを Web 上で見つけて、それがどのように使われているかの説明を書きます。
## ルーブリック
| 基準 | 模範的な例 | 適切な | 改善が必要 |
| -------- | --------------------------------------------- | ------------------------------------------------ | ----------------------- |
| | 段落書きを例に挙げて紹介します。 | 例示せずに、段落書きを提示 | 書き込みはありません。 |

@ -0,0 +1,33 @@
# マイテラリウム: JavaScript を使った HTML・CSS・DOM 操作を学ぶプロジェクト 🌵🌱
ちょっとしたドラッグ&ドロップのコードメディテーション。少しの HTML、JS、CSS で、Web インターフェースを構築し、スタイルを設定し、インタラクションを追加することができます。
![my terrarium](images/screenshot_gray.png)
# レッスン
1. [HTML 入門](./1-intro-to-html/README.md)
2. [CSS 入門](./2-intro-to-css/README.md)
3. [DOM と JS Closures の紹介](./3-intro-to-DOM-and-closures/README.md)
## クレジット
Written with ♥️ by [Jen Looper](https://www.twitter.com/jenlooper)
CSS で作ったテラリウムは、Jakub Mandra のガラス瓶 [codepen](https://codepen.io/Rotarepmi/pen/rjpNZY) にインスパイアされています。
アートワークは [Jen Looper](http://jenlooper.com) が Procreate を使って手書きで描いたものです。
## テラリウムのデプロイ
Azure Static Web Apps を使ってテラリウムをデプロイしたり、ウェブに公開したりすることができます。
1. このリポジトリをフォークします
2. このボタンを押します
[![Deploy to Azure button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/?feature.customportal=false&WT.mc_id=cxaall-4621-cxall#create/Microsoft.StaticApp)
3. アプリを作成するウィザードに沿って進みます。アプリのルートを `/solution` またはコードベースのルートに設定してください。このアプリには API はありませんので、追加については心配しないでください。フォークされたレポに .github フォルダが作成され、Azure Static Web Apps のビルドサービスのビルドを支援し、新しい URL にアプリを公開します。
Loading…
Cancel
Save