JavaScriptの基礎

JavaScriptとは

JavaScriptは、webページに組み込んでブラウザ上で実行するプログラミング言語です。
動的にWebページの内容を書き換えることができます。

JavaScriptを使用することでページの視認性や利便性が向上し、ユーザーにとって使いやすいサイトになります。
身近な例で言えば、ポップアップウィンドウの表示自動スクロール(画面トップに戻ったり、目次から該当の箇所までスクロールする)、
アコーディオン(スマートフォンサイトで「三」のような三本線を押すとメニューがスライドして表示される)の設定などに使われています。

また、画面を切り替えることなく一部分だけ画面更新することを可能にする、非同期通信という処理を行うこともできます。次の「Ajax通信」の単元で取り扱います。

JavaScriptには、「ライブラリ」や「フレームワーク」というものが用意されています。

ライブラリ汎用性の高いプログラム(コード)パーツのコレクション。
よく利用される機能を切り出して、再利用しやすいようにまとめたもの。
例:Angular、React、jQuery、Node.js…など
フレームワーク使い回すことのできるアプリケーションの枠組み、土台部分。
例:Vue、Bootstrap(CSSとJavaScript)…など

どちらもWEBアプリケーションの開発の際に、簡単かつ迅速に作業できるようにする要素です。
フレームワークにライブラリが含まれたり、ライブラリがフレームワークのようなメソッドを実装していたりして
実際は境界が曖昧なので総じてフレームワークと呼ぶ事もあります。
これらを利用して開発することで、コーディングの手間を省き作業を効率化できます。

この中でも初歩的で昔からよく使われているのがjQueryです。単元の後半でまた紹介します。
ちなみに、ライブラリやフレームワークを用いずに「素のJavaScript」で記述することを別名「Vanilla JS」と呼ぶこともあります。

JavaとJavaScript
JavaとJavaScriptは名前がよく似ていますが、両者は全く異なるものです。
混同しないように気を付けてください。

JavaScriptは開発当初LiveScriptという名前だったのですが、後に発表されたJavaが世界中で注目を浴びていたため、その人気に便乗して改名したと言われています。紛らわしいですね。

JavaScriptの基本文法

JavaScriptには他のプログラミング言語とは違う「JavaScript特有の文法ルール」が存在します。

基本的な書き方

HTML ファイル上に書いた場合、以下のソースコードの<script>から</script>までがJavaScriptの記述範囲です。

<!DOCTYPE html>
<html lang="ja">
 <body>

 <script>
  document.write(“Hello world!!”);
 </script>

 </body>
</html>

外部ファイル(○○.js)に記述した場合、HTMLファイルのHeadタグ内にJavaScriptを記述したファイルを読み込みます。
CSSファイルと同様、こちらの外部ファイルの形式が一般的です。

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="UTF-8">
  <script src="〇〇.js"></script>
 </head>
 <body>
 </body>
</html>

JavaScriptは、HTMLのscriptタグ内、もしくはjsファイルに記述してscriptタグでHTMLに読みこむことで機能します。

変数・定数

Java同様、JavaScriptでも変数を取り扱うのですが、
基本的には変数の宣言時には、変数名の前に「let」や「var」が必要です。

一度決まった値を変更することができない定数を宣言する際は、変数名の前に「const」を使用します。

これらの違いは変数の再宣言や再代入ができるかどうかなどにあります。
原則「const」を使い、繰り返し処理や再代入をするときだけ「let」を使うようにしましょう。

それぞれの違いについて詳しくは以下の参照サイトをご確認ください。
参照サイト:【JavaScript】let、const、varの違いと使い分け方法を徹底解説

変数の値の確認

変数の中身は「console.log(‘変数’)」で確認します。

let hoge = '見たい値';
console.log('ログ表示:', hoge);

検証ツールの「console」タブに出力されます。(ブラウザ内を右クリック→検証、もしくは「F12」キー使用)。

関数(function)

