wiki:HowTo/JavaScriptTutorial

Version 13 (modified by 村山 俊之, 14 years ago) ( diff )

--

JavaScript チュートリアル

JavaScript って何?

PC 上で動作する主要な Web ブラウザに必ずと言っていいほど搭載されているスクリプト言語です。

単体で動作する JavaScript インタプリタも存在しますが、主な用途は基本的には Web アプリケーションのクライアントサイドプログラムとなります。

クライアントサイドプログラムとは?

CGI がブラウザ (クライアント) からの要求を受けてサーバーサイドでプログラムを動作させる仕組みであるのに対し、ブラウザ上、すなわちクライアントサイドでプログラムを動作させる仕組みのことをこう呼んでいます。

元々は、サーバーとの通信を必要としない動作 (画面表示の動的な変化、等) を記述する目的で使われていましたが、 Ajax と呼ばれる通信機能により、最近ではページ読み込みの待ち時間によるストレスを感じさせない UI 作りや、Google Map に代表されるようなリッチな UI の実装などに大きく貢献するようになってきています。

とりあえず使ってみよう

どうやって使うの?

JavaScript は HTML と一緒にブラウザに読み込ませて使います。従って、基本的には HTML ファイルの中に直接記述してしまいますが、別ファイルに JavaScript のスクリプトファイル単体として記述することも可能です。

まずは、最も簡単な例から見てみましょう。以下のサンプルプログラムは、ブラウザ上に「hoge」と書かれたボタンが表示され、それをクリックすると、メッセージボックスに「hoge」と表示する、というものです。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>hoge</title>
</head>

<body>

<form>
  <input type="button" value="hoge" onclick="alert('hoge');">
</form>

</body>

</html>

動かしてみる

上記のサンプルプログラムをテキストエディタに記述したら、拡張子 .html で保存し、そのファイルを Web ブラウザ (IE、Firefox、Safari、Opera、etc...) にドラッグ&ドロップするなどして読み込ませれば動かせるはずです。

IE の場合、画面上部に警告メッセージの黄色い帯が表示されるかも知れませんが、その場合は帯の部分をクリックし、表示されるコンテキストメニューの「ブロックされているコンテンツを許可...」を選択してください。

イベントハンドラ

上記のサンプルの中で、 JavaScript が用いられているのは、以下の部分です。

  <input type="button" value="hoge" onclick="alert('hoge');">

<input> 要素に onclick という属性が存在し、その値として、 JavaScript によるプログラムが記述されています。

onclick 属性は、その要素がクリックされたときに、値に指定されたプログラムを実行せよ、という意味のものです。この手の属性は、他にも以下のようなものが存在します。(本当は他にももっといろいろ存在します…)

  • onmousemove ... その要素が表示されている箇所でマウスカーソルが動いたら、プログラムを実行する。
  • onmousedown ... その要素が表示されている箇所にマウスカーソルが存在するときに、マウスのボタンが押し下げられたら、プログラムを実行する。 (onclick が押して放さないと認識されないのに対し、こちらは押しただけで認識される)
  • onmouseup ... その要素が表示されている箇所にマウスカーソルが存在するときに、マウスのボタンが放されたら、プログラムを実行する。
  • onkeydown ... キーボードのキーが押されたら、プログラムを実行する。
  • onkeyup ... キーボードのキーが放されたら、プログラムを実行する。
  • onload ... HTML ファイルが読み込まれたら、プログラムを実行する。
  • onfocus ... その要素にフォーカスが移ったら、プログラムを実行する。例えば、入力欄をクリックするなどしてカーソルが表示されるようになるタイミングで、その入力欄の <input> 要素に onfocus 属性があれば、その値が実行される。
  • onchange ... コンボボックス (<select> 要素) の選択されている値が変化したら、プログラムを実行する。
  • …などなど。

このような、「○○されたら××する」というプログラム上の仕組みのことを、イベントハンドラと呼びます。多くの場合、 JavaScript はイベントハンドラから実行されるように記述します。

<script> タグ

HTML 要素の属性値として JavaScript を記述することができるのは分かりましたが、これだけだと、より長くて複雑なプログラムを記述したい場合には不便です。

