HTMLとの連携
Javascriptの最も大きな特徴として ブラウザで動く という点が挙げられます。
JavascriptはWebページの表示に用いられている HTML という形式の文書を、思い通りに操作することができます。
HTMLとは
HTML は Hyper Text Markup Language の略で、Webページの内容を記述するのに用いられる言語です。ハイパーテキストとは、複数の文書を相互に結びつける仕組みです。リンク機能がそれにあたります。そしてマークアップとは、文書構造や視覚表現をコンピュータが正しく認識できるように、「タグ」と呼ばれる目印をつけて文書に意味づけしていくことを指します。
これまでの学習でも使用してきた index.html ファイルがHTMLです。ここで改めてソースコードを見てみましょう。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>はじめてのJavascript</title>
</head>
<body>
<h1>はじめてのプログラミング</h1>
<script src="main.js"></script>
</body>
</html>
最初の行にある <!DOCTYPE html>
は、おまじないだと思って下さい。ブラウザは冒頭にこの記述がある文書ファイルを「HTMLだな」と認識します。
次の行には <html>
とありますが、一方で最後の行には </html>
というのもあります。これが文書の意味づけに用いられる「タグ」と呼ばれるものです。同じ名前で /
スラッシュがついたタグが出てくるまでの間が、そのタグの「中身」になります。
<開始タグ> 〜中身〜 </終了タグ>
htmlタグは「ここからここまではHTMLです」という意味付けを行なっています。
3行目には、字下げ(インデント)がされて <head>
という開始タグがあります。6行目の終了タグ </head>
までの間は、headという意味付けがされています。head タグには文書に関する様々な設定が記述されます。
head タグが終わると今度は <body>
タグが登場します。 body タグはテキストや画像など、実際にブラウザに表示される部分になります。
そして body タグの中には <h1>
タグ や <script>
タグがあります。このように、HTML文書はタグを用いて階層(ツリー)を構成しながら記述されていきます。
index.htmlを少しづつ分解しながら、詳しく見ていくことにしましょう。それぞれのタグにコメント <!--
〜 -->
を入れて解説します。(解説なのでindex.htmlは書き換えないでください)
<html>
<head>
<!-- ヘッダ情報 -->
<!-- ブラウザに表示されない部分 -->
</head>
<body>
<!-- 本文 -->
<!-- ブラウザに表示される部分 -->
</body>
</html>
これがHTML文書の基本形になります。どのようなHTMLにも必ず htmlタグ・headタグ・bodyタグがあります。
headタグにはページの様々な情報を記述していきます。
<!-- ヘッダ情報 -->
<head>
<!-- 文字コードをUTF-8に指定 -->
<meta charset="utf-8">
<!-- このページのタイトル -->
<!-- ブラウザのタブや、検索結果のタイトルにも使われる超重要タグ -->
<title>はじめてのJavascript</title>
</head>
そしてbodyタグには画面に見える部分を記述していきます。
<!-- 本文 -->
<body>
<!-- 見出し:大きな文字で表示される -->
<h1>はじめてのプログラミング</h1>
<!-- スクリプト読込み:main.jsを読み込んでいる -->
<script src="main.js"></script>
</body>
DOMとは
HTML形式で書かれたツリー構造の文書を操作する仕組みが、Javascriptには備わっています。このような仕組のことをDOM(Document Object Model)といいます。
JavascriptはHTML文書をひとつの「オブジェクト」として扱うことができます。各オブジェクトにはさまざまなプロパティやメソッドがあらかじめ用意されていて、JavascriptはそれらにアクセスすることでHTMLの情報を取得したり、書き換えることができます。
main.jsを次のように変更して、実行(ページの更新)してみて下さい。
var h1 = document.getElementsByTagName('h1');
h1[0].innerHTML = 'はじめてのDOM操作';
今度はコンソールではなく実際のWebページの方を確認してみてください。見出しに元々書かれていた「はじめてのプログラミング」という文字が、「はじめてのDOM操作」に変わったのが確認できたでしょうか?
一体何が起こったのか、コードを確認してみましょう。
var h1 = document.getElementsByTagName('h1');
h1[0].innerHTML = 'はじめてのDOM操作';
まず1行目の
var h1 = document.getElementsByTagName('h1');
document
は、ブラウザーに読み込まれたウェブページ全体 <html>
〜 </html>
を表すオブジェクトです。つまりツリー構造の最上層にあたります。
getElementsByTagName()
はdocumentに備わっているメソッド(機能)で ()
内に指定したタグ名に該当するものを全て取得します。今回は ('h1')
と指定したので、index.htmlに書かれた次の要素が取得されました。
<h1>はじめてのプログラミング</h1>
h1はこのひとつだけでしたが、場合によっては同じページ内にh1タグが複数存在するかもしれません。メソッド名が getElement s ByTagName となっているように、複数の要素を取得することが想定されていて、取得した結果は「配列」になっています。今回はその配列を var h1 =
でh1という変数に代入しています。あとから使いやすくするためです。
次に2行目を見てみましょう。
h1[0].innerHTML = 'はじめてのDOM操作';
先ほど h1 には「配列」が代入されていると説明しました。このページには h1タグ は1つしか存在しないので、目的の h1 要素の情報は配列の 0 番目 のインデックスに格納されていることになります。0 番目の配列にアクセスするには
h1[0]
こうでしたね。
h1[0]はこの時点で「オブジェクト」として扱われているので、さまざまなプロパティやメソッドを使って操作することができます。今回は innerHTML
というプロパティを使って h1 タグの中に書かれた内容にアクセスしようとしています。
h1[0].innerHTML = 'はじめてのDOM操作';
=
は「等しい」ではなく「代入」なので、この時点で、h1タグの内容は「はじめてのDOM操作」に書き換えられました。
このようにしてmain.jsの2行の命令が実行されたことによって、Webページの内容が変更されたというわけです。
せっかくなので、もう少し遊んでみましょう。
main.jsにさらに次の3行を追加してください。
var h1 = document.getElementsByTagName('h1');
h1[0].innerHTML = 'はじめてのDOM操作';
var p = document.createElement('p'); // 追加
p.innerHTML = 'Javascriptって面白い!'; // 追加
h1[0].after(p); // 追加
ページを更新したら、Chromeのデベロッパーツールを開いてHTMLがどのように変化しているかを確認することができます。
var p = document.createElement('p');
3 行目おこなっているのは「 p というタグを使って新しく要素を作成し、変数 p に代入せよ」です。
p.innerHTML = 'Javascriptって面白い!';
4 行目は「作成されたpタグの中身(innerHTML)に文字列 'Javascriptって面白い!' を代入せよ」としています。
h1[0].after(p);
5 行目「h1 タグの後ろに p を追加せよ」という命令によって、Webページの見出しの下部に新たに要素が追加されたのでした。HTML文書はこの時点で次のように変化しています。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>はじめてのJavascript</title>
</head>
<body>
<h1>はじめてのDOM操作</h1>
<p>Javascriptって面白い!</p>
<script src="main.js"></script>
</body>
</html>
Javascriptを使うとこんな風に、WebページのHTMLを操って内容を書き換えることも簡単にできてしまいます。
イベントを操ろう
ここまでのプログラムは「ブラウザでページを表示した時に自動的(勝手)に実行される」ものでした。これをもう少し改良してみましょう。
「はじめてのプログラミング」というテキストを「クリックしたら」内容を書き換えるというものです。処理の開始を開発者ではなくユーザーに委ねます。
「クリックしたら」のように何か特定のアクションに対して、処理を結びつける仕組みを「イベントリスナ」といいます。イベントリスナを登録する方法もメソッドとしてあらかじめ用意されていて、使い方は簡単です。ただし、まだ学習していない「関数」が出てくるので、少し注意深く読んで下さい。
var h1 = document.getElementsByTagName('h1');
var changeText = function () {
h1[0].innerHTML = 'はじめてのDOM操作';
var p = document.createElement('p');
p.innerHTML = 'Javascriptって面白い!';
h1[0].after(p);
}
h1[0].addEventListener('click', changeText);
これを実行してみて下さい。見出しはまだh1タグに書かれた「はじめてのプログラミング」のままです。
ではこの見出し文の文字をクリックしてみて下さい。ページの内容が変化しましたか?
このように「クリックされたら」「○○という処理をする」ということをあらかじめ設定しておくことができるのが addEventListner() です。
1イベントの対象.addEventListner(2イベントの種類, 3処理内容);
今回のケースでは
- イベントの対象・・・h1タグ
- イベントの種類・・・クリック
- 処理内容・・・ページの内容を書き換える
としました。
1 と 2 についてはそれほど難しくはないでしょう。問題は 3 の部分です。ここには changeText
と書かれています。
h1[0].addEventListener('click', changeText);
これは何を指しているかというと、2 行目〜 7 行目の var changeText = ...
の部分になります。
var changeText = function () {
h1[0].innerHTML = 'はじめてのDOM操作';
var p = document.createElement('p');
p.innerHTML = 'Javascriptって面白い!';
h1[0].after(p);
}
これはJavascriptの「関数」という機能です。
「変数」はデータに名前をつける機能でしたよね。一方、関数は「処理に名前をつける機能」と言うことができます。
先ほどのケースではページが表示された瞬間にこれらの処理が実行されましたが、今回はその処理内容に changeText という名前をつけておいたのです。そして、addEventListnerの 3 の部分でこれを紐付けています。これによって、ページが表示された時ではなくユーザーの任意のタイミングで処理を実行させることができるようになりました。
尚、このmain.jsは次のように書き換えることもできます。
var h1 = document.getElementsByTagName('h1');
h1[0].addEventListener('click', function () {
h1[0].innerHTML = 'はじめてのDOM操作';
var p = document.createElement('p');
p.innerHTML = 'Javascriptって面白い!';
h1[0].after(p);
});
一度きりしか使わないのであれば、わざわざ名前をつけて使い回せるようにしておく必要もありません。changeText に代入していた処理内容は、addEventListenerの第2引数に直接記述することもできます。これを「無名関数」と呼びます。このような方法も覚えておいて下さい。
まとめ
以上、JavascriptでDOMを操って、Webページの内容を書き換える体験をしました。イベントリスナを扱うことで、ユーザのアクションに対するリアクションを定義しておく方法も学びました。
いよいよ次の最終章では、ユーザーの身長と体重からBMI値を計算して、ユーザーに知らせる、というWebアプリを作成します。これまでの学習の集大成となるので、頑張って下さい。