uhyohyo.net

JavaScript初級者から中級者になろう

基礎第五回

イベント

今回はイベントについて解説します。イベントといっても、お祭りとかではありません。

JavaScriptでのイベントとは、何かが起こったときにJavaScriptが動くことです。

何かが起こるとは、例えばクリックしたとか、そういうことです。サンプルを見てみましょう。今回はHTMLが絡んでくるので久しぶりにHTMLを全部示します。

<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <p style="width:200px;height:200px;background-color:#ff0" onclick="alert('click');">test</p>
  </body>
</html>

実行してみても、黄色い長方形があるだけで何も起こりません。

サンプルも、いつもとは何か違うようです。まず、いつもあるscript要素がありません。そして、pタグに2つも属性がついています。style属性とonclick属性です。

このstyle属性は、スタイルシートの設定をしているので、今回あまり関係ありません。このスタイルシートによって、p要素があの黄色い四角になっています。

重要なのは、その次のonclick属性です。onclick属性の中には、なんとJavaScriptが書かれています。

実は、このonclick属性の中身が、クリックされると実行されます

今回、このonclick属性はpタグについているので、p要素をクリックしたときに実行されるというわけです。ちなみに、クリックされる度に何回でも実行されます。

一応中身を見てみます。

alert('click');

普通にアラートを表示しているだけなのですが、その引数が不可解です。

クリックすると「click」と表示されるのでこれは文字列のようですが、「"」ではなく「'」で囲まれています。

実は、'」で囲んでも文字列になります

HTMLの属性が「"」で囲まれているので、その中で再び「"」を使うとわからなくなってしまいます。そこで、異なる記号を使うようにしているのです。

また、次のサンプルを見てみましょう。

<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <script type="text/javascript">
function aaa(){
    alert('click');
}
    </script>
    <form action="#">
      <p><input type="button" value="click!" onclick="aaa();"></p>
    </form>
  </body>
</html>

画面にボタンが現れ、クリックするとアラートが出ます。

このように、ボタンにonclickを付けて押されると何か処理をするというのもよくあります。

また、今回はちゃんとscript要素もあります。しかし、中身を見てみると、関数aaaを作っているだけで何もしていません。実は、この関数aaaはinputのonclick属性内で使われています。処理が長くなる場合は、このようにonclick内では関数呼び出しをするだけにして、関数内で多くの処理をする方法がよいです。

短いですが、今回のイベントの解説はこれで終了します。ずっとアラートで結果を見るだけというのもつまらないので、これを解説してみました。

繰り返し

同じ処理を何度も繰り返したいということはよくあります。そういう時のための書き方があります。今回は、そのうちwhile文を解説します。

次のサンプルを見てみましょう。

var i = 0;
while(i < 5){
    alert(i);
    i++;
}

「0」「1」「2」「3」「4」と5回アラートが出ました。

しかし、スクリプト中にalertは1度しかありません。当然、「while」が関係しています。今回はこれを解説していきます。

このwhile文は次のように書きます。

while(  ){
    文(いくつでも)
}

それでは、while文のはたらきを解説します。

while文の行に来ると、括弧の中のが計算されます。そして、だった場合{ 〜 }の文を実行し、だった場合{ 〜 }の中を飛ばして処理を終了します

ここまでだと、if文と同じように条件分岐のように思えます。しかし、ここから先に大きな違いがあります。

真の場合に{ 〜 }の処理を全て実行すると、なんとwhileの行に戻ります

そしてまた条件を判断し、真の場合実行してまた戻ります。条件に使う式が同じだし、永遠に繰り返すように見えますが、そういうわけでもありません。判断に使う式に変数などを使えば、結果が変わる可能性があります。このサンプルなどが例です。

それでは、このサンプルの動作を見てみましょう。

まず、変数iに0を代入します。次の行で、「i < 5」は、iは0で5より小さいのでtrueを返します。つまりです。

よって、中の文が実行されます。中の文では、iをアラートで表示します。いま、iは0なので、0が表示されます。

その次の行を見てみましょう。見たことがない処理ですね。しかし、この文は「iに1をたす」という意味です。詳しくは後で解説します。よって、iはここで1になります。

さて、ここで処理が終わったのでwhileの行に戻ります。「i < 5」は同じくtrueを返すので、またアラートが表示されiが1増えて2になります。

この繰り返しは、i < 5がfalseを返すようになるまで続きます。つまりそれは、iが5になったときです。

iが4になるまで繰り返してアラートが4を表示したところから追ってみましょう。

i++;の文により、iが5になります。ここでwhileの行に戻りますが、i < 5falseを返すためここで処理が終了します。よって、5のアラートは表示されることなくwhile文は終了します。

このようにwhile文を使うと同じ処理を何度も繰り返すことができます。

