5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【JavaScript】1日で基本を学ぶ〜後編

Last updated at Posted at 2018-05-27

イベントとは

今回も、引き続きこちらの本を参考にさせていただいた。
岩田宇史「いちばんやさしいJavaScriptの教本」(インプレス)

まずイベントを理解するにあたり、JavaScriptで実装できる動作の一例を紹介する。

  • ボタンをクリックしたら、入力フォームが表示される
  • マウスポインタが当たったら、文字の色が変わる
  • 入力フォームに文字を入力したら、その文字数が表示される

どれも、ユーザー側の動作動作の結果実行されることが対になっている。上記の例では、以下の動作がユーザー側の動作に該当するだろう。

  • ボタンをクリックする
  • マウスポインタを特定の箇所に当てる
  • 入力フォームに文字を入力する

これらのユーザー側の動作がイベントと呼ばれているものだ。

イベントの設定

上記で紹介した動作を実現するためには、イベントイベントに伴い実行される内容を設定しなければならない。その方法には幾つか種類があるのだが、今回はイベントリスナーによる設定を行ってみる。

早速プログラムを書いてみた。

ボタンをクリックしたら、入力フォームが表示される

このためにプログラムに必要となる要素は、当然ボタン入力フォームだ。id="button"id="form"の要素を取得する。

使用するイベントはclickだ。このイベントは、その名の通り要素をクリックした時に発生する。

HTML

HTMLでは通常の入力フォームを記述する。

test.html
<head>
  <!-- 省略 -->
  <link rel="stylesheet" href="css/style.css">
</head>
<body>
  <button id="button">フォーム表示</button><br>
  <form action="" id="form">
    <textarea id="textarea" name="textarea"></textarea></br>
    <input type="submit" id="submit" value="送信">
  </form>
  <script src="js/app.js"></script>
</body>

CSS

CSSで入力フォームの表示を阻止している。ボタンがクリックされたらフォームを表示させるため、あえてnoneにする。

style.css
#form {
  display: none;
}

JavaScript

ここでイベントリスナーが登場する。イベントリスナーはイベントイベントに伴い実行される内容をそれぞれ引数に取り、処理を実行する。

イベントに伴い実行される内容は、基本的に無名関数として記述する。名前付き関数で引数をとる場合は、無名関数の中で呼び出さなければならない。

app.js
var button = document.getElementById('button');
var form = document.getElementById('form');

button.addEventListener('click', function() {
  form.style.display = 'block';
});

動作の流れはこうだ。

  • documentオブジェクトのgetElementByIdメソッドで、HTMLに記述されているid="button"id="form"の要素をオブジェクトとして取得する。
  • buttonオブジェクトのaddEventListenerメソッドを使用する。
  • 上記メソッドの第1引数はイベントであるclick第2引数はイベントに伴い実行される内容を無名関数として記述する。
  • この場合、formオブジェクトのstyleプロパティから呼び出されるdisplay(CSSで設定されるプロパティ)blockを代入している。
  • 結果、CSSで設定されていたdisplay: none;display: block;に置き換わり、フォームが表示される。

マウスポインタが当たったら、文字の色が変わる

ここで必要な要素は、文字(を囲んでいる要素)だ。id="greeting"の要素を取得する。

今回使用するイベントはmouseoverだ。これは、マウスポインタが該当する要素の上に乗った時に発生するイベントだ。

HTML

test.html
<body>
  <div id="greeting">
    <h1>ようこそ!</h1>
  </div>
  <script src="js/app.js"></script>
</body>

JavaScript

今回はイベントの発生により、CSSのcolorプロパティを変更している。マウスポインタが要素の上に乗った時、文字の色が赤に変わる。

app.js
var greeting = document.getElementById('greeting');

greeting.addEventListener('mouseover', function() {
  greeting.style.color = '#FF0000';
});

入力フォームに文字を入力したら、その文字数が表示される

入力フォームに文字を入力した場合、新しい要素が挿入され、そこに文字数が表示される。入力フォームそのものであるid="textarea"の要素と新要素divの取得が必要となる。

また、使用するイベントkeyupはキーを離した時(=入力文字数)に発生する。

HTML

test.html
<body>
  <button id="button">フォーム表示</button><br>
  <form action="" id="form">
    <textarea id="textarea" name="textarea"></textarea></br>
    <input type="submit" id="submit" value="送信">
  </form>
  <script src="js/app.js"></script>
</body>

JavaScript

app.js
var button = document.getElementById('button');
var form = document.getElementById('form');

