前の記事で扱った重要な理屈をたくさん使って、この記事では実践的な練習を行ないます。ここではあなたが自力で独自関数を作成するための練習を行なっていきます。同時に、関数を扱う上で役に立つ細々の説明もしていきます。

前提知識: 基本的なコンピュータの知識、 HTML と CSS への理解、 JavaScriptの第一歩 関数 — 再利用可能なコードブロック
目的: 独自の関数を作成する練習、役に立つ関連事項についてつっこんだ説明。

Active learning: 関数を作ってみよう

これから作ってみる独自の関数を displayMessage()。これは独自のメッセージボックスをウェブページ上に表示し、ブラウザ組込みのalert()関数の特製の代替品として動作します。既に見たものですが、忘れた事にしましょう。以下をブラウザのJavaScriptコンソールから打ち込みます、どのページでも構いません:

alert('This is a message');

alert関数は引数を一つ取ります — アラートボックスに表示される文字列です。文字列を色々変えてメッセージを変化させてみて下さい。

alert関数には制限があります: メッセージを変更することはできますが、色やアイコンなど、それ以外の部分を簡単には変えられません。もっと楽しくできるやつを作りましょう。

メモ: この例題は全てのモダンブラウザ上で問題なく動くはずですが、古いブラウザではちょっとおかしな見た目になるかもしれません。この課題はFirefox、Opera、Chromeのようなモダンなブラウザ上で行なうのが推奨です。

基本的な関数

最初に、基本的な関数を組み立てていきましょう。

Note: 関数に名前を付ける方針としては、変数名に名前をつける方針と同じルールに従うべきです。問題はありません、すぐに見分けがつくからです — 関数ならすぐ後にカッコが付きますが、変数には付きません。

  1. function-start.html ファイルにアクセスして、ローカルコピーを作成するところから初めます。HTMLは単純です — bodyにはボタン一つしかありません。特製メッセージボックス用の基本的なCSSスタイルと、JavaScriptを追加していく用の空の<script>要素が含まれています。
  2. 次に、<script>要素の中に以下を追加して下さい:
    function displayMessage() {
     
    }
    キーワード function から始めますが、これは関数を定義するという意味です。この後には、関数につけたい名前、カッコの組、中括弧の組と続きます。関数に渡したい引数はカッコの中に、関数を呼び出したときに走らせたいコードは中括弧の中に書きます。
  3. 最後に、以下のコードを中括弧の中に追加します:
    var html = document.querySelector('html');
    
    var panel = document.createElement('div');
    panel.setAttribute('class', 'msgBox');
    html.appendChild(panel);
    
    var msg = document.createElement('p');
    msg.textContent = 'This is a message box';
    panel.appendChild(msg);
    
    var closeBtn = document.createElement('button');
    closeBtn.textContent = 'x';
    panel.appendChild(closeBtn);
    
    closeBtn.onclick = function() {
      panel.parentNode.removeChild(panel);
    }

これは見ていくにはそこそこの量のコードですから、いっしょに一つ一ついっしょに進んでいく事にしましょう。

最初の行では document.querySelector() と呼ばれるDOM API関数を使って<html>要素を選択し、htmlという名前の変数に要素への参照を保存したので、これを使っていろいろやっていきます:

var html = document.querySelector('html');

次の部分では別の DOM API 関数Document.createElement() を使い、<div> 要素を作成、これへの参照をpanelという変数に保存しています。この要素は我々のメッセージボックスの外枠となっていきます。

次にまた別の DOM API 関数Element.setAttribute() を使って、我々のパネルの class 属性とその値msgBoxを設定します。 これは要素のスタイルを指定しやすくするためです — ページの CSS を見ると、メッセージボックスとその中身に適用するスタイルとして.msgBox クラスセレクターがあるのがわかるでしょう。

最後に、前に保存した html 変数の DOM 関数 Node.appendChild() を呼んでいますが、この関数は一つの要素を別の要素の子として組み入れる働きをします。panelという<div>要素を子として、<html>要素の中に追加したいのです。 作成した要素は作成したページにぽんと現われたりはしません — どこに置くのかも指定しなければなりません。なのでこのようにする必要があります。

var panel = document.createElement('div');
panel.setAttribute('class', 'msgBox');
html.appendChild(panel);

次の2つのセクションでは既に見た同じcreateElement()appendChild() 関数を使用して、2つの新しい要素、つまり<p><button> を作成し、<div>パネルの子要素としてページに挿入します。 段落の中にメッセージを挿入する Node.textContent プロパティ (要素のテキスト内容を表す) とボタンの中に 'x' を使います。このボタンは、ユーザーがメッセージボックスを閉じるときにクリック/アクティブ化する必要があります。

var msg = document.createElement('p');
msg.textContent = 'This is a message box';
panel.appendChild(msg);

var closeBtn = document.createElement('button');
closeBtn.textContent = 'x';
panel.appendChild(closeBtn);

最後に、GlobalEventHandlers.onclick イベントハンドラを使用して、ボタンをクリックするとページ全体をパネルから削除してメッセージボックスを閉じるようにします。

簡単に説明すると、onclickハンドラはボタン (または実際にはページ上の任意の要素) で使用できるプロパティで、ボタンをクリックしたときに実行するコードを指定する関数に設定できます。後のイベントの記事で、これらについてさらに詳しく学びます。onclickハンドラは、ボタンがクリックされたときに実行されるコードを含む無名関数と等しくなります。 関数内の行は Node.removeChild() DOM API関数を使用して、HTML要素の特定の子要素 (この場合は <div> パネル) を削除することを指定します。

closeBtn.onclick = function() {
  panel.parentNode.removeChild(panel);
}

基本的には、このコードブロック全体がHTMLのブロックを生成してページに挿入しています。

<div class="msgBox">
  <p>This is a message box</p>
  <button>x</button>
</div>

作業するコードがたくさんありました。今のところどのように動作しているか正確に覚えていないことをあまり心配しないでください! ここでは、関数の構造と使用法を中心に説明しますが、この例では何か面白いことを示したかったのです。

関数の呼び出し

これで、<script> 要素に書かれた関数定義がうまくいきましたが、それは何もしません。

  1. 関数の下に次の行を含めて呼び出してみてください:
    displayMessage();
    この行は関数を呼び出し、すぐに実行させます。コードを保存してブラウザを再読み込みすると、小さなメッセージボックスがすぐに1回だけ表示されます。それを一度呼ぶだけです。
  2. サンプルページでブラウザの開発者ツールを開き、JavaScriptコンソールに移動してもう一度その行を入力すると、もう一度表示されます。これは楽しいことです - 私たちは今好きな時に呼び出すことができる再利用可能な関数を持っています

    しかし、ユーザーとシステムのアクションに応じて表示されるようにすることをお勧めします。実際のアプリケーションでは、このようなメッセージボックスは、新しいデータが利用可能であること、エラーが発生したこと、ユーザーがプロファイルを削除しようとしている(「これは本当ですか?」)、またはユーザーが 新しい連絡先や操作が正常に終了しました...などが起こったときに呼び出されるでしょう。

    このデモでは、ユーザーがボタンをクリックするとメッセージボックスが表示されます。

  3. 追加した前の行を削除します
  4. 次に、ボタンを選択し、そのボタンへの参照を変数に格納します。 関数定義の上のコードに次の行を追加します
    var btn = document.querySelector('button');
  5. 最後に、前の行の下に次の行を追加します
    btn.onclick = displayMessage;
    関数内のcloseBtn.onclick...行と同様に、ここではボタンがクリックされたことに応答してコードを呼び出します。しかしこの場合、コードを含む無名関数を呼び出す代わりに、関数名を直接呼び出しています。
  6. ページを保存して再表示してみてください。ボタンをクリックするとメッセージボックスが表示されるはずです

関数名の後ろにカッコが含まれていないのはなぜでしょうか。これは、ボタンがクリックされた後にのみ、関数をすぐに呼びたくないからです。行を次の行に変更しようとすると

btn.onclick = displayMessage();

保存して再読み込みすると、ボタンをクリックせずにメッセージボックスが表示されます。このコンテキストのかっこは「関数呼び出し演算子」と呼ばれることがあります。現在のスコープですぐに関数を実行する場合にのみ使用します。同様の点で、匿名関数内のコードは関数スコープ内にあるため、すぐには実行されません。

最後の実験を試した場合は、最後の変更を取り消してから実行してください。

パラメータを使用して関数を改善する

