目次
1. はじめに
Web Development for Beginners の3つのレッスンをやっていきます。
- 8日目:Terrarium Project Part 1: Introduction to HTML
- HTMLの紹介
- 9日目:Terrarium Project Part 2: Introduction to CSS
- CSSの紹介
- 10日目:Terrarium Project Part 3: DOM Manipulation and a Closure
- DOM操作とクロージャ
3日分のレッスンを通して、Terrarium というWebアプリケーションを作成します。Terrarium というのは、植物を育てるためのガラスの容器だそうです。どんなものか確かめたい方は、Googleなどで検索してください。
※ 本記事は、ほぼ「個人的なメモ」です。
2. Lesson 8: Terrarium Project Part 1: Introduction to HTML
Introduction
Webアプリケーションにおいて、CSS が装飾を行い、JavaScript が動きを持たらすとすると、HTML の文法もそれを反映している(<head>
, <body>
, <footer>
というタグがある)。
このレッスンでは、タイトルと3カラムのレイアウトをHTMLで作成する。左と右のカラムには、ドラッグできる植物を配置し、真ん中のカラムがテラリウム本体となる。
Task
terrarium
という名前のフォルダを作成し、その中に index.html
というファイルを生成する。
DOCTYPE
の簡単な説明
index.html
ファイルに以下を記述する。
<!DOCTYPE html>
<html>
</html>
The document’s ‘head’
<head>
についての簡単な説明。ページのタイトルやメタデータを記述する。
Task
<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>
The document’s body
HTML Tags
HTMLタグを、例えば <p>hello</p>
といった形で書いていく。
Task
</head>
の後ろに、<body></body>
を追記する。
Images
<img>
タグは、開始タグと終了タグの間に何も書く必要がないから、終了タグを書く必要はない。
images
フォルダを作成し、../solution/images
内にあるすべての画像ファイル(植物の画像)を入れておく。
Task
それらの画像ファイルを、<body>
内に配置するタグを記述する。(長いので一部省略する)
<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>
<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="plant14" src="./images/plant14.png" />
</div>
</div>
</div>
Semantic markup
セマンティック・マークアップについての簡単な説明。それぞれのタグが持つ意味に沿ったマークアップを適切に行うことで、スクリーン・リーダーや検索ボットがコンテンツの構造や部分毎の意図を読み取りやすくする。例えば、ボタンを作りたければ <button>
タグを使べきである。別のタグのスタイルを上手く調整して、見た目をボタンのようにして使うのはよいことではない。
<body>
タグのすぐ下に、以下を追記する。
<h1>My Terrarium</h1>
The terrarium
テラリウム本体となる部分のHTMLを追記する。
Task
最後の </div>
の手前に以下を記述する。
<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>
3. Lesson 9: Terrarium Project Part 2: Introduction to CSS
Introduction
CSS の簡単な説明。CSS は装飾やレスポンシブデザインに使用する。また、アニメーションや形の変形にも利用できる。
Task
style.css
ファイルを生成し、index.html
ファイルの <head>
内に以下を追記する。
<link rel="stylesheet" href="./style.css" />
The Cascade
CSS の簡単な説明。
Task
<h1>
タグに style
属性を追加する。
<h1 style="color: red">My Terrarium</h1>
以下を style.css
ファイルに記述する。
h1 {
color: blue;
}
Inheritance
ネストされた要素が親のスタイルを継承するように、スタイルは祖先スタイルから子孫スタイルに継承される。
Task
<body>
のフォントを指定する。
body {
font-family: helvetica, arial, sans-serif;
}
例えば Chrome ブラウザであれば、開発者ツールの [Elements]タブを開き、h1のフォントを確認すると、<body>
に指定したフォントが継承されているのが分かる。
CSS Selectors
Tags
いろいろなCSSセレクタを利用するべし。
Ids
id属性の値を使ってHTMLの要素を特定し、スタイルを記述するには、#
を使う。
#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;
}
Classes
複数の要素にまとめて同じスタイルを指定する場合は、class属性を使用する。
<div class="plant-holder">
<img class="plant" alt="plant" id="plant1" src="./images/plant1.png" />
</div>
class属性の値を使ってHTMLの要素を特定し、スタイルを記述するには、.
を使う。
style.css
に以下を追記する。
.plant-holder {
position: relative;
height: 13%;
left: -10px;
}
.plant {
position: absolute;
max-width: 150%;
max-height: 150%;
z-index: 2;
}
plant-holder クラスを指定した <div>
要素(カラム上の植物の置き場所、これを親要素とする)を縦に 7等分し、それを基準にして、plant クラスを指定した <img>
要素(これを子要素とする)の大きさを調整している。position要素を使っているのは、JavaScript で <img>
要素を動かすと際に、親要素側の位置を基準とした値で操作したいからだと思われる。
CSS Positioning
position要素を使ってカラムを左右の端に配置している。
CSS Layouts
style.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;
}
4. Lesson 10: Terrarium Project Part 3: DOM Manipulation and a Closure
Introduction
DOMの簡単な説明。HTMLページは、<html>
要素を頂点とした木構造に解釈される。このとき、各要素はオブジェクトとして保持される。これが DOM である。
JavaScript closure の簡単な説明。関数に囲まれた関数で、内側の関数内から、外側の関数内で定義された変数にアクセスできる。
Task
terrarium フォルダー直下に script.js
ファイルを作成し、index.html
内の <head>
内に以下を記述する。
<script src="./script.js" defer></script>
- defer を指定することにより、DOM生成後にこの JavaScript ファイルが実行されるようにしている。
The DOM elements
Task
「渡された要素を ドラッグ・アンド・ドロップ可能にする関数 (dragElement)」に、植物を表す要素を渡す。
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'));
その続きのコードは以下である。本来はパートに分けて説明されているが、それだと見づらいのでここでまとめる。
function dragElement(terrariumElement) {
//set 4 positions for positioning on the screen
let pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
terrariumElement.
/*
* 要素の上でポインターを押した際に発火するイベントリスナー
* (ドラッグのスタート時に動作する)
*/
function pointerDrag(e) {
e.preventDefault();
pos3 = e.clientX; // クリックしたときの絶対位置
pos4 = e.clientY; // クリックしたときの絶対位置
document.
document.
}
/*
* ポインターが動いたら発火するイベントリスナー
* (ドラッグして要素が動いた時に動作する)
*/
function elementDrag(e) {
pos1 = pos3 - e.clientX; // 1つ前の位置との差
pos2 = pos4 - e.clientY; // 1つ前の位置との差
pos3 = e.clientX; // 1つ前の絶対位置を保存
pos4 = e.clientY; // 1つ前の絶対位置を保存
// 要素を移動させる(相対位置で指定)
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
}
/*
* ポインターを離した際に発火するイベントリスナー
* (ドラッグ・アンド・ドロップの終了時に動作する)
* これがないとポインターから植物要素が離れない
*/
function stopElementDrag() {
document.
document.
}
}
The Closure
Task
displayCandy()
関数の説明。コード内のコメントに書いた。
The Pointerdrag function
Task
pointerDrag()
関数の説明。コード内のコメントに書いた。
The elementDrag and stopElementDrag functions
Task
elementDrag()
関数の説明。コード内のコメントに書いた。
Task
stopElementDrag()
関数の説明。コード内のコメントに書いた。
5. デモページ
このゲームのデモページを作りました → Welcome to my Virtual Terrarium
6. 参考情報
CSS関連
Web API 関連
Pointer Events 関連
- Pointer Events
- Pointer Events – Chrome Platform Status
- Pointing the Way Forward | Web | Google Developers
- GlobalEventHandlers – Web APIs | MDN
7. おわりに
ドラッグ・アンド・ドロップに使えそうなイベントは複数ありますが、スマートフォンのタッチ操作にも対応しているか? や各ブラウザの実装状況などを考えると、現在は Pointer Events を使うのが良い?ようです(少なくとも有力な候補にはなると思います)。勉強になりました。各イベントを比較するには、GlobalEventHandlers – Web APIs | MDN に載っている表が役に立ちます。