button.addEventListener('click', function() {
  form.style.display = 'block';
});

// 以下を追記

var textarea = document.getElementById('textarea');
var text_counter = document.createElement('div');
var parent = textarea.parentElement;
parent.insertBefore(text_counter, null);

textarea.addEventListener('keyup', function(event) {
  console.log(event.key);
  // console.log(textarea.value);
  text_counter.innerHTML = "<h2>現在" + textarea.value.length + "文字入力しています</h2>";
});

動作を解説する。

  • documentのgetElementByIdメソッドによりtextareaオブジェクトを取得する。
  • documentのcreateElementメソッドdivタグを作成しtext_counterへ代入。オブジェクトとして扱う。
  • textareaオブジェクトのparentElementメソッドで親要素を取得し、さらに親要素のinsertBeforeメソッドtext_counterオブジェクトを追加する。
  • textareaオブジェクトのaddEventListenerメソッドで、動作のタイミングとなる第1引数keyupを指定する。
  • 第2引数である無名関数で、text_counterオブジェクトのinnerHTMLメソッドにより入力文字数を示す文を挿入する。

入力文字数自体は、textarea.value.lengthで簡単に取得できる。また、console.log(textarea.value);を試してみると、1文字入力する度にvalue属性の内容(=入力内容)がコンソールに出力される。

さらに、今回の無名関数では第1引数としてeventを指定している。これはイベントオブジェクトと呼ばれており、イベントに関する情報が格納されている。

この情報を使用したい場合は、無名関数の第1引数として指定すれば、関数内で使用することができる。今回はconsole.log(event.key)の記述で、eventオブジェクトのkeyプロパティの内容がコンソールに出力される。

オブジェクトのメソッドを使用する

今までイベントに伴う動作には既存のメソッドを使用してきた。今回は独自のメソッドを定義し、それを使用してみる。

オブジェクトの定義

メソッドを定義するには、まず元となるオブジェクトが必要だ。以下の構文で、オブジェクトを変数thanksに代入している。

定義している内容は、messageプロパティthanksMessメソッドの2つだけだ。

thanksMessメソッドのreturn文にあるthisは、この構文内ではthanksオブジェクト自身を表している。this.messagethanksオブジェクトのmessageプロパティつまり"<h2>ありがとう!</h2>"を呼び出している。

app.js
var thanks = {
  message: "<h2>ありがとう!</h2>",
  thanksMess: function() {
    return this.message;    
  }
}

ボタンをクリックしたら、メッセージを表示する

id="thanks_button"のボタンがクリックされたら、id="message"の中にメソッドの結果(メッセージ)が表示される仕組みだ。

HTML

test.html
<body>
  <input type="button" id="thanks_button" value="メッセージ表示">
  <div id="message"></div>
  <script src="js/app.js"></script>
</body>

JavaScript

他のイベントリスナーの記述法とほぼ変わらない。ただし、メソッドを呼び出す場合はthanks.thanksMess()のように、オブジェクト名.メソッド名と記述しなくてはならない。

app.js
var thanks = {
  message: "<h2>ありがとう!</h2>",
  thanksMess: function() {
    return this.message;    
  }
}

// 以下を追記

var thanks_button = document.getElementById('thanks_button');
var message = document.getElementById('message');

thanks_button.addEventListener('click', function() {
  message.innerHTML = thanks.thanksMess();
});

イベントハンドラについて

イベントを記述するもう1つの方法がイベントハンドラだ。よくHTMLのbuttonタグ内でonClickという記述を見かけるが、これがそうだ。また、JavaScript内にも記述が可能だ。

しかし、その結果実行できる関数は1つに限られるため、参考にした基本書の中ではあまり推奨されていなかった。

イベントハンドラについては、こちらの記事が参考になる。
JavaScriptのイベントハンドラ一覧-PHP & JavaScript Room

まとめ

結局記事の作成には2日間かかってしまったが、JavaScriptの概要はざっくり把握できたと思う。次はVue.jsにチャレンジしてみたいのがだが、jQueryにも興味がある。

自分が作成しているアプリは学習も兼ねた超小規模なものなので、それに合わせて選択したいと思う。様々なライブラリ・フレームワークの動作確認も兼ねて。

さらに、今回の学習ではイベント時の動作は実行できたが、その逆ができなかった。(もう一度クリックするとフォームが非表示になる等・・・)色々試してみたが、CSSの要素の取得が難しい。解決策としてイベントハンドラによる記述例も見かけたが、時と場合により使い分けるものなのだろうか?

課題も多いが、今回はここまで。

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?