そこで、属性値の中ではなく、もうちょっと別の場所に、プログラムをまとめて記述する方法を以下に示します。以下のサンプルプログラムは、「hoge」ボタンを押すたびに、ブラウザ画面上の至る所に「hoge」という文字を表示する、というものです。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>hoge</title>
  <script type="text/javascript" language="JavaScript"><!--
function putHoge() {
    var span = document.createElement("span");
    with (span.style) {
        position = "absolute";
        left = (Math.floor(Math.random() *
            (window.innerWidth ? window.innerWidth :
            document.documentElement.clientWidth ? document.documentElement.clientWidth :
            document.body.clientWidth))) + "px";
        top = (Math.floor(Math.random() *
            (window.innerHeight ? window.innerHeight :
            document.documentElement.clientHeight ? document.documentElement.clientHeight :
            document.body.clientHeight))) + "px";
    }
    span.appendChild(document.createTextNode("hoge"));
    document.getElementById("hoge_place").appendChild(span);
};
//--></script>
</head>

<body>

<form>
  <input type="button" value="hoge" onclick="putHoge();">
</form>

<div style="position: absolute; left: 0; top: 0;" id="hoge_place"></div>

</body>

</html>

さて、先ほどのプログラムと比べると、今回のプログラムはかなり複雑です。今はプログラムの内容は気にせず、プログラムが記述されている場所と、その雰囲気に注目してください。

先ほどと同様、今回も <input> タグには onclick 属性が指定されています。

  <input type="button" value="hoge" onclick="putHoge();">

しかし、そこに書かれているのは、 putHoge という名前の、恐らくは関数呼び出しに見える (後ろに丸かっこが付いているので) もののみが記述されています。

HTML ファイルの上の方に、なんだか見慣れない記述がありますね。以下の部分です。

  <script type="text/javascript" language="JavaScript"><!--
function putHoge() {
    var span = document.createElement("span");
    with (span.style) {
        position = "absolute";
        left = (Math.floor(Math.random() *
            (window.innerWidth ? window.innerWidth :
            document.documentElement.clientWidth ? document.documentElement.clientWidth :
            document.body.clientWidth))) + "px";
        top = (Math.floor(Math.random() *
            (window.innerHeight ? window.innerHeight :
            document.documentElement.clientHeight ? document.documentElement.clientHeight :
            document.body.clientHeight))) + "px";
    }
    span.appendChild(document.createTextNode("hoge"));
    document.getElementById("hoge_place").appendChild(span);
};
//--></script>

この、 <script> タグに囲まれた部分も、 JavaScript プログラムです。そしてこのプログラム、