JavaScriptで関数は「関数オブジェクト」として扱われる、複合型(オブジェクト型)のデータ型のひとつです。
関数作成のための、基本的な構文は以下の通りです。

function 関数名(引数) {
    return 返り値
}

関数名の後にある括弧の中には引数を指定し、引数が必要でない場合は、空欄にしておきます。

作成した関数を呼び出すには、以下のように記述します。

関数名(引数);

他にもこれまでにJavaで学んだif文やwhile文などの構文も、ほとんど同じ記述で使用することができます。
詳しくは以下のサイトをご参照ください。

・基本的な文法
【JavaScript入門】これだけは知っておくべき!JavaScriptの基礎文法
JavaScriptの書き方、基本ルールをコードつきで徹底解説!

・DOM (Document Object Model)操作、イベントについて
JavaScriptのDOM操作でよく使うメソッド

・スタイルを変える時はClasslistを活用しましょう。
【JavaScript】classListの使い方まとめ(add.remove.contains.toggle)

・体系的に丁寧に学べます。(詳しい分長めです。)
 ・DOM操作
 【JavaScriptの基本】DOMの仕組みと構造
 ・イベント
 【JavaScriptの基本】イベントハンドラ

実践

Spring Bootの基本的な処理の流れ」の練習問題で使用したフォームに実装していきましょう。

文字数カウント

テキストエリアの入力文字数を数え、表示する機能を実装します。

フォーム内に、カウント文字数を表示する場所としてHTMLを追加します。
textareaタグには「id=textArea」、spanタグには「id=textCount」を設定しています。

               <li>
                    <div>
                        <p>テキストエリア</p>
                        <textarea name="textarea" id="textArea" cols="30" rows="3"></textarea>
                        <p>文字数:<span id="textCount">0</span>文字</p> <!-- 追記 -->
                    </div>
                </li>

同じファイル内、</body>タグの上に以下の追記をしましょう。
外部ファイル形式で作成するので、そのファイルを読み込むための記述です。

	<script th:src="@{/js/jsmanual.js}"></script><!-- 追記 -->
</body>

続いて以下の階層にJavaScriptファイルを作成し、コードを記述してください。
【/src/main/resources/static/js/jsmanual.js】

"use strict";
// idを使用し、カウント用のパーツを設定
const textarea = document.getElementById('textArea');
const insert = document.getElementById('textCount');

// テキストエリアの入力イベントを監視
textarea.addEventListener('input', function () {
	// lengthメソッドを用いて現在の文字数をカウント
	const count = textarea.value.length;
	// textContentで入力文字数を出力
	insert.textContent = count;
});

「Spring Bootアプリケーション」を実行し、ブラウザ上でフォームを確認してみましょう。
文字数を入力するごとに、文字数がカウントされて表示されるのが確認できるでしょう。

JavaScriptの記述について、解説していきます。

"use strict";

この記述は一般にJavaScriptのコードの1行目に書く慣習になっている、strictモード(厳格モード)というものです。JavaScriptは少々チェックが寛容なところがあり、この記述を入れることで、宣言していない変数を使用したときや同じ変数名で再宣言したときにエラーを出してくれたり、厳格にチェックさせることが出来ます。
JavaScriptのファイルでは必ず1行目に書くようにしましょう。
参考サイト:use strictを書く理由を理解しておこう!

const textarea = document.getElementById('textArea');
const insertEle = document.getElementById('textCount');

上記の記述は、getElementById()メソッドでidとマッチするドキュメント要素を取得し、それぞれ変数に格納しています。

getElementById()メソッドの前のdocumentは、documentオブジェクトといいHTML要素へプログラム上からアクセスする際に使用します。
このdocumentオブジェクトには、HTML要素を取得するためのプロパティやメソッドが用意されており、getElementById()メソッドもその一つです。documentオブジェクトの主なメソッドは以下の通りです。

メソッド機能
getElementById()指定されたIDを持つ要素を取得
getElementsByClassName()指定されたクラスを持つ要素をすべて取得
getElementsByTagName()指定されたタグ名を持つ要素をすべて取得 
getElementsByName()指定されたname属性の要素をすべて取得
querySelector()指定されたCSSセレクターに一致する最初の要素を取得
querySelectorAll()指定されたCSSセレクターに一致するすべての要素を取得
addEventListener()指定されたイベントタイプに対するイベントハンドラを追加
createElement()HTML要素を生成
appendChild()指定された親要素の末尾に子要素を追加
removeChild()指定された子要素を削除
textarea.addEventListener('input', function () {

addEventListener() メソッドは、マウスによるクリックやキーボードからの入力といった様々なイベント処理を実行するメソッドです。
第1引数にイベントの種類、第2引数に関数、第3引数にイベント伝搬の方法をtrueかfalseで指定します(通常はfalseを指定、falseの場合省略可能)。取得できるイベントを一部紹介します。

イベントの種類内容
clickマウスがクリックされた際
keydownキーボードが押された際
keyupキーボードから離された際
onLoadページが読み込まれた際
submitフォームが送信された際
changeフォーム要素(セレクトボックス・チェックボックスなど)の値が変更された際
inputフォームや選択メニューにおいて、ユーザー操作によって値が変更された際
scrollページ全体または特定の要素がスクロールされた際

今回の場合、イベントの種類として「input」を設定、関数部分(第2引数)に無名関数を記述しています。

無名関数
関数名なしで関数を定義できるもの。
関数名を考える手間を省ける、関数を引数で渡す際に無名関数を使用すれば、その場面だけの処理ということが表現できる、といった利点があります。

const count = textarea.value.length;
insertEle.textContent = count;

textarea(id=textAreaの要素)からvalueプロパティで文字列を取得し、さらにlengthプロパティで文字数を取得しています。

valueプロパティは、フォーム要素の現在の値を取得したり、設定したりするために使用されるJavaScriptプロパティで、lengthプロパティは文字列の長さや配列の要素数を取得するプロパティです。

そして、取得した文字数(count)をtextContentを使って、insertEle(id=textCountの要素)へ書き込んでいます。
textContentプロパティはHTML要素に既に存在するテキストを変更する際に使用されます。

JavaScriptは、要素指定アクション処理の3つのパーツから出来ていることを意識して記述しましょう。
(この文字数カウントの実装例で例えると、「テキストエリアに対し(要素指定)、文字を入力したとき(アクション)、文字数を表示する(処理)」といったイメージです。)

ラジオボタン選択によるクラスの付与

ラジオボタンをクリックすると選択した要素に背景色がつくように実装します。

HTMLファイル内に以下の要素を追記してください。
・フォーム内
ここではinputタグにname=”radio1″、id=”radioGood”と”radioBad”をつけています。

	<li>
		<div>
			<p>ラジオボタン</p>
			<input type="radio" name="radio1" value="良い" id="radioGood" checked="checked">
			<label for="radioGood">良い</label> 
			<input type="radio" name="radio1" value="悪い" id="radioBad">
			<label for="radioBad">悪い</label>
		</div>
	</li>

・ headタグ内
付与されるクラスとCSSとなります。

	<style>
.bg-selected {
background-color: #CEF6F5;
color: #000000;
}

.bg-unselected {
background-color: #ffff;
color: #999999;
}
</style>

・jsmanual.js 内

// name="radio1"をすべてまとめて取得
const radioContent = document.getElementsByName('radio1');

function updateBackgrounds() {
	// 全ラジオボタンを順番に処理
	radioContent.forEach(radio => {
		const label = radio.nextElementSibling;
		if (radio.checked) {
			label.classList.add('bg-selected');
			label.classList.remove('bg-unselected');
		} else {
			label.classList.add('bg-unselected');
			label.classList.remove('bg-selected');
		}
	});
}
// 全ラジオボタンに対して「選択状態が変わったとき」にupdateBackgrounds関数を呼び出す
radioContent.forEach(radio => {
	radio.addEventListener('change', updateBackgrounds);
});

// 初期状態
updateBackgrounds();

「Spring Bootアプリケーション」を実行し、ブラウザ上でフォームを確認してみましょう。

解説していきます。

const radioContent = document.getElementsByName('radio1');

getElementsByName()メソッドで、name属性「radio1」(name=”radio1″)を持つ HTML要素をすべて取得します。

radioContent.forEach(・・・)

JavaScriptで使用できるforEachメソッドです。
radioContentをループ処理で回して、要素を順番に処理していきます。

const label = radio.nextElementSibling;

nextElementSiblingプロパティは、指定した要素の次の兄弟要素を取得します。

今回の場合、getElementsByName()で取得した要素をループ処理したradio、
つまり「name=”radio1″」を持つ要素の次の兄弟要素なので「label(タグ)」が該当します。

if (radio.checked) {
	label.classList.add('bg-selected');
	label.classList.remove('bg-unselected');
} else {
	label.classList.add('bg-unselected');
	label.classList.remove('bg-selected');
}

classListプロパティは、特定の要素のクラス名を追加・削除・参照することが出来ます。
プロパティの後ろにメソッドを定義することにより、追加削除などの機能を指定することができます。

今回はradioがchecked(選択された状態)だったら、labelに「bg-selected」というクラスを付与し、「bg-unselected」というクラスを削除する、といった指示をしています(elseはその反対ですね)。

radioContent.forEach(radio => {
	radio.addEventListener('change', updateBackgrounds);
});

addEventListener() メソッド(イベントの種類は「change」)で、radioの状態が変化した際の挙動を設定しています。

今回でいうと、全ラジオボタンに対して「選択状態が変わったとき」にupdateBackgrounds関数を呼び出す、といった処理になります。

updateBackgrounds();

条件など付けずにupdateBackgrounds関数を呼び出すことで、
ページ読み込み時にすでに選択されている(checkedの入っている)ラジオボタンに対応するラベルへ、背景色クラスを反映しています。

ページ読み込み完了後に実行される処理

window.onloadというJavaScriptのイベント(イベントハンドラ)を使用することで、
ページの読み込みが完了したタイミングで、処理を実行することが出来ます。

どのような場面で使われるのかというと
・画像やスクリプトの読み込み完了の検知
・読み込み完了後にスライドショーが開始
など様々です。

ここではページの読み込み完了後にカウントダウンが始まる処理を実装してみましょう。

HTMLファイル内に以下の要素を追記してください。
・bodyタグ内、scriptタグよりも上の任意の箇所

<h2>カウントダウン: <span id="timer">10</span></h2>

・jsmanual.js 内

window.onload = function () {
	let timeLeft = 10;
	const timerElement = document.getElementById('timer');
	const timerInterval = setInterval(function () {
		timeLeft -= 1;
		timerElement.textContent = timeLeft;

		if (timeLeft <= 0) {
			clearInterval(timerInterval);
			timerElement.textContent = 'カウントダウン終了';
		}
	}, 1000);
};

「Spring Bootアプリケーション」を実行し、ブラウザ上でフォームを確認してみましょう。

解説していきます。

window.onload = function () {

このように記述することで、波括弧内の処理をページ・画像、スクリプトなどが完全に読み込まれた後に発動させることが出来ます。

let timeLeft = 10;

残り時間を設定しています。今回は10秒です。

const timerElement = document.getElementById('timer');

getElementById()メソッドで「id = timer」の要素をHTML上から探し、取得します。

const timerInterval = setInterval(function () { ... }, 1000);

setInterval()メソッドは、setInterval(関数,処理間隔)で第一引数に与えられた関数を、第二引数に与えられた間隔で実行します。

第2引数の1000は「1000ミリ秒=1秒ごと」に実行する、という意味です。

timeLeft -= 1;
timerElement.textContent = timeLeft;

「timeLeft = timeLeft – 1」で1秒ごとにtimeLeftから1を引いていきます。
そしてtimeLeftの値をtimerElement(id = timerの要素)へ書き込みます。

clearInterval(timerInterval);

clearInterval()メソッドはsetInterval() メソッドによって呼び出された繰り返し動作を取り消します。
今回の場合、timeLeftが0以下になったら、繰り返し処理を取り消し、代わりに「カウントダウン終了」を表示させています。

ちなみにwindow.onloadは複数記述すると上書きされて、一番最後に記述したもののみ実行されるという特徴があります。
複数実行したい場合は「window.addEventListener()」を使用しましょう。

ここではJavaScriptの中でもDOM操作(HTML上の要素を中心とした処理)について扱いました。
DOM操作以外にも様々な実装ができます。気になった場合は調べてみるといいでしょう。
参考サイト:JavaScriptでできること一覧!特徴や他言語との比較も解説

jQueryで実装する

jQueryとは、JavaScriptのためのライブラリです。jQueryを使用することでシンプルにJavaScriptを記述できます。
jQueryによる実装についても学んでいきましょう。

ここではjQueryを利用する簡単な方法としてCDN(インターネット経由で利用する形式のこと)を使用します。
</body>の上に以下のCDNの記述をすることで読み込みできます。(公式サイトから入手可)

<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>

jQueryの基本的な書き方

上記でjQuery本体を読み込んだその次の行以降のscriptタグ内では、jQueryが利用できるようになります。
jQueryの処理を記述する際は、下記の//処理の中に書いていきます。

<script>
    $(function () {
        // 処理
    });
</script>

基本の処理の書き方は以下の通りです。
実行したい処理を以下のように記述します。(複数記述可)

$(function () {
    $('セレクタ').イベント名(function(){
        //イベント発生時に実行したい処理
    });
});

セレクタは、HTMLのタグに付けたID名やクラス名などでどれが対象の要素かを指定します。

指定する対象コードの書き方
idを指定$(“#要素名”)
例: $('#button')
classを指定$(“.要素名”)
: $('.button')

イベントは、クリックイベントやマウスのホバーなどの動作の起点(発火条件)を指定します。
セレクタが主語で、イベントが動詞と考えると良いでしょう。
【jQuery】イベント一覧まとめ
[jQuery] メソッド・プロパティ一覧

jQueryでの実装

実践にて作成した文字数カウント機能を、jQueryで記述してみましょう。

・JavaScriptの記述(元、比較用)

const textarea = document.getElementById('textArea');
const insert = document.getElementById('textCount');

// テキストエリアの入力イベントを監視
textarea.addEventListener('input', function () {
	// lengthメソッドを用いて現在の文字数をカウント
	const count = textarea.value.length;
	// textContentで入力文字数を出力
	insert.textContent = count;
});

 ↓ jQueryに書き換えると・・

・jQuery CDN
<script>タグの1つ上の箇所に追加します。

	<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script><!-- 追記 -->
	<script th:src="@{/js/jsmanual.js}"></script>
</body>

・jQuery
jsmanual.js 内に記述します。

$(function(){
  $('#textArea').on('input',function(){
    const count = $(this).val().length;
    $('#textCount').text(count);
  });
});

元の記述よりもシンプルになっていることがお分かりいただけますでしょうか?

解説していきます。

$(function(){ ... });

$(function(){}は、「読み込みを待ってから実行する」という意味合いがあり、「window.onload」のjQuery版といえます。

 $('#textArea').on('input',function(){

「id = textArea」の要素を取得、そこに入力(input)があるたびにイベントを実行します。

 const count = $(this).val().length;

入力中のテキストエリアの値(文字数)を取得します。

$('#textCount').text(count);

「id = textCount」の要素に文字数を表示させます。

タイトルとURLをコピーしました