その機能はそれほど便利ではありません - 毎回同じ既定のメッセージを表示したくはないのです。いくつかのパラメータを追加して機能を改善し、いくつかの異なるオプションで呼び出すことができるようにしましょう。

  1. まず、関数の最初の行を更新します。
    function displayMessage() {
    このようになります
    function displayMessage(msgText, msgType) {
    関数を呼び出すと、カッコ内に2つの変数値を指定して、メッセージボックスに表示するメッセージとそのメッセージのタイプを指定できます。
  2. 最初のパラメータを使用するには、関数内の次の行を更新します
    msg.textContent = 'This is a message box';
    このようになります
    msg.textContent = msgText;
  3. 最後に関数呼び出しを更新して、更新されたメッセージテキストを追加する必要があります。次の行を変更します。
    btn.onclick = displayMessage;
    このブロックのようになります
    btn.onclick = function() {
      displayMessage('Woo, this is a different message!');
    };
    私たちが呼び出している関数のかっこ内にパラメータを指定したい場合、直接呼び出すことはできません - 直接のスコープにないため、すぐに呼び出されないように無名関数の中に入れる必要があります。ボタンがクリックされるまで呼び出されません。
  4. 再読み込みしてコードをもう一度試してみてください。それでもパラメータ内のメッセージを変えてボックスに表示されるメッセージを変えることができます。

より複雑なパラメータ

次のパラメータをオンにします。これにはもう少し作業が必要です。msgTypeパラメータの設定によって、別のアイコンと異なる背景色が表示されるように設定していきます。

  1. まず始めに、この演習に必要なアイコン (warningchat) をGitHubからダウンロードしてください。HTMLファイルと同じ場所にあるiconsという新しいフォルダに保存します
    メモ: iconfinder.com にある warningchat のアイコンは Nazarrudin Ansyari によってデザインされたものです。ありがとう!
  2. 次に、HTMLファイル内のCSSを探します。私たちは、アイコンの道を作るためにいくつかの変更を行います。まず .msgBox の幅を次のように更新します
    width: 200px;
    このようにします
    width: 242px;
  3. 次に、.msgBox p { ... } ルール内に次の行を追加します
    padding-left: 82px;
    background-position: 25px center;
    background-repeat: no-repeat;
  4. これでアイコンの表示を処理するために、displayMessage()関数にコードを追加する必要があります。関数の終了中かっこ (}) のすぐ上に次のブロックを追加します。
    if (msgType === 'warning') {
      msg.style.backgroundImage = 'url(icons/warning.png)';
      panel.style.backgroundColor = 'red';
    } else if (msgType === 'chat') {
      msg.style.backgroundImage = 'url(icons/chat.png)';
      panel.style.backgroundColor = 'aqua';
    } else {
      msg.style.paddingLeft = '20px';
    }
    ここで、msgTypeパラメータが 'warning' に設定されている場合、警告アイコンが表示され、パネルの背景色は赤に設定されます。 'chat'に設定されている場合、チャットアイコンが表示され、パネルの背景色が青色に設定されます。msgTypeパラメータがまったく設定されていない (または別のものに変更されている) 場合、コードのelse { ... } 部分が有効になり、段落には単にデフォルトのパディングが与えられ、背景パネルの色もしくはアイコンのどちらかが未設定の状態となります。これはmsgTypeパラメータが指定されていない場合、省略可能なパラメータであることを意味するデフォルトの状態を提供します。
  5. 更新された関数をテストして、displayMessage() を次のように更新してみましょう:
    displayMessage('Woo, this is a different message!');
    これらの中の1つになります
    displayMessage('Your inbox is almost full — delete some mails', 'warning');
    displayMessage('Brian: Hi there, how are you today?','chat');
    私たちの (今はそうではない) 小さな機能がどのように役立つかがわかります。

メモ: サンプルをうまく動作させることができない場合は、コードをGitHubの完成バージョンと比較して (see it running live もみて) チェックしてください。もしくは私たちにヘルプを依頼してください。

まとめ

最後までたどり着きました。おめでとうございます! この記事では、実用的なカスタム関数を構築するプロセス全体を紹介しました。もう少し動けば、実際のプロジェクトに移植することができます。次の記事では、別の重要な関連概念である戻り値を説明して関数をまとめます。

モジュール内の文書

 

ドキュメントのタグと貢献者

このページの貢献者: silverskyvicto, i12o
最終更新者: silverskyvicto,