前回の復習
第1回の講習では、Webサイトがどのような仕組みで構成され表示されるのかを学びました。今回も、そのWebサイトを作るための基本的な技術であるHTML/CSS/JSについて学びます。
CSSを外部のファイルに書く
CSSはHTML内に書くこともできますが、外部のファイルに書くこともできます。実際に、前回作成したHTMLファイルを編集して、CSSを外部のファイルに書いてみましょう。
<!DOCTYPE html>
<html>
<head>
<title>Web研講義1</title>
<style>
h1 {
color: blue;
}
span {
color: red;
}
.hero {
width: 700px;
}
</style>
</head>
<body>
<img src="https://maximum.vc/images/hero.png" alt="Maximumのロゴ" class="hero">
<h1>Web研究会</h1>
<h2>活動内容</h2>
<p>Web研究会は、Webに興味のある学生が集まって、Web技術の研究や開発を行う<span>プログラミングサークルMaximumの活動の一環</span>です。</p>
<h2>Webの分野</h2>
<ul>
<li>フロントエンド</li>
<li>バックエンド</li>
<li>インフラ</li>
</ul>
<a href="https://maximum.vc">Maximumのサイトはこちら</a>
</body>
</html>
まずは、index.html
と同じディレクトリにstyle.css
というファイルを作成します。
.
├── index.html
└── style.css
作成したstyle.css
に、<style>
タグ内に書いていたCSSをコピーします。
h1 {
color: blue;
}
span {
color: red;
}
.hero {
width: 700px;
}
次に、index.html
の<style>
タグ内のCSSを削除し、以下のように<link>
タグを追加します。
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./style.css">
<title>Web研講義1</title>
</head>
<body>
<img src="https://maximum.vc/images/hero.png" alt="Maximumのロゴ" class="hero">
<h1>Web研究会</h1>
<h2>活動内容</h2>
<p>Web研究会は、Webに興味のある学生が集まって、Web技術の研究や開発を行う<span>プログラミングサークルMaximumの活動の一環</span>です。</p>
<h2>Webの分野</h2>
<ul>
<li>フロントエンド</li>
<li>バックエンド</li>
<li>インフラ</li>
</ul>
<a href="https://maximum.vc">Maximumのサイトはこちら</a>
</body>
</html>
ここでの<link>
タグのhref
(hypertext reference)属性にはCSSファイルのパスを指定し、rel
(relationship)属性にはstylesheet
を指定します。<link>
タグは<head>
タグ内に書くのが一般的です。
<link rel="stylesheet" href="style.css">
これで、CSSを外部のファイルに書くことができました。
Tip: <a>
タグと<link>
タグの違い
<a>
タグはインライン要素として文章中にハイパーリンクを作るためのタグです。<link>
タグは直接Webページの見栄えに関係なく、外部ファイルを読み込むためのタグです。
CSSを書いてみよう
まずは、作業ディレクトリ(maximum
フォルダ)の中のwebken
フォルダにlec-02
というディレクトリを作成し、その中にindex.html
とstyle.css
を作成します。
maximum
└── webken
└── lec-01
| └── ...
└── lec-02
└── index.html
└── style.css
作成したindex.html
に以下のHTMLを記述します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./style.css">
<title>Web研講義2</title>
</head>
<body>
<header class="header">
<h2>サンプルサイト</h2>
</header>
<main class="main">
<div class="hero">ヒーロー</div>
<article class="article">
<div class="contents">メイン</div>
<div class="sidebar">サイドバー</div>
</article>
</main>
<footer class="footer">
<p>2024 Maximum Web研究会</p>
</footer>
</body>
</html>
レイアウトは様々ありますが、今回は例として下のようなレイアウトを作成します。
style.css
を作成して、下の見た目になるようにCSSを書いてみましょう。
(正解は1つではありません。第1回で学んだことを生かしたり調べてみましょう)
- ヘッダー、フッターの色は
#AFF4C6
- ヒーローの色は
#B3B3B3
- メインの色は
#FFC7C2
- サイドバーの色は
#BDE3FF
を指定してみましょう。(他の色でも大丈夫です)
レベル1
サンプルコード
前回の資料に載っているプロパティだけで書けます。
.header {
background-color: #AFF4C6;
width: 100%;
}
.hero {
background-color: #B3B3B3;
}
.article {
width: 100%;
}
.contents {
background-color: #FFC7C2;
}
.sidebar {
background-color: #BDE3FF;
}
.footer {
background-color: #AFF4C6;
width: 100%;
}
レベル2
サンプルコード
height
を使って高さを指定しました。text-align
やdisplay
などのプロパティを使いました。
.header {
background-color: #AFF4C6;
width: 100%;
}
.main {
padding: 20px;
}
.hero {
background-color: #B3B3B3;
padding: 8px;
}
.article {
display: flex;
width: 100%;
}
.contents {
width: 70%;
height: 70vh;
background-color: #FFC7C2;
padding: 8px;
}
.sidebar {
width: 30%;
height: 70vh;
background-color: #BDE3FF;
padding: 8px;
}
.footer {
background-color: #AFF4C6;
text-align: center;
width: 100%;
}
レベル3
サンプルコード
margin-left
やmargin-bottom
を使って余白を調整しました。:root
を使って変数を定義しました。*
(ユニバーサルセレクター)を使ってページ全体(全ての要素)にスタイルを適用しました。
:root {
--top-bottom-color: #AFF4C6;
}
* {
margin: 0;
}
.header {
background-color: var(--top-bottom-color);
width: 100%;
}
.main {
padding: 20px;
}
.hero {
height: 200px;
margin-bottom: 20px;
background-color: #B3B3B3;
padding: 8px;
}
.article {
display: flex;
width: 100%;
}
.contents {
width: 70%;
height: 70vh;
background-color: #FFC7C2;
padding: 8px;
}
.sidebar {
width: 30%;
height: 70vh;
background-color: #BDE3FF;
margin-left: 20px;
padding: 8px;
}
.footer {
background-color: var(--top-bottom-color);
text-align: center;
width: 100%;
}
プログラミング言語を学ぶ上での基本ルール
ちょっと余談ですが...
現在主流となっているプログラミング言語には、Java、JavaScript、C#、C++、PHPなどなどありますが、これらのプログラミング言語は「C言語」から派生しています。 つまり、起源が同じなので基本的な文法の構造は全て同じなので、1つ主流なプログラミング言語を習得すれば他のプログラミング言語も習得しやすくなります。
入門講習会でも学習したと思いますが、かる~く復習しておきましょう。
プログラムを処理をする順番
C言語やPython、JavaScriptなどの手続き型プログラミング言語は、基本的にプログラムを処理する順番は、1行ごとに上から下に処理されます。
console.log("こんにちは");
console.log("今日は4月29日です。");
console.log("天気は晴れです。");
詳しいことはわからなくても、プログラムが実行される順番は一目でわかりますね。
変数と代入
変数とは、データを格納するための箱のようなもので、変数には様々なデータを格納することができます。
let num = 10;
このように変数を宣言し、値を代入することができます。
命令文の終わりを伝える
JavaScriptやC++などのプログラムを書く際には、命令文の終わりに;
をつけることが基本です。
// JS
let num = 5;
console.log(num);
// cpp
int num = 5;
cout << num << endl;
Pythonでは改行することで命令文の終わりを伝えることができます。
# Python
num = 5
print(num)
JavaScript
JavaScript(以降JS)とは、HTMLとCSSをとともにWebページを作るための言語で、ユーザーの操作に応じてサイト上の要素を動かしたり、変更したりすることができます。 HTMLやCSSは、Webページにテキストや画像を追加したり、色を付けたりするなどWebページ全体の装飾をするための言語であり、「マークアップ言語」と呼ばれます。 一方、JSは計算や条件分岐などの処理ができるプログラミング言語です。 例えば
- ボタンを押したら画像を表示する
- 検索機能やソート機能を実装する
- 送信フォームの入力内容をチェックする
などの処理はHTML/CSSだけでは作ることができず、JSを組み合わせることで書くことができます。
基本文法を学ぼう
Web研ではJSを初めて学習する人もいるため、基本文法について簡単に紹介します。 入力が大変な部分もあるので、適宜コピー&ペーストしてください。
Web学習におけるコピペ
再度アナウンスしますが、Webでは文法よりも真似して慣れること・動作を理解することが大切です。 そのため、コードを模写する勉強はタイピングの練習としてはとても有効ですが、Webの勉強には不向きだと思います。 コピペをすることをためらう必要はなく、したものを少しいじったりして動作を理解すると良いと思います。
コンソールに出力する
JSをコンソールに出力してみましょう。
まずは、index.html
に以下のコードを追加します。
<!DOCTYPE html>
<html>
<head>
<script src="./script.js"></script>
</head>
</html>
script.js
をindex.html
と同じディレクトリに作成し、以下のコードを入力してください。
console.log('Hello World!');
index.html
を開き、F12キーからコンソールログを開くとコンソールに Hello World!
と表示されるはずです。
C++ではcout << "Hello World!" << endl;
と書くのがおなじみですが、JSではconsole.log()
を使います。
お馴染みの四則演算もできます
console.log(1 + 1); // 2
console.log(1 - 1); // 0
console.log(2 * 2); // 4
console.log(4 / 2); // 2
console.log(5 % 2); // 1
C言語ではint型同士の除算は小数点以下が切り捨てられますが、JSでは整数も小数として表されるため、除算では小数点以下も計算されます。
console.log(5 / 2); // 2.5
ちなみに0で割った時はInfinity
と表示されます。
console.log(1 / 0); // Infinity
変数
変数宣言の方法はvar
(variable)とlet
の2つありますが、基本的にはlet
を使います。
let a = 1;
let b = 2;
console.log(a + b); // 3
var a = 3;
var b = 4;
console.log(a + b); // 7
お気づきの方もいるかもしれませんが、JSには型宣言がありません。これは、JSが動的型付け言語だからです。Pythonなどと同じですね。 動的型付け言語とは、変数の型を宣言する必要がない言語のことです。 その代わり実行時に型を推論するので、実行が遅くなります。 コンパイル型言語が速いのは静的型付け言語だからです。
定数
変数と同じようにconst
(constant)で定数を宣言できます。
const a = 1;
const b = 2;
console.log(a + b); // 3
a = 2; // エラー
定数なので、再代入はできません。a
に2を代入しようとするとエラーになります。
基本は定数を使い、再代入が必要な場合に限って変数を使うようにしましょう。
条件分岐
比較演算
演算子 | 意味 |
---|---|
== | 等しい(キャストあり) |
=== | 厳密に等しい(キャストなし) |
!= | 等しくない(キャストあり) |
!== | 厳密に等しくない(キャストなし) |
> | より大きい |
>= | 以上 |
< | より小さい |
<= | 以下 |
&& | かつ |
|| | または |
! | 否定 |
console.log(1 == 1); // true
console.log(1 == '1'); // true
console.log(1 === '1'); // false
console.log(1 != 2); // true
console.log(1 !== '1'); // true
console.log(1 > 0); // true
console.log(1 >= 1); // true
console.log(1 < 2); // true
console.log(1 <= 1); // true
console.log(true && true); // true
console.log(true && false); // false
console.log(true || false); // true
console.log(false || false); // false
console.log(1 > 0 && 2 > 1); // true
console.log(1 < 0 || 2 > 1); // true
console.log(!false); // true
if文
const a = 1;
const b = 2;
if (a < b) {
console.log('a < b');
} else if (a > b) {
console.log('a > b');
} else {
console.log('a = b');
}
switch文
const text = "Mon";
switch (text) {
case "Sun":
console.log("日曜日");
break;
case "Mon":
console.log("月曜日");
break;
case "Tue":
console.log("火曜日");
break;
case "Wed":
console.log("水曜日");
break;
case "Thu":
console.log("木曜日");
break;
case "Fri":
console.log("金曜日");
break;
case "Sat":
console.log("土曜日");
break;
default:
console.log("曜日ではありません");
break;
}
繰り返し
for (let i = 0; i < 10; i++) {
console.log(i);
}
関数
従来の関数
function add(a, b) {
return a + b;
}
console.log(add(1, 2)); // 3
アロー関数
const add = (a, b) => {
return a + b;
}
console.log(add(1, 2)); // 3
従来の関数とアロー関数は同じことができますが、アロー関数の方が短く書けたり、簡潔だったりします。 厳密には違いがありますが、今のうちは気にしなくて大丈夫です。
早期リターン
const add = (a, b) => {
if (a < 0 || b < 0) {
return;
}
return a + b;
}
console.log(add(1, 2)); // 3
console.log(add(-1, 2)); // undefined
関数の中でreturn
を使うと、その時点で関数の処理が終了し、その後ろの処理は実行されません。
これを早期リターンと言います。
本当は
const add = (a, b) => {
if (a < 0 || b < 0) {
return;
} else {
return a + b;
}
}
と書かなきゃいけないところを、else
を省略して書けるので、短く書けます。
これが綺麗なコードを書く時の基本になりますので、覚えておきましょう。
※この技術はどの言語でも使えます。競プロでもよく使います。 特にオブジェクト指向言語(JavaやC#など)では必須な表現として紹介されることが多いです。
配列
const array = [1, 2, 3, 4, 5];
console.log(array[0]); // 1
console.log(array[1]); // 2
console.log(array[2]); // 3
console.log(array) // [1, 2, 3, 4, 5]
配列操作
JSで繰り返し処理を行う場合、for
文を使うことはほとんどありません。
その代わりに、配列操作を行います。
代表的な高階関数8個とその他メソッドを覚えておきましょう。(ほかにもありますが、とりあえずこれだけ覚えておけば大丈夫です)
全部覚える必要はありません、早見表を置いておくので、必要なときに見てください。
関数名・メソッド名 | 説明 | 出力例 |
---|---|---|
map | 各要素を加工して新しい配列を作成する | 2倍する [1, 2, 3, 4, 5] -> [2, 4, 6, 8, 10] |
forEach | 各要素に対して関数を実行する | 一つずつ表示する [1, 2, 3, 4, 5] -> 1, 2, 3, 4, 5 |
filter | 条件に当てはまる要素だけを新しい配列にして作成する | 偶数だけ取り出す [1, 2, 3, 4, 5] -> [2, 4] |
find | 条件に当てはまる要素を最初の一つだけ取り出す | 偶数を一つだけ取り出す [1, 2, 3, 4, 5] -> 2 |
reduce | 各要素をどんどん加工して一つの値にする | 合計を求める [1, 2, 3, 4, 5] -> 15 |
some | 一つでも条件に当てはまる要素があるか | 偶数があるか [1, 2, 3, 4, 5] -> true |
every | すべての要素が条件に当てはまるか | 偶数だけか [1, 2, 3, 4, 5] -> false |
sort | 配列を並び替える | 降順に並び替える [1, 2, 3, 4, 5] -> [5, 4, 3, 2, 1] |
includes | 配列に指定した要素が含まれているか | 3が含まれているか [1, 2, 3, 4, 5] -> true |
indexOf | 配列に指定した要素が何番目にあるか | 3は何番目か [1, 2, 3, 4, 5] -> 2 |
join | 配列を指定した文字で結合する | , で結合する [1, 2, 3, 4, 5] -> 1,2,3,4,5 |
split | 文字列を指定した文字で分割する | , で分割する 1,2,3,4,5 -> [1, 2, 3, 4, 5] |
slice | 配列の一部を取り出す | 2番目から4番目まで取り出す [1, 2, 3, 4, 5] -> [2, 3, 4] |
length | 配列の要素数を取得する | [1, 2, 3, 4, 5] -> 5 |
map
map
はその配列の要素一つ一つを加工して、新しい配列を作成します。
const array = [1, 2, 3, 4, 5];
// すべての要素を2倍する
const doubledArray = array.map((value) => {
return value * 2;
});
console.log(doubledArray); // [2, 4, 6, 8, 10]
for文でいちいちindexを指定して要素を取り出すのは面倒なので、map
を使います。
map
は配列の要素を一つずつ取り出して、関数を実行します。
その結果を配列にして返します。
forEach
forEach
はその配列の要素一つ一つに対して、関数を実行します。
const array = [1, 2, 3, 4, 5];
const log = (value) => {
console.log("value: " + value);
}
array.forEach(log); // value: 1, value: 2, value: 3, value: 4, value: 5
map
と違って、forEach
は新しい配列を作成しません。
その代わり各要素に対して関数を実行します。
今回はlog
という関数を作成して、それをforEach
に渡しています。
filter
filter
はその配列の要素一つ一つに対して、関数を実行し、その結果がtrue
の要素だけを取り出して、新しい配列を作成します。
const array = [1, 2, 3, 4, 5];
const isEven = (value) => {
return value % 2 === 0;
}
const isOdd = (value) => {
return value % 2 === 1;
}
const evenArray = array.filter(isEven);
const oddArray = array.filter(isOdd);
console.log(evenArray); // [2, 4]
console.log(oddArray); // [1, 3, 5]
reduce
reduce
はその配列の要素一つ一つに対して、関数を実行し、その結果を次の要素に渡していきます。
最終的には一つの値を返します。
const array = [1, 2, 3, 4, 5];
const sum = (a, b) => {
return a + b;
}
const result = array.reduce(sum);
console.log(result); // 15
find
find
はその配列の要素一つ一つに対して、関数を実行し、その結果がtrue
になった最初の要素を返します。
const array = [1, 2, 3, 4, 5];
const isEven = (value) => {
return value % 2 === 0;
}
const result = array.find(isEven);
console.log(result); // 2
filter
と違って、find
は最初に見つかった要素だけを返します。なので今回はindex0
から線形探索をして初めて見つかった値2
を返します。
some
some
はその配列の要素一つ一つに対して、関数を実行し、その結果がtrue
になった要素が一つでもあればtrue
を返します。
const array = [1, 2, 3, 4, 5];
const isEven = (value) => {
return value % 2 === 0;
}
const result = array.some(isEven);
console.log(result); // true
every
every
はその配列の要素一つ一つに対して、関数を実行し、その結果がtrue
になった要素がすべてtrue
ならばtrue
を返します。
const array = [1, 2, 3, 4, 5];
const isEven = (value) => {
return value % 2 === 0;
}
const result = array.every(isEven);
console.log(result); // false
sort
sort
はその配列の要素一つ一つに対して、関数を実行し、その結果を元にソートします。
const array = [1, 2, 3, 4, 5];
const compare = (a, b) => {
if (a < b) {
return 1;
} else if (a > b) {
return -1;
} else {
return 0;
}
}
array.sort(compare);
console.log(array); // [5, 4, 3, 2, 1]
配列array
はconst
なのに再代入できるの?と思うかもしれませんが、
const
は再代入できないだけで、配列の内部状態を変更することはできます。
簡単に言えば、=
による変更ができないということです。
compare
関数はa
とb
を比較して、a
が大きければ1
、b
が大きければ-1
、同じなら0
を返します。
sort
は負なら要素を入れ替え、0
ならそのまま、正なら要素を入れ替えないという3値論理を使ってソートを行います。
includes
includes
はその配列の要素一つ一つに対して、引数に指定した値と同じかどうかを調べ、一つでも同じ値があればtrue
を返します。
const array = [1, 2, 3, 4, 5];
const result = array.includes(3);
console.log(result); // true
const result2 = array.includes(6);
console.log(result2); // false
indexOf
indexOf
はその配列の要素一つ一つに対して、引数に指定した値と同じかどうかを調べ、一つでも同じ値があればその要素のindexを返します。
const array = [1, 2, 3, 4, 5];
const result = array.indexOf(3);
console.log(result); // 2
const result2 = array.indexOf(6);
console.log(result2); // -1
join
join
はその配列の要素一つ一つを文字列に変換し、引数に指定した文字列で結合します。
const array = [1, 2, 3, 4, 5];
const result = array.join('-');
console.log(result); // 1-2-3-4-5
split
split
は引数に指定した文字列で配列を分割します。
const text = '1-2-3-4-5';
const result = text.split('-');
console.log(result); // ['1', '2', '3', '4', '5']
slice
slice
は引数に指定したindexから、引数に指定したindexまでの要素を取り出します。
slice
は左閉右開の半開区間で指定します。
例えば、slice(1, 3)
とすると、indexが[1, 3)
の要素を取り出します。
const array = [1, 2, 3, 4, 5];
const result = array.slice(1, 3); // indexが1以上3未満の要素を取り出す
console.log(result); // [2, 3]
length
length
はその配列の要素の数を返します。
const array = [1, 2, 3, 4, 5];
const result = array.length;
console.log(result); // 5
まとめ
今回の講義では、CSSの練習とJavaScriptの基本文法について学習しました。 JavaScriptの文法は慣れるまでは難しいかもしれませんが、無理に覚えようとせずに使っていくうちに読める/書けるようになると思います。 次回は、JavaScriptを使ってWebページを動的に操作する方法について学習します。