ただし、while文を使う場合必ず処理がいつか終わるようにしましょう。いつまでも式が真のままで繰り返し続けると、永遠に処理をし続けてブラウザがフリーズしてしまうことがあり危険です。

インクリメント・デクリメント

さっき出てきた「i++;」の解説をします。実は、「++」が新しい演算子で、インクリメント演算子といいます。

しかし、今までと多少様子が違います。今までの演算子は「3 + 5」とか「a = 7」のように左右に値がありました。

それが、今回は左に変数iがあるのみで右にはなにもありません。実は、この演算子は、影響を与える(または影響を受ける)値(オペランドといいましたね)が1つしかありません

ちなみに、このようにオペランドが1つしかない演算子を単項演算子といいます。対して、2つある演算子は二項演算子といいます。

それでは、このインクリメント演算子のはたらきですが、上でちらと解説したように変数に1を足します。つまり、

i++;
i+=1;

の2つの文は同じ動作をしていることになります。

ちなみに、++i;のように変数の前につけることもできます。変数に1を足すのは同じです。

ただし、1つだけ違いがあります。それは返す値の違いです。演算子が前にあると足した後の値を返し、後にあると足す前の値を返します。

さらに、「--」という演算子があります。インクリメント演算子が変数に1を足すのに対し、変数から1を引く演算子で、デクリメント演算子といいます。使い方はまったく同じです。

break文・continue文

繰り返し(ループともいいます)を操作するための文があります。次のサンプルを見てみましょう。

var i = 0;
while(true){
    i++;
    if(i < 2){
        continue;
    }
    alert(i);
    if(i > 5){
        break;
    }
}

「2」「3」「4」「5」「6」と5回アラートが出ました。

気づく人は気づいたと思いますが、whileの式がtrueとなっています。つまり必ず真となっています。これはたいへん危険なはずです。

しかし、特にフリーズなどすることなく正常に5回アラートが出たと思います。これには、新しく出てきた「break」と「continue」の2つが関係しています。

さて、continueの解説をします。このcontinue文は、強制的にループの最初に戻るというはたらきをします。今回の場合、whileの行まで戻ることになりますね。

breakは、ループを強制的に終了するというはたらきをします。ループが正常に終了したのは、このbreakによるものでした。

とりあえずコードを追っていきましょう。

まず変数iに0を代入し、whileの行に入ります。ここで式がtrueなので、ループに入ります。

ループの最初でiに1を足しているので、ここでiの値は1です。その次の行のif文で「i < 2」はtrueを返し真なので、中の文が実行されます。

ここで、continue文が実行されるので、whileの行まで戻ります。さて、ループを初めからやり直すと、iにiを足してiが2になります。

今度はifの条件は偽なのでこの中のcontinueは実行されず、次の行に進みます。ここでalertでiが表示されるので、「2」が表示されます。

次のif文の「i > 5」は偽なので、breakは実行されず最初に戻ります。その後iが3になり同様の処理がされます。「i < 2」が真になることはもう二度とないですね。よってalertで3が表示されます。

その後の「i > 5」も、「iが5より大きい」という意味なので、iが6以上になるまでは真を返さないのが分かると思います。だから、「3」「4」「5」と表示されるまで順調に進んでいきます。

「5」を表示した後もまだi > 5は偽なので次にiが6になります。

ここで、「6」を表示した後次のifが真になりbreakが実行されます。breakはループを終了するというものなので、ここでwhileが終了します。ちなみにbreakは、while文の処理にまだ続きがあっても途中で抜けます。

少し長かったですが、これが一連の流れです。

do 〜 while文

さて、while文には仲間みたいなのがいます。do 〜 while文です。サンプルを見てみましょう。

var i=0;
do{
    alert(i);
    i++;
}while(i < 3);

「0」「1」「2」とアラートが出ます。

実は、while( 式 ){ 〜 }{ 〜 }がwhileの後ろではなく前についただけです。つまり、次のようになります。

do{
    文(いくつでも)
}while( 式 )

ただし、最初にdoをつける必要があります。

ただのwhileとの違いですが、do 〜 while文は中の文を先に実行してから式の真偽を判定します。これの違いは、次のような場合に現れてきます。

do{
    alert("test");
}while(false);

「test」とアラートが出ます。

これは、まず中の処理、つまりalertを実行して、それからwhileの判定をして偽なのでループを終了するという処理からきています。これが、ただのwhile文だったらどうでしょう。

while(false){
    alert("test");
}

アラートは出ません。

まずwhileが判定されていきなり偽なので、一度も中の処理が実行されずに処理が終わるからです。このように、条件がいきなり偽だった場合に、1度実行されるか1度も実行されないかの違いがあります。