function putHoge() {

で始まっていることから分かるように、先ほど <input> 要素の onclick 属性で呼び出そうとしていた putHoge() 関数の定義であることが、何となくおわかりいただけるかと思います。

このように、通常は <script> タグを用いて複雑な処理を行う関数を記述し、その関数をイベントハンドラから呼び出す、というスタイルで記述されるのが一般的です。

なお、上記の例では HTML 4.01 で記述している為、<script> タグの内側は HTML のコメントタグ (<!-- ~ -->) で包んでいます。これには以下の 2つの理由があります。

  • <script> タグに対応していない古いブラウザや未知のブラウザでも、画面上に JavaScript のプログラムを表示してしまわないようにする為。
  • JavaScript 中に出現する不等号記号 (<, >) が、 HTML タグと混同されてしまうのを防ぐ為。

一方、 XHTML で記述する場合には、 <script> タグの内側に記述するプログラムを HTML のコメントタグで包むことは禁止されています。 XHTML であれば、 <script> タグには必ず対応しているので、画面上に JavaScript のプログラムを表示してしまう危険性はありませんが、不等号記号が HTML タグだと誤解されるが故の誤動作の危険性は残っています。それを防ぐ為、 XHTML の場合は以下のように、コメントタグの代わりに <![CDATA[ ~ ]]> で囲うようにする必要があります。

  <script type="text/javascript" language="JavaScript">
// <![CDATA[
function putHoge() {
    // (...省略)
};
// ]]>
</script>

JavaScript のみを別ファイルに記述する

<script> タグを用いれば、 JavaScript で記述された複雑な処理のプログラムを、 HTML ファイルとは別のファイルに記述して実行させることも可能です。

その場合、 HTML ファイルは以下のように記述します。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>hoge</title>
  <script src="hoge.js" type="text/javascript" language="JavaScript"></script>
</head>

<body>

<form>
  <input type="button" value="hoge" onclick="putHoge();">
</form>

<div style="position: absolute; left: 0; top: 0;" id="hoge_place"></div>

</body>

</html>

そして、 hoge.js ファイルは以下のような内容となります。といっても、前のサンプルで <script> タグの内側に記述していた内容と全く同じです。もちろん、 HTML コメントタグ <!-- ~ --> や CDATA セクション <![CDATA[ ~ ]]> で囲う必要はありません。

function putHoge() {
    var span = document.createElement("span");
    with (span.style) {
        position = "absolute";
        left = (Math.floor(Math.random() *
            (window.innerWidth ? window.innerWidth :
            document.documentElement.clientWidth ? document.documentElement.clientWidth :
            document.body.clientWidth))) + "px";
        top = (Math.floor(Math.random() *
            (window.innerHeight ? window.innerHeight :
            document.documentElement.clientHeight ? document.documentElement.clientHeight :
            document.body.clientHeight))) + "px";
    }
    span.appendChild(document.createTextNode("hoge"));
    document.getElementById("hoge_place").appendChild(span);
};

大規模な Web アプリケーションの場合、HTML 自体がサーバーサイドで動的に生成され、そこから JavaScript で記述された同一の処理を実行する、といった作りになることが多い為、このような方法で JavaScript のみを別ファイルで記述する方がより一般的です。

読み込みと同時に実行されるプログラム

<script> タグ内に記述したプログラムは、HTML ファイルの読み込み中に順次実行されます。その様子を、以下のサンプルプログラムで確認してみましょう。このプログラムは、ブラウザ上で HTML ファイルを読み込んだときの日時を表示するものです。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>

<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<meta http-equiv="content-script-type" content="text/javascript">
	<title>run in load</title>
</head>

<body>

<p>このファイルは、</p>

<p><strong>
  <script type="text/javascript" language="JavaScript"><!--
    document.write((new Date()).toLocaleString());
//--></script>
</strong></p>

<p>に読み込まれました。</p>

</body>

</html>

document.write() メソッドを用いることにより、 <script> タグを記述した箇所に直接文字列を挿入することができます。

が、こうした書き方は、実際にはあまりやりません。できることが限られているからです。 <script> タグは <head> の中に配置し、その中では変数や関数の定義を記述し、それらをイベントハンドラから呼び出して利用する、というスタイルがもっとも一般的です。

JavaScript で Web ページが動く仕組み

window オブジェクト

それでは、 JavaScript をどのように記述すると、どんな風に Web ページを動かすことができるのか、その仕組みを見ていくことにしましょう。

まずは、一番最初に示したサンプルプログラムを、もう一度見てみることにしましょう。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>hoge</title>
</head>

<body>

<form>
  <input type="button" value="hoge" onclick="alert('hoge');">
</form>

</body>

</html>

JavaScript によるプログラムが記述されているのは、以下の部分ですね。

  <input type="button" value="hoge" onclick="alert('hoge');">

この <input> 要素は type="button" となっているとおりボタンであり、これをクリックすることで、 onclick イベントハンドラに指定されている以下の JavaScript プログラム

  alert('hoge');

が実行される、という仕組みです。この alert() という関数に見えるものに、表示したい文字列を引数に渡して呼び出せば、その文字列が書かれたメッセージボックスを表示できるらしい、ということが分かると思います。

さて、この alert() ですが、これは正確には、 window.alert() が正式名称です。言い換えると、 window というオブジェクトが持つ alert() という名前のメソッドである、ということができます。

このプログラムは、もちろん以下のように書き換えても、同じように動作します。

  <input type="button" value="hoge" onclick="window.alert('hoge');">  <!-- alert('hoge'); と同じこと -->

Web ブラウザ上で動作する JavaScript においては、 window は特別なオブジェクトで、 window オブジェクトが持っている変数 (属性) や関数 (メソッド) を用いる際には、「window.」という記述を省略することが許されています。

window オブジェクトには様々な役割の属性やメソッドがあらかじめ用意されています。それらは今後のチュートリアルで、追って紹介してゆくことにします。

それから、 JavaScript では、変数を使用する場合、 var 命令を用いて宣言する必要がありますが、

  var num = 10;     // 変数 num を宣言し、値 10 で初期化する

var 命令を用いずにいきなり適当な名前の変数に代入を行ってしまった場合、

  num = 10;         // 変数 num はまだ宣言されていないが…

通常エラーになることはありませんが、実際には以下のように、 window オブジェクトのメンバ変数に値を代入したものとして扱われるので、注意が必要です。

  window.num = 10;  // さっきの num = 10 と同じ意味

HTML を直接いじる

さて、ここからが本題です。メッセージボックスだけ出せても大したプログラムは作れませんので、実際に既に画面に表示されている内容を変更する方法について踏み込んでみることにしましょう。

JavaScript を用いて、 Web ブラウザ上の画面表示を変更するには、どうすればよいでしょうか? その答えの一つとして、 Web ブラウザが読み込んでいる HTML の内容を、 JavaScript から書き換えてしまう、という方法があります。

まず準備として、以下の HTML ファイルを見てください。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta http-equiv="content-script-type" content="text/javascript">
  <title>HTML look in test</title>
</head>

<body>

<p>これは、<strong>innerHTML プロパティ</strong>のテストです。</p>

</body>

</html>

この HTML ファイルは、部分的に強調表示を行ってはいるものの、文が 1行表示されるだけの非常に簡単なものです。このファイルの中に 1つだけ存在するパラグラフ、すなわち <p> タグの中に記述された HTML を JavaScript から参照するには、どうすればよいでしょうか?

その答えに当たるプログラムを、以下に示します。このプログラムは、先ほどの文の下にボタンが表示され、それをクリックすると、その文の HTML がメッセージボックスに表示されます。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta http-equiv="content-script-type" content="text/javascript">
  <title>HTML look in test</title>
  <script type="text/javascript" language="JavaScript"><!--
function lookInnerHtml() {
    var p = document.getElementById("main_paragraph");  // HTML を参照したいパラグラフを取得
    alert(p.innerHTML); // HTML をメッセージボックスに表示する
}
  //--></script>
</head>

<body>

<p id="main_paragraph">これは、<strong>innerHTML プロパティ</strong>のテストです。</p>

<form>
  <p><input type="button" value="HTML を表示" onclick="lookInnerHtml();"></p>
</form>

</body>

</html>

それでは解説していきましょう。まず、 HTML を参照しようとしている <p> 要素についてですが、

<p id="main_paragraph">これは、<strong>innerHTML プロパティ</strong>のテストです。</p>

よく見ると、 <p> タグに id 属性 が記述されています。こうすることで、個々の HTML 要素にユニークな ID を指定することができます。

これを踏まえて、ボタンをクリックしたときに呼び出される lookInnerHtml() 関数の実装を見てみましょう。

function lookInnerHtml() {
    var p = document.getElementById("main_paragraph");  // HTML を参照したいパラグラフを取得
    alert(p.innerHTML); // HTML をメッセージボックスに表示する
}

document オブジェクト (言うまでもなく、正式名称は window.document です) は、Web ブラウザに読み込まれた HTML 文書を操作する際に用いるオブジェクトです。 window オブジェクトと同様、さまざまな機能があり、多くの属性とメソッドを持っていますが、その中でも document.getElementById() メソッドは、今後もっとも頻繁に利用するメソッドの一つです。このメソッドは、先ほどの id 属性に記述した ID で HTML 要素を検索し、その HTML 要素をオブジェクトとして取得する、というものです。

すなわち、

    var p = document.getElementById("main_paragraph");  // HTML を参照したいパラグラフを取得

と記述することによって、変数 p に、「main_paragraph」という ID が設定された要素、すなわち先ほどの <p> タグが、 JavaScript 言語で扱うオブジェクトとなって代入される、という処理が行われることになります。

次に、いつもの alert() メソッドによってメッセージボックスを表示しようとしていますが、その引数に注目してください。

    alert(p.innerHTML); // HTML をメッセージボックスに表示する

document.getElementById() メソッドなどによって取得された HTML 要素オブジェクトも、これまたさまざまな属性やメソッドを持っています。その中の一つ、 innerHTML 属性は、まさにその属性が内包する HTML そのものを、文字列として保持する、というものです。これによって、 <p> ~ </p> の間に挟まれている文の HTML が、メッセージボックスにそのまま表示される、というわけです。

それでは、逆にこの innerHTML 属性に対して文字列を代入した場合、何が起きるでしょうか? すでにご想像の通り、まさに、代入したとおりに HTML が書き換わり、その内容に合わせて画面の表示も変化します!!

以下のサンプルプログラムは、入力欄に HTML の文字列を入力し、ボタンを押すと、下の枠の中に、入力した HTML を Web ブラウザが解釈した結果が表示される、というものです。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta http-equiv="content-script-type" content="text/javascript">
  <title>HTML modify test</title>
  <script type="text/javascript" language="JavaScript"><!--
function displayHtml() {
    var textarea = document.getElementById("html_input");
    var view = document.getElementById("result_view");
    view.innerHTML = textarea.value;
}
  //--></script>
</head>

<body>

<form>
  <p><textarea id="html_input" cols="80" rows="5"></textarea></p>
  <p><input type="button" value="表示する" onclick="displayHtml();"></p>
</form>

<div id="result_view" style="width: 720px; height: 540px; border: 1px solid #000;"></div>

</body>

</html>

解説しましょう。まずは HTML で記述された部分。

<form>
  <p><textarea id="html_input" cols="80" rows="5"></textarea></p>
  <p><input type="button" value="表示する" onclick="displayHtml();"></p>
</form>

<div id="result_view" style="width: 720px; height: 540px; border: 1px solid #000;"></div>

入力欄となる <textarea> 要素、および結果を表示する領域となる <div> 要素のそれぞれに、 id 属性による ID が設定されています。

<div> 要素には style 属性も設定されていますが、これは表示領域を固定の大きさの枠として表示する為のものです。

次に、ボタンをクリックしたときに呼び出される displayHtml() 関数の実装を見てみましょう。

function displayHtml() {
    var textarea = document.getElementById("html_input");
    var view = document.getElementById("result_view");
    view.innerHTML = textarea.value;
}

最初の 2行で、 ID を設定していた 2つの HTML 要素のオブジェクトを取得し、それぞれ別個の変数に代入しているのが分かると思います。

そして、 3行目で <div> 要素の innerHTML 属性に、 <textarea> 要素の value 属性を代入しています。

    view.innerHTML = textarea.value;

<textarea> 要素や <input> 要素、 <select> 要素といった、いわゆるフォーム部品を document.getElementById() などによって取得したオブジェクトには、ほとんどの場合 value という属性が用意されています。これは、その Web ページを閲覧しているユーザーが、実際にフォーム部品に入力した値を参照する属性です。この属性も、逆に代入することが可能で、その場合、代入された値でフォーム部品の表示が反映されることになります。

さておき、プログラムの内容が分かったところで、試しにこのプログラムを Web ブラウザに読み込ませて、入力欄に適当な HTML を入力し、「表示する」ボタンをクリックしてみてください。下の枠内に、その HTML が Web ブラウザに解釈された結果が表示されるのが分かると思います。1回だけではなく、入力欄の内容を書き換えては、何度でも「表示する」ボタンを試してみてください。クリックするたびに、下の枠内の表示が、書き換えた内容に応じて変化するのが分かると思います。

DOM を扱う

実は、画面表示に関してのみいうのであれば、理論的には先ほどの innerHTML 属性だけであらゆる操作が可能です。そして、実際のところ、画面表示の操作は何でもかんでも innerHTML でやってしまおう、という考え方の Web プログラマーも少なくありません。

しかし、 innerHTML を用いる方法はあまりにも原始的である為、それを補う為には、プログラミングの際に以下の点に気をつける必要があります。

  1. innerHTML に HTML を代入する場合、その HTML の文法に誤りがないよう気をつける必要がある。
  2. 外部から入力した文字列を表示する場合、 HTML タグ等に誤解されないよう、 HTML マークアップ用の文字 (「<」、「>」、「&」、「"」) を実体参照 (「&lt;」等) に変換する必要がある。
  3. ある要素の innerHTML 属性に代入した HTML 要素の配下にあとから HTML を記述したい場合、その要素を document.getElementById() で取得できるようにあらかじめ id 属性付きで記述しておく必要がある。

これに対して、 HTML 文書をオブジェクトのツリー構造に見立てて扱い、操作する方法があります。そのようなモデルのことを、 DOM (Document Object Model) と呼びます。

Note: See TracWiki for help on using the wiki.