作成日:2021/04/12 更新日:2022/08/05

#8 変数を使う

「変数」という便利な機能を使ってみましょう。

変数へんすうとは簡単に言えば(数値や文字列や式)を入れておく箱や引き出しのようなものです。
変数名の前にletレットconstコンストvarバーvariable変数の略)という文字を付けて変数を作成します。(変数の定義)
=イコール をつけて右側(右辺)にある値を変数に入れます(代入する)。

let 変数名 = 1;	/* 数値 */
let 変数名 = "CRI";	/* 文字列 */
let 変数名 = x+y;	/* 式 */
変数名は、htmlのクラス名と同様自分で好きな名前や英単語などをつけます。 「let」という文字を変数名の頭につけることで変数宣言したことになります。
変数という箱には、文字列や数値、計算結果の答えなどを入れておき、のちのち計算などにつかっていく事ができます。
変数を宣言するときにはvar以外にも、 letレットconstコンストというのもあります。
同じ式のなかで再度、宣言や代入し直せるかが異なります。
varの場合

var hoge = 1;	// 1回目の宣言と代入

var hoge = 2;	// 2回目の宣言と代入(OK)
hoge     = 2;	// 再代入(OK)
このとき変数hogeには「2」が入っていますが、
letの場合

let hoge = 1;	// 1回目の宣言と代入

let hoge = 2;	// 2回目の宣言と代入(エラー)
hoge     = 2;	// 再代入(OK)
constの場合

const hoge = 1;	// 1回目の宣言と代入

const hoge = 2;	// 2回目の宣言と代入(エラー)
hoge        = 2;	// 再代入(エラー)
このように変数の頭にletやconstを記述すると再宣言はできず`再宣言`エラーとなります。 また変数の頭にletやconstを記述せずに値を代入(再代入)しようとすると、letはできますが、constの場合はエラーとなります。

varはひとつの関数内であればどこでも使えたり再宣言もできますが、letやconstは関数内のなかでも、ある一つの式ブロックスコープ (if文など)の中だけで値を使えるという特徴があります。

本来は変数が使用できる範囲スコープを設定することが好ましいです。 ですのでvarではなく基本的にはconstを使用し、再代入が必要なときにはletを使うということが良いこととされます。
ひとまずこの基礎講座ではletで説明していきます。

足し算してみる

+ =

<script>
$(function(){
  $('#calc').on('change', function(){             /* onメソッド changeイベント = #calc内の要素に変更されるイベントが発生したら */
    let numA = parseInt( $('.number_A').val() );  /* $(クラス名).val() でinput内の文字を取得できる */
    let numB = parseInt( $('.number_B').val() );  /* parseInt(文字) parseIntで文字が数値になる */
    $('#number_total').text(numA + numB);         /* textメソッドで対象のidに文字列を出力 */
  });
});
</script>

+ =
on()メソッドを使います。
onメソッド内でchangeイベントを指定しています。#calc内にある要素に、変更されるイベントが発生したら処理が実行されるという機能です。
このようにクリックしたとき、要素が変更になった時といった動作に対応して動きの処理を行うものをイベントハンドラ(イベントを扱う人)と呼びます。 下記のように書くことができます。
$('対象の要素').on( イベント名, function(){処理})
$('対象の要素').on( イベント名, 独自関数名)
$('対象の要素').on( イベント名, セレクタ, function(){処理})

※第2引数に入れる関数は、function(){ で始まる無名関数や、別に用意した独自関数(次の#9で紹介)を入れます。
※onメソッドはhover()やtoggle()と違ってイベントが発生したときの処理は一つだけです。.on('イベント名', なにか関数1こ)
※onメソッドはイベントを複数設定することができます。.on('イベント名1':なにか関数, 'イベント名2':なにか関数)

特にイベントハンドラを使わなくて良いと判断したときには、onメソッド.on('change', 関数)ではなくchangeメソッドを使って .change(関数)と書いても構いませんが、 例えばappendメソッドなどで追加した要素に、何かのメソッドを適応させたい場合などはイベントハンドラでないとできないので、悩んだらイベントハンドラであるonメソッドで書いておいて良いと思います。 よくあるメソッドは前ページの#6で紹介しています。


問題:上記を踏まえて、整数の円周を計算できる計算機を作ってみましょう。

cm × 3.14 = cm
小数点第2までを表示させるメソッドがあります。google検索で「js 小数点第2 関数」などで調べてみましょう。
答え

<script>
$(function(){
  $('#calc_pi').on('change', function(){
    let num = parseInt( $('.number_C').val() );
    let pi  = (num * 3.14);
    $('#pi').text(pi.toFixed(2));
  });
});
</script>
<div id="calc_pi" style="margin-bottom:20px;">
  <span><input class="number_C" type="number" style="width:50px;"></span> cm × 3.14 = 
  <span id="pi"></span>cm
</div>

#9 関数を使う

自分で作った方法論や数式を使い回す

関数(独自関数)とは、自分で作った数式やロジックをひとまとめにしたものです。
ある数式を考えたとして、このページでもあのページでも、そういえばあの式にも使える...といった具合に、 一度作った数式は何度も使い回せることがあります。そのようなシーンを想定して数式を関数化しておくことが多くあります。

例えば、家計簿アプリを作ろうとしたとします。
家計簿には消費税の計算を入れてみようと思います。(税率は古いですが8%とします)。
しかし商品の一つ一つに消費税の計算を入れるのは面倒です。消費税の計算は価格 × 0.08で簡単に求められますが関数化してみましょう。


/*関数*/
function tax(price) {
  let tax = 0.08;                 /* 税率の初期設定 */
  let floatTax = price * tax;     /* 取得された値に設定された消費税率をかける */
  return Math.round(floatTax);    /* 四捨五入された値がreturnで出力 */
}

関数を作る場合はfunctionと宣言したあとにtaxなど自分で考えた関数名をいれます。
関数名のあとのカッコ()の中にいれる 引数ひきすうには、その関数内で使われる入るであろう値を総称する自分で考えた適当な名前をいれます。
どういうことかといえば、例は「price」という名前にしてますが、このpriceという場所は入力される値によって、100だったり150だったり1,000だったりします。
関数では具体的な数値を入れるのではなく 文字記号にしておいて、どんな数値が入ってきても対応できるようにしておきます。
最後に、入ってきた値が計算を経てどんな値になって帰ってくるかreturnで指定します。※関数のreturnは基本的にはひとつのみです。

先程の消費税計算での引数とreturn
function tax ()
let TAX = 0.08;
let floatTax = * TAX;
 ちなみに現在のfloatTaxの値は、
return 四捨五入した値→
あとはhtml内に関数を使って以下のような式を書いていきます。

<script>
/* 消費税を計算するtax関数 */
function tax(price) {
  let TAX = 0.08;
  let floatTax = price * TAX;
  return Math.round(floatTax);
}

$(function(){
  $('#tax').on('change', function(){	/* ← 文字入力を検知したら起動 */
    let num = parseInt( $('.ex_price').val() );	/* ← inputタグに入力された値を変数numに代入 */
    let t   = tax(num);		/* ← tax関数で計算した値を変数tに代入 */
    $('.ex_tax').text(t);		/* ← <span class="ex_tax">に変数tの値を出力 */
  });
});
</script>

<div id="tax">
  <input class="ex_price"> 消費税:<span class="ex_tax"></span> 円
</div>

<span class="ex_tax">〜この部分〜</span>
〜この部分〜に計算した結果が出力されます。

もし上記のように、同じ内容の式(引数に0.08をかける)を関数化して、分けておかないと以下の悪い例のように同じ式をでてくるところ全てに入れることになり、 消費税率が変わったときなど複数箇所変えなければならずメンテナンスが大変になります。

/* 悪い例 */
$(function(){
  let TAX = 0.08;
  $('#tax').on('change', function(){
    let num      = parseInt( $('.ex_price').val() );
    let floatTax = num * TAX;
    let t        = Math.round(floatTax);
    $('.ex_tax').text(t);
  });
});
$(function(){
  let TAX = 0.08;
  $('#tax2').on('change', function(){
    let num      = parseInt( $('.ex_price2').val() );
    let floatTax = num * TAX;
    let t        = Math.round(floatTax);
    $('.ex_tax2').text(t);
  });
});
ただ、最初のうちはどこを関数化したらよいかわからないことも多いです。まずは式を書いていく中で、 同じ処理を何度も書いていて「面倒だな...」と思ったときに関数化してみるという手順でも良いと思います。

#10 コンソールでデータの確認

デバッグの第一歩console.log

JavaScriptを書いている際に、思ったとおりの数値が出ないなど度々エラーがおきます。変数や関数に今どんなデータが入ってるんだろう? そういったときに役に立つのがconsole.log()コンソール.ログです。
正確にはconsoleオブジェクトのlog()メソッドです。consoleオブジェクトには.error()、info()、.debug()などたくさんのメソッドが用意されています。
MDN Web Docs
例えば、#9で消費税の計算を行いましたが、最終的に四捨五入して出力する前に「引数×0.08」という計算を行いましたが、 この値は表面上はどこにも出てきません。

function tax(price) {
  let TAX      = 0.08;
  let floatTax = price * TAX;  /* ←この部分 */
  return Math.round(floatTax);
}
たとえばこの関数をつくるときに、変数名を間違って出力できなかったとします。

function tax(price) {
  let TAX      = 0.08;
  let floatTax = price * FAX;  /* TAXの記述ミス */
  return Math.round(floatTax);
}
この場合、変数floatTaxには何も数値が入らないため、returnは何も出力されません。

console.log()をブラウザの開発ツールを使って確認

Macの場合は「⌘+option+i」WindowsはF12でブラウザの開発モードウィンドウが出てきます。
コンソールタブをクリックしてみましょう。
コンソールタブがでたところで、先程のエラーの見つけていきましょう。
consoleを表示させると、変数名が違う場合はエラー内容が表示されます。右側のxxx.php: 193:7というエラー箇所のリンクも張ってありますので、 間違った場所も確認しやすいです。
英語なのでとっつきにくいですが、翻訳ソフトなどで確認して見ましょう。
is not definedは「定義されていません」の意味です。
つまり、「FAXなんて名前の変数は、そもそもどこにも設定されてませんよ。」というエラーになります。
本題に戻って、floatTaxの値をconsole.log(引数);で確認してみましょう。まず、以下の内容を記述します。

消費税:

$(function(){
  $('#tax_console').on('change', function(){
    let num      = parseInt( $('.ex_price_console').val() );
    let floatTax = num * 0.08;
    console.log(floatTax);   /* コンソールでfloatTax変数に入っている内容を表示させる */
    let t        = tax(num);
    $('.ex_tax_console').text(t);
  });
});
関数で指定していますが、関数に掛ける前に入力されたnumに0.08をかけてどうなるかをコンソールしてみます。 以下のinputに数値を入力してみましょう。
消費税:

すると、入力するたびにコンソール欄にこのように表示されます。
変数名の間違いなどはきちんとエラーがでるので大丈夫ですが、式の途中の変数の値がどうなっているのかを確認することで エラー解消に役立ちます。

#11 モーダルウィンドウを作ろう

モーダルウィンドウを作ってみましょう

テスト:画面の中央にモーダルを出してみましょう

<div class="modal-open">モーダル起動!</div>
<div class="modal-content">
  モーダルウィンドウの中身<br>
  モーダルウィンドウの中身
</div>

.modal-open{  /* モーダル起動のボタン */
  padding:20px;
  border: 1px solid #000;
  display:inline-block;
}
.modal-content { /* モーダル部分 */
  display: none;
  position: fixed;
  width: 80%;
  height:200px;
  padding: 10px 20px;
  color: #333;
  background: #ccc;
  overflow-y: auto;
  border-radius: 1em;
  z-index: 100;
}
.modal-overlay { /* 背景 */
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 120%;
  background-color: rgba(0, 0, 0, 0.8);
  z-index: 99;
}
↑ココまではコピペしてください。以下のjQueryをヒントを元に完成させましょう。

<script>
$(function() {
  $('クラス名').on('クリックメソッド', function(){				/* クラス名をクリックしたら */
    $('body').要素追加メソッド('<div class="modal-overlay"></div>');	/* bodyにオーバーレイの要素を追加 */
    $('クラス名1, クラス名2').フェードインメソッド('速度指定');			/* モーダルコンテンツ要素とオーバーレイ要素をフェードイン */

    $('クラス名').on('クリックメソッド', function(){					/* オーバーレイをクリックしたら削除する機能 */
      $('クラス名1, クラス名2').フェードアウトメソッド('速度指定',function(){	/* モーダルコンテンツ要素とオーバーレイ要素をフェードアウトし、*/
        $('クラス名').削除メソッド();						/* オーバーレイ要素を削除*/
      });
    });

    modalResize();				/* モーダル起動&リサイズしたら、再計算させる*/

    function modalResize(){			/* リサイズする独自関数を設定 */
      let w = $(window).width();		/* その時のウィンドウの横幅、高さを取得し、変数に入れる */
      let h = $(window).height();
      let cw = $('クラス名').outerWidth();	/* モーダルコンテンツの表示位置を取得し、変数に入れる */
      let ch = $('クラス名').outerHeight();
      $('クラス名').css({			/* 取得した数値をモーダルコンテンツにcssを付与 */
        'left' : ((w - cw)/2) + 'px',	/* cssのleftプロパティ */
        'top'  : ((h - ch)/2) + 'px'	/* cssのtopプロパティ */
      });
    }

  });
});
</script>
独自関数function内でcssプロパティ「left: ◯◯px」の◯◯値を求める計算をさせています。
(ウィンドウ幅 - コンテンツ幅)/ 2 という計算で求めた値を入れるとセンターに配置されるという論理です。
例えば現在のウィンドウ幅が1,000px、モーダルコンテンツは80%なので800pxとなる場合、(1,000-800)/2 = 100。 つまりleft:100px;となるわけです。よくでてくるので覚えておきましょう。
答え

<script>
$(function() {
  $('.modal-open').on('click', function(){
    $('#contents').css('filter', 'none');
    $('body').append('<div class="modal-overlay"></div>');
    $('.modal-content, .modal-overlay').fadeIn('slow');

    $('.modal-overlay').on('click', function(){
      $('.modal-content, .modal-overlay').fadeOut('slow',function(){
        $('.modal-overlay').remove();
      });
    });

    modalResize();

    function modalResize(){
      let w = $(window).width();
      let h = $(window).height();
      let cw = $('.modal-content').outerWidth();
      let ch = $('.modal-content').outerHeight();
      $('.modal-content').css({
        'left' : ((w - cw)/2) + 'px',
        'top'  : ((h - ch)/2) + 'px'
      });
    }
  });
